Skip to content

Commit a1bd3ba

Browse files
Allen Hubbejonmason
authored andcommitted
NTB: Add NTB hardware abstraction layer
Abstract the NTB device behind a programming interface, so that it can support different hardware and client drivers. Signed-off-by: Allen Hubbe <[email protected]> Signed-off-by: Jon Mason <[email protected]>
1 parent ec110bc commit a1bd3ba

File tree

5 files changed

+1271
-1
lines changed

5 files changed

+1271
-1
lines changed

Documentation/ntb.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# NTB Drivers
2+
3+
NTB (Non-Transparent Bridge) is a type of PCI-Express bridge chip that connects
4+
the separate memory systems of two computers to the same PCI-Express fabric.
5+
Existing NTB hardware supports a common feature set, including scratchpad
6+
registers, doorbell registers, and memory translation windows. Scratchpad
7+
registers are read-and-writable registers that are accessible from either side
8+
of the device, so that peers can exchange a small amount of information at a
9+
fixed address. Doorbell registers provide a way for peers to send interrupt
10+
events. Memory windows allow translated read and write access to the peer
11+
memory.
12+
13+
## NTB Core Driver (ntb)
14+
15+
The NTB core driver defines an api wrapping the common feature set, and allows
16+
clients interested in NTB features to discover NTB the devices supported by
17+
hardware drivers. The term "client" is used here to mean an upper layer
18+
component making use of the NTB api. The term "driver," or "hardware driver,"
19+
is used here to mean a driver for a specific vendor and model of NTB hardware.
20+
21+
## NTB Client Drivers
22+
23+
NTB client drivers should register with the NTB core driver. After
24+
registering, the client probe and remove functions will be called appropriately
25+
as ntb hardware, or hardware drivers, are inserted and removed. The
26+
registration uses the Linux Device framework, so it should feel familiar to
27+
anyone who has written a pci driver.
28+
29+
## NTB Hardware Drivers
30+
31+
NTB hardware drivers should register devices with the NTB core driver. After
32+
registering, clients probe and remove functions will be called.

MAINTAINERS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6995,15 +6995,17 @@ F: drivers/power/bq27x00_battery.c
69956995
F: drivers/power/isp1704_charger.c
69966996
F: drivers/power/rx51_battery.c
69976997

6998-
NTB DRIVER
6998+
NTB DRIVER CORE
69996999
M: Jon Mason <[email protected]>
70007000
M: Dave Jiang <[email protected]>
7001+
M: Allen Hubbe <[email protected]>
70017002
S: Supported
70027003
W: https://github.com/jonmason/ntb/wiki
70037004
T: git git://github.com/jonmason/ntb.git
70047005
F: drivers/ntb/
70057006
F: drivers/net/ntb_netdev.c
70067007
F: include/linux/ntb.h
7008+
F: include/linux/ntb_transport.h
70077009

70087010
NTFS FILESYSTEM
70097011
M: Anton Altaparmakov <[email protected]>

drivers/ntb/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
obj-$(CONFIG_NTB) += ntb.o
12
obj-$(CONFIG_NTB) += ntb_hw_intel.o
23

34
ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o

drivers/ntb/ntb.c

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/*
2+
* This file is provided under a dual BSD/GPLv2 license. When using or
3+
* redistributing this file, you may do so under either license.
4+
*
5+
* GPL LICENSE SUMMARY
6+
*
7+
* Copyright (C) 2015 EMC Corporation. All Rights Reserved.
8+
*
9+
* This program is free software; you can redistribute it and/or modify
10+
* it under the terms of version 2 of the GNU General Public License as
11+
* published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful, but
14+
* WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*
18+
* BSD LICENSE
19+
*
20+
* Copyright (C) 2015 EMC Corporation. All Rights Reserved.
21+
*
22+
* Redistribution and use in source and binary forms, with or without
23+
* modification, are permitted provided that the following conditions
24+
* are met:
25+
*
26+
* * Redistributions of source code must retain the above copyright
27+
* notice, this list of conditions and the following disclaimer.
28+
* * Redistributions in binary form must reproduce the above copy
29+
* notice, this list of conditions and the following disclaimer in
30+
* the documentation and/or other materials provided with the
31+
* distribution.
32+
* * Neither the name of Intel Corporation nor the names of its
33+
* contributors may be used to endorse or promote products derived
34+
* from this software without specific prior written permission.
35+
*
36+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47+
*
48+
* PCIe NTB Linux driver
49+
*
50+
* Contact Information:
51+
* Allen Hubbe <[email protected]>
52+
*/
53+
54+
#include <linux/device.h>
55+
#include <linux/kernel.h>
56+
#include <linux/module.h>
57+
58+
#include <linux/ntb.h>
59+
#include <linux/pci.h>
60+
61+
#define DRIVER_NAME "ntb"
62+
#define DRIVER_DESCRIPTION "PCIe NTB Driver Framework"
63+
64+
#define DRIVER_LICENSE "Dual BSD/GPL"
65+
#define DRIVER_VERSION "1.0"
66+
#define DRIVER_RELDATE "24 March 2015"
67+
#define DRIVER_AUTHOR "Allen Hubbe <[email protected]>"
68+
69+
MODULE_LICENSE(DRIVER_LICENSE);
70+
MODULE_VERSION(DRIVER_VERSION);
71+
MODULE_AUTHOR(DRIVER_AUTHOR);
72+
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
73+
74+
static struct bus_type ntb_bus;
75+
static void ntb_dev_release(struct device *dev);
76+
77+
int __ntb_register_client(struct ntb_client *client, struct module *mod,
78+
const char *mod_name)
79+
{
80+
if (!client)
81+
return -EINVAL;
82+
if (!ntb_client_ops_is_valid(&client->ops))
83+
return -EINVAL;
84+
85+
memset(&client->drv, 0, sizeof(client->drv));
86+
client->drv.bus = &ntb_bus;
87+
client->drv.name = mod_name;
88+
client->drv.owner = mod;
89+
90+
return driver_register(&client->drv);
91+
}
92+
EXPORT_SYMBOL(__ntb_register_client);
93+
94+
void ntb_unregister_client(struct ntb_client *client)
95+
{
96+
driver_unregister(&client->drv);
97+
}
98+
EXPORT_SYMBOL(ntb_unregister_client);
99+
100+
int ntb_register_device(struct ntb_dev *ntb)
101+
{
102+
if (!ntb)
103+
return -EINVAL;
104+
if (!ntb->pdev)
105+
return -EINVAL;
106+
if (!ntb->ops)
107+
return -EINVAL;
108+
if (!ntb_dev_ops_is_valid(ntb->ops))
109+
return -EINVAL;
110+
111+
init_completion(&ntb->released);
112+
113+
memset(&ntb->dev, 0, sizeof(ntb->dev));
114+
ntb->dev.bus = &ntb_bus;
115+
ntb->dev.parent = &ntb->pdev->dev;
116+
ntb->dev.release = ntb_dev_release;
117+
dev_set_name(&ntb->dev, pci_name(ntb->pdev));
118+
119+
ntb->ctx = NULL;
120+
ntb->ctx_ops = NULL;
121+
spin_lock_init(&ntb->ctx_lock);
122+
123+
return device_register(&ntb->dev);
124+
}
125+
EXPORT_SYMBOL(ntb_register_device);
126+
127+
void ntb_unregister_device(struct ntb_dev *ntb)
128+
{
129+
device_unregister(&ntb->dev);
130+
wait_for_completion(&ntb->released);
131+
}
132+
EXPORT_SYMBOL(ntb_unregister_device);
133+
134+
int ntb_set_ctx(struct ntb_dev *ntb, void *ctx,
135+
const struct ntb_ctx_ops *ctx_ops)
136+
{
137+
unsigned long irqflags;
138+
139+
if (!ntb_ctx_ops_is_valid(ctx_ops))
140+
return -EINVAL;
141+
if (ntb->ctx_ops)
142+
return -EINVAL;
143+
144+
spin_lock_irqsave(&ntb->ctx_lock, irqflags);
145+
{
146+
ntb->ctx = ctx;
147+
ntb->ctx_ops = ctx_ops;
148+
}
149+
spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
150+
151+
return 0;
152+
}
153+
EXPORT_SYMBOL(ntb_set_ctx);
154+
155+
void ntb_clear_ctx(struct ntb_dev *ntb)
156+
{
157+
unsigned long irqflags;
158+
159+
spin_lock_irqsave(&ntb->ctx_lock, irqflags);
160+
{
161+
ntb->ctx_ops = NULL;
162+
ntb->ctx = NULL;
163+
}
164+
spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
165+
}
166+
EXPORT_SYMBOL(ntb_clear_ctx);
167+
168+
void ntb_link_event(struct ntb_dev *ntb)
169+
{
170+
unsigned long irqflags;
171+
172+
spin_lock_irqsave(&ntb->ctx_lock, irqflags);
173+
{
174+
if (ntb->ctx_ops && ntb->ctx_ops->link_event)
175+
ntb->ctx_ops->link_event(ntb->ctx);
176+
}
177+
spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
178+
}
179+
EXPORT_SYMBOL(ntb_link_event);
180+
181+
void ntb_db_event(struct ntb_dev *ntb, int vector)
182+
{
183+
unsigned long irqflags;
184+
185+
spin_lock_irqsave(&ntb->ctx_lock, irqflags);
186+
{
187+
if (ntb->ctx_ops && ntb->ctx_ops->db_event)
188+
ntb->ctx_ops->db_event(ntb->ctx, vector);
189+
}
190+
spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
191+
}
192+
EXPORT_SYMBOL(ntb_db_event);
193+
194+
static int ntb_probe(struct device *dev)
195+
{
196+
struct ntb_dev *ntb;
197+
struct ntb_client *client;
198+
int rc;
199+
200+
get_device(dev);
201+
ntb = dev_ntb(dev);
202+
client = drv_ntb_client(dev->driver);
203+
204+
rc = client->ops.probe(client, ntb);
205+
if (rc)
206+
put_device(dev);
207+
208+
return rc;
209+
}
210+
211+
static int ntb_remove(struct device *dev)
212+
{
213+
struct ntb_dev *ntb;
214+
struct ntb_client *client;
215+
216+
if (dev->driver) {
217+
ntb = dev_ntb(dev);
218+
client = drv_ntb_client(dev->driver);
219+
220+
client->ops.remove(client, ntb);
221+
put_device(dev);
222+
}
223+
224+
return 0;
225+
}
226+
227+
static void ntb_dev_release(struct device *dev)
228+
{
229+
struct ntb_dev *ntb = dev_ntb(dev);
230+
231+
complete(&ntb->released);
232+
}
233+
234+
static struct bus_type ntb_bus = {
235+
.name = "ntb",
236+
.probe = ntb_probe,
237+
.remove = ntb_remove,
238+
};
239+
240+
static int __init ntb_driver_init(void)
241+
{
242+
return bus_register(&ntb_bus);
243+
}
244+
module_init(ntb_driver_init);
245+
246+
static void __exit ntb_driver_exit(void)
247+
{
248+
bus_unregister(&ntb_bus);
249+
}
250+
module_exit(ntb_driver_exit);
251+

0 commit comments

Comments
 (0)