diff options
-rw-r--r-- | Documentation/ntb.txt | 32 | ||||
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | drivers/ntb/Makefile | 1 | ||||
-rw-r--r-- | drivers/ntb/ntb.c | 251 | ||||
-rw-r--r-- | include/linux/ntb.h | 984 |
5 files changed, 1271 insertions, 1 deletions
diff --git a/Documentation/ntb.txt b/Documentation/ntb.txt new file mode 100644 index 000000000000..9d46dc9712a8 --- /dev/null +++ b/Documentation/ntb.txt | |||
@@ -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. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 663bc8ed1860..e2fc9eec2e16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6995,15 +6995,17 @@ F: drivers/power/bq27x00_battery.c | |||
6995 | F: drivers/power/isp1704_charger.c | 6995 | F: drivers/power/isp1704_charger.c |
6996 | F: drivers/power/rx51_battery.c | 6996 | F: drivers/power/rx51_battery.c |
6997 | 6997 | ||
6998 | NTB DRIVER | 6998 | NTB DRIVER CORE |
6999 | M: Jon Mason <jdmason@kudzu.us> | 6999 | M: Jon Mason <jdmason@kudzu.us> |
7000 | M: Dave Jiang <dave.jiang@intel.com> | 7000 | M: Dave Jiang <dave.jiang@intel.com> |
7001 | M: Allen Hubbe <Allen.Hubbe@emc.com> | ||
7001 | S: Supported | 7002 | S: Supported |
7002 | W: https://github.com/jonmason/ntb/wiki | 7003 | W: https://github.com/jonmason/ntb/wiki |
7003 | T: git git://github.com/jonmason/ntb.git | 7004 | T: git git://github.com/jonmason/ntb.git |
7004 | F: drivers/ntb/ | 7005 | F: drivers/ntb/ |
7005 | F: drivers/net/ntb_netdev.c | 7006 | F: drivers/net/ntb_netdev.c |
7006 | F: include/linux/ntb.h | 7007 | F: include/linux/ntb.h |
7008 | F: include/linux/ntb_transport.h | ||
7007 | 7009 | ||
7008 | NTFS FILESYSTEM | 7010 | NTFS FILESYSTEM |
7009 | M: Anton Altaparmakov <anton@tuxera.com> | 7011 | M: Anton Altaparmakov <anton@tuxera.com> |
diff --git a/drivers/ntb/Makefile b/drivers/ntb/Makefile index 545b10a131af..712e953a8fda 100644 --- a/drivers/ntb/Makefile +++ b/drivers/ntb/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_NTB) += ntb.o | ||
1 | obj-$(CONFIG_NTB) += ntb_hw_intel.o | 2 | obj-$(CONFIG_NTB) += ntb_hw_intel.o |
2 | 3 | ||
3 | ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o | 4 | ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o |
diff --git a/drivers/ntb/ntb.c b/drivers/ntb/ntb.c new file mode 100644 index 000000000000..23435f2a5486 --- /dev/null +++ b/drivers/ntb/ntb.c | |||
@@ -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 <Allen.Hubbe@emc.com> | ||
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 <Allen.Hubbe@emc.com>" | ||
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 | |||
diff --git a/include/linux/ntb.h b/include/linux/ntb.h new file mode 100644 index 000000000000..b02f72bb8e32 --- /dev/null +++ b/include/linux/ntb.h | |||
@@ -0,0 +1,984 @@ | |||
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 <Allen.Hubbe@emc.com> | ||
52 | */ | ||
53 | |||
54 | #ifndef _NTB_H_ | ||
55 | #define _NTB_H_ | ||
56 | |||
57 | #include <linux/completion.h> | ||
58 | #include <linux/device.h> | ||
59 | |||
60 | struct ntb_client; | ||
61 | struct ntb_dev; | ||
62 | struct pci_dev; | ||
63 | |||
64 | /** | ||
65 | * enum ntb_topo - NTB connection topology | ||
66 | * @NTB_TOPO_NONE: Topology is unknown or invalid. | ||
67 | * @NTB_TOPO_PRI: On primary side of local ntb. | ||
68 | * @NTB_TOPO_SEC: On secondary side of remote ntb. | ||
69 | * @NTB_TOPO_B2B_USD: On primary side of local ntb upstream of remote ntb. | ||
70 | * @NTB_TOPO_B2B_DSD: On primary side of local ntb downstream of remote ntb. | ||
71 | */ | ||
72 | enum ntb_topo { | ||
73 | NTB_TOPO_NONE = -1, | ||
74 | NTB_TOPO_PRI, | ||
75 | NTB_TOPO_SEC, | ||
76 | NTB_TOPO_B2B_USD, | ||
77 | NTB_TOPO_B2B_DSD, | ||
78 | }; | ||
79 | |||
80 | static inline int ntb_topo_is_b2b(enum ntb_topo topo) | ||
81 | { | ||
82 | switch ((int)topo) { | ||
83 | case NTB_TOPO_B2B_USD: | ||
84 | case NTB_TOPO_B2B_DSD: | ||
85 | return 1; | ||
86 | } | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static inline char *ntb_topo_string(enum ntb_topo topo) | ||
91 | { | ||
92 | switch (topo) { | ||
93 | case NTB_TOPO_NONE: return "NTB_TOPO_NONE"; | ||
94 | case NTB_TOPO_PRI: return "NTB_TOPO_PRI"; | ||
95 | case NTB_TOPO_SEC: return "NTB_TOPO_SEC"; | ||
96 | case NTB_TOPO_B2B_USD: return "NTB_TOPO_B2B_USD"; | ||
97 | case NTB_TOPO_B2B_DSD: return "NTB_TOPO_B2B_DSD"; | ||
98 | } | ||
99 | return "NTB_TOPO_INVALID"; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * enum ntb_speed - NTB link training speed | ||
104 | * @NTB_SPEED_AUTO: Request the max supported speed. | ||
105 | * @NTB_SPEED_NONE: Link is not trained to any speed. | ||
106 | * @NTB_SPEED_GEN1: Link is trained to gen1 speed. | ||
107 | * @NTB_SPEED_GEN2: Link is trained to gen2 speed. | ||
108 | * @NTB_SPEED_GEN3: Link is trained to gen3 speed. | ||
109 | */ | ||
110 | enum ntb_speed { | ||
111 | NTB_SPEED_AUTO = -1, | ||
112 | NTB_SPEED_NONE = 0, | ||
113 | NTB_SPEED_GEN1 = 1, | ||
114 | NTB_SPEED_GEN2 = 2, | ||
115 | NTB_SPEED_GEN3 = 3, | ||
116 | }; | ||
117 | |||
118 | /** | ||
119 | * enum ntb_width - NTB link training width | ||
120 | * @NTB_WIDTH_AUTO: Request the max supported width. | ||
121 | * @NTB_WIDTH_NONE: Link is not trained to any width. | ||
122 | * @NTB_WIDTH_1: Link is trained to 1 lane width. | ||
123 | * @NTB_WIDTH_2: Link is trained to 2 lane width. | ||
124 | * @NTB_WIDTH_4: Link is trained to 4 lane width. | ||
125 | * @NTB_WIDTH_8: Link is trained to 8 lane width. | ||
126 | * @NTB_WIDTH_12: Link is trained to 12 lane width. | ||
127 | * @NTB_WIDTH_16: Link is trained to 16 lane width. | ||
128 | * @NTB_WIDTH_32: Link is trained to 32 lane width. | ||
129 | */ | ||
130 | enum ntb_width { | ||
131 | NTB_WIDTH_AUTO = -1, | ||
132 | NTB_WIDTH_NONE = 0, | ||
133 | NTB_WIDTH_1 = 1, | ||
134 | NTB_WIDTH_2 = 2, | ||
135 | NTB_WIDTH_4 = 4, | ||
136 | NTB_WIDTH_8 = 8, | ||
137 | NTB_WIDTH_12 = 12, | ||
138 | NTB_WIDTH_16 = 16, | ||
139 | NTB_WIDTH_32 = 32, | ||
140 | }; | ||
141 | |||
142 | /** | ||
143 | * struct ntb_client_ops - ntb client operations | ||
144 | * @probe: Notify client of a new device. | ||
145 | * @remove: Notify client to remove a device. | ||
146 | */ | ||
147 | struct ntb_client_ops { | ||
148 | int (*probe)(struct ntb_client *client, struct ntb_dev *ntb); | ||
149 | void (*remove)(struct ntb_client *client, struct ntb_dev *ntb); | ||
150 | }; | ||
151 | |||
152 | static inline int ntb_client_ops_is_valid(const struct ntb_client_ops *ops) | ||
153 | { | ||
154 | /* commented callbacks are not required: */ | ||
155 | return | ||
156 | ops->probe && | ||
157 | ops->remove && | ||
158 | 1; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * struct ntb_ctx_ops - ntb driver context operations | ||
163 | * @link_event: See ntb_link_event(). | ||
164 | * @db_event: See ntb_db_event(). | ||
165 | */ | ||
166 | struct ntb_ctx_ops { | ||
167 | void (*link_event)(void *ctx); | ||
168 | void (*db_event)(void *ctx, int db_vector); | ||
169 | }; | ||
170 | |||
171 | static inline int ntb_ctx_ops_is_valid(const struct ntb_ctx_ops *ops) | ||
172 | { | ||
173 | /* commented callbacks are not required: */ | ||
174 | return | ||
175 | /* ops->link_event && */ | ||
176 | /* ops->db_event && */ | ||
177 | 1; | ||
178 | } | ||
179 | |||
180 | /** | ||
181 | * struct ntb_ctx_ops - ntb device operations | ||
182 | * @mw_count: See ntb_mw_count(). | ||
183 | * @mw_get_range: See ntb_mw_get_range(). | ||
184 | * @mw_set_trans: See ntb_mw_set_trans(). | ||
185 | * @mw_clear_trans: See ntb_mw_clear_trans(). | ||
186 | * @link_is_up: See ntb_link_is_up(). | ||
187 | * @link_enable: See ntb_link_enable(). | ||
188 | * @link_disable: See ntb_link_disable(). | ||
189 | * @db_is_unsafe: See ntb_db_is_unsafe(). | ||
190 | * @db_valid_mask: See ntb_db_valid_mask(). | ||
191 | * @db_vector_count: See ntb_db_vector_count(). | ||
192 | * @db_vector_mask: See ntb_db_vector_mask(). | ||
193 | * @db_read: See ntb_db_read(). | ||
194 | * @db_set: See ntb_db_set(). | ||
195 | * @db_clear: See ntb_db_clear(). | ||
196 | * @db_read_mask: See ntb_db_read_mask(). | ||
197 | * @db_set_mask: See ntb_db_set_mask(). | ||
198 | * @db_clear_mask: See ntb_db_clear_mask(). | ||
199 | * @peer_db_addr: See ntb_peer_db_addr(). | ||
200 | * @peer_db_read: See ntb_peer_db_read(). | ||
201 | * @peer_db_set: See ntb_peer_db_set(). | ||
202 | * @peer_db_clear: See ntb_peer_db_clear(). | ||
203 | * @peer_db_read_mask: See ntb_peer_db_read_mask(). | ||
204 | * @peer_db_set_mask: See ntb_peer_db_set_mask(). | ||
205 | * @peer_db_clear_mask: See ntb_peer_db_clear_mask(). | ||
206 | * @spad_is_unsafe: See ntb_spad_is_unsafe(). | ||
207 | * @spad_count: See ntb_spad_count(). | ||
208 | * @spad_read: See ntb_spad_read(). | ||
209 | * @spad_write: See ntb_spad_write(). | ||
210 | * @peer_spad_addr: See ntb_peer_spad_addr(). | ||
211 | * @peer_spad_read: See ntb_peer_spad_read(). | ||
212 | * @peer_spad_write: See ntb_peer_spad_write(). | ||
213 | */ | ||
214 | struct ntb_dev_ops { | ||
215 | int (*mw_count)(struct ntb_dev *ntb); | ||
216 | int (*mw_get_range)(struct ntb_dev *ntb, int idx, | ||
217 | phys_addr_t *base, resource_size_t *size, | ||
218 | resource_size_t *align, resource_size_t *align_size); | ||
219 | int (*mw_set_trans)(struct ntb_dev *ntb, int idx, | ||
220 | dma_addr_t addr, resource_size_t size); | ||
221 | int (*mw_clear_trans)(struct ntb_dev *ntb, int idx); | ||
222 | |||
223 | int (*link_is_up)(struct ntb_dev *ntb, | ||
224 | enum ntb_speed *speed, enum ntb_width *width); | ||
225 | int (*link_enable)(struct ntb_dev *ntb, | ||
226 | enum ntb_speed max_speed, enum ntb_width max_width); | ||
227 | int (*link_disable)(struct ntb_dev *ntb); | ||
228 | |||
229 | int (*db_is_unsafe)(struct ntb_dev *ntb); | ||
230 | u64 (*db_valid_mask)(struct ntb_dev *ntb); | ||
231 | int (*db_vector_count)(struct ntb_dev *ntb); | ||
232 | u64 (*db_vector_mask)(struct ntb_dev *ntb, int db_vector); | ||
233 | |||
234 | u64 (*db_read)(struct ntb_dev *ntb); | ||
235 | int (*db_set)(struct ntb_dev *ntb, u64 db_bits); | ||
236 | int (*db_clear)(struct ntb_dev *ntb, u64 db_bits); | ||
237 | |||
238 | u64 (*db_read_mask)(struct ntb_dev *ntb); | ||
239 | int (*db_set_mask)(struct ntb_dev *ntb, u64 db_bits); | ||
240 | int (*db_clear_mask)(struct ntb_dev *ntb, u64 db_bits); | ||
241 | |||
242 | int (*peer_db_addr)(struct ntb_dev *ntb, | ||
243 | phys_addr_t *db_addr, resource_size_t *db_size); | ||
244 | u64 (*peer_db_read)(struct ntb_dev *ntb); | ||
245 | int (*peer_db_set)(struct ntb_dev *ntb, u64 db_bits); | ||
246 | int (*peer_db_clear)(struct ntb_dev *ntb, u64 db_bits); | ||
247 | |||
248 | u64 (*peer_db_read_mask)(struct ntb_dev *ntb); | ||
249 | int (*peer_db_set_mask)(struct ntb_dev *ntb, u64 db_bits); | ||
250 | int (*peer_db_clear_mask)(struct ntb_dev *ntb, u64 db_bits); | ||
251 | |||
252 | int (*spad_is_unsafe)(struct ntb_dev *ntb); | ||
253 | int (*spad_count)(struct ntb_dev *ntb); | ||
254 | |||
255 | u32 (*spad_read)(struct ntb_dev *ntb, int idx); | ||
256 | int (*spad_write)(struct ntb_dev *ntb, int idx, u32 val); | ||
257 | |||
258 | int (*peer_spad_addr)(struct ntb_dev *ntb, int idx, | ||
259 | phys_addr_t *spad_addr); | ||
260 | u32 (*peer_spad_read)(struct ntb_dev *ntb, int idx); | ||
261 | int (*peer_spad_write)(struct ntb_dev *ntb, int idx, u32 val); | ||
262 | }; | ||
263 | |||
264 | static inline int ntb_dev_ops_is_valid(const struct ntb_dev_ops *ops) | ||
265 | { | ||
266 | /* commented callbacks are not required: */ | ||
267 | return | ||
268 | ops->mw_count && | ||
269 | ops->mw_get_range && | ||
270 | ops->mw_set_trans && | ||
271 | /* ops->mw_clear_trans && */ | ||
272 | ops->link_is_up && | ||
273 | ops->link_enable && | ||
274 | ops->link_disable && | ||
275 | /* ops->db_is_unsafe && */ | ||
276 | ops->db_valid_mask && | ||
277 | |||
278 | /* both set, or both unset */ | ||
279 | (!ops->db_vector_count == !ops->db_vector_mask) && | ||
280 | |||
281 | ops->db_read && | ||
282 | /* ops->db_set && */ | ||
283 | ops->db_clear && | ||
284 | /* ops->db_read_mask && */ | ||
285 | ops->db_set_mask && | ||
286 | ops->db_clear_mask && | ||
287 | ops->peer_db_addr && | ||
288 | /* ops->peer_db_read && */ | ||
289 | ops->peer_db_set && | ||
290 | /* ops->peer_db_clear && */ | ||
291 | /* ops->peer_db_read_mask && */ | ||
292 | /* ops->peer_db_set_mask && */ | ||
293 | /* ops->peer_db_clear_mask && */ | ||
294 | /* ops->spad_is_unsafe && */ | ||
295 | ops->spad_count && | ||
296 | ops->spad_read && | ||
297 | ops->spad_write && | ||
298 | ops->peer_spad_addr && | ||
299 | /* ops->peer_spad_read && */ | ||
300 | ops->peer_spad_write && | ||
301 | 1; | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * struct ntb_client - client interested in ntb devices | ||
306 | * @drv: Linux driver object. | ||
307 | * @ops: See &ntb_client_ops. | ||
308 | */ | ||
309 | struct ntb_client { | ||
310 | struct device_driver drv; | ||
311 | const struct ntb_client_ops ops; | ||
312 | }; | ||
313 | |||
314 | #define drv_ntb_client(__drv) container_of((__drv), struct ntb_client, drv) | ||
315 | |||
316 | /** | ||
317 | * struct ntb_device - ntb device | ||
318 | * @dev: Linux device object. | ||
319 | * @pdev: Pci device entry of the ntb. | ||
320 | * @topo: Detected topology of the ntb. | ||
321 | * @ops: See &ntb_dev_ops. | ||
322 | * @ctx: See &ntb_ctx_ops. | ||
323 | * @ctx_ops: See &ntb_ctx_ops. | ||
324 | */ | ||
325 | struct ntb_dev { | ||
326 | struct device dev; | ||
327 | struct pci_dev *pdev; | ||
328 | enum ntb_topo topo; | ||
329 | const struct ntb_dev_ops *ops; | ||
330 | void *ctx; | ||
331 | const struct ntb_ctx_ops *ctx_ops; | ||
332 | |||
333 | /* private: */ | ||
334 | |||
335 | /* synchronize setting, clearing, and calling ctx_ops */ | ||
336 | spinlock_t ctx_lock; | ||
337 | /* block unregister until device is fully released */ | ||
338 | struct completion released; | ||
339 | }; | ||
340 | |||
341 | #define dev_ntb(__dev) container_of((__dev), struct ntb_dev, dev) | ||
342 | |||
343 | /** | ||
344 | * ntb_register_client() - register a client for interest in ntb devices | ||
345 | * @client: Client context. | ||
346 | * | ||
347 | * The client will be added to the list of clients interested in ntb devices. | ||
348 | * The client will be notified of any ntb devices that are not already | ||
349 | * associated with a client, or if ntb devices are registered later. | ||
350 | * | ||
351 | * Return: Zero if the client is registered, otherwise an error number. | ||
352 | */ | ||
353 | #define ntb_register_client(client) \ | ||
354 | __ntb_register_client((client), THIS_MODULE, KBUILD_MODNAME) | ||
355 | |||
356 | int __ntb_register_client(struct ntb_client *client, struct module *mod, | ||
357 | const char *mod_name); | ||
358 | |||
359 | /** | ||
360 | * ntb_unregister_client() - unregister a client for interest in ntb devices | ||
361 | * @client: Client context. | ||
362 | * | ||
363 | * The client will be removed from the list of clients interested in ntb | ||
364 | * devices. If any ntb devices are associated with the client, the client will | ||
365 | * be notified to remove those devices. | ||
366 | */ | ||
367 | void ntb_unregister_client(struct ntb_client *client); | ||
368 | |||
369 | #define module_ntb_client(__ntb_client) \ | ||
370 | module_driver(__ntb_client, ntb_register_client, \ | ||
371 | ntb_unregister_client) | ||
372 | |||
373 | /** | ||
374 | * ntb_register_device() - register a ntb device | ||
375 | * @ntb: NTB device context. | ||
376 | * | ||
377 | * The device will be added to the list of ntb devices. If any clients are | ||
378 | * interested in ntb devices, each client will be notified of the ntb device, | ||
379 | * until at most one client accepts the device. | ||
380 | * | ||
381 | * Return: Zero if the device is registered, otherwise an error number. | ||
382 | */ | ||
383 | int ntb_register_device(struct ntb_dev *ntb); | ||
384 | |||
385 | /** | ||
386 | * ntb_register_device() - unregister a ntb device | ||
387 | * @ntb: NTB device context. | ||
388 | * | ||
389 | * The device will be removed from the list of ntb devices. If the ntb device | ||
390 | * is associated with a client, the client will be notified to remove the | ||
391 | * device. | ||
392 | */ | ||
393 | void ntb_unregister_device(struct ntb_dev *ntb); | ||
394 | |||
395 | /** | ||
396 | * ntb_set_ctx() - associate a driver context with an ntb device | ||
397 | * @ntb: NTB device context. | ||
398 | * @ctx: Driver context. | ||
399 | * @ctx_ops: Driver context operations. | ||
400 | * | ||
401 | * Associate a driver context and operations with a ntb device. The context is | ||
402 | * provided by the client driver, and the driver may associate a different | ||
403 | * context with each ntb device. | ||
404 | * | ||
405 | * Return: Zero if the context is associated, otherwise an error number. | ||
406 | */ | ||
407 | int ntb_set_ctx(struct ntb_dev *ntb, void *ctx, | ||
408 | const struct ntb_ctx_ops *ctx_ops); | ||
409 | |||
410 | /** | ||
411 | * ntb_clear_ctx() - disassociate any driver context from an ntb device | ||
412 | * @ntb: NTB device context. | ||
413 | * | ||
414 | * Clear any association that may exist between a driver context and the ntb | ||
415 | * device. | ||
416 | */ | ||
417 | void ntb_clear_ctx(struct ntb_dev *ntb); | ||
418 | |||
419 | /** | ||
420 | * ntb_link_event() - notify driver context of a change in link status | ||
421 | * @ntb: NTB device context. | ||
422 | * | ||
423 | * Notify the driver context that the link status may have changed. The driver | ||
424 | * should call ntb_link_is_up() to get the current status. | ||
425 | */ | ||
426 | void ntb_link_event(struct ntb_dev *ntb); | ||
427 | |||
428 | /** | ||
429 | * ntb_db_event() - notify driver context of a doorbell event | ||
430 | * @ntb: NTB device context. | ||
431 | * @vector: Interrupt vector number. | ||
432 | * | ||
433 | * Notify the driver context of a doorbell event. If hardware supports | ||
434 | * multiple interrupt vectors for doorbells, the vector number indicates which | ||
435 | * vector received the interrupt. The vector number is relative to the first | ||
436 | * vector used for doorbells, starting at zero, and must be less than | ||
437 | ** ntb_db_vector_count(). The driver may call ntb_db_read() to check which | ||
438 | * doorbell bits need service, and ntb_db_vector_mask() to determine which of | ||
439 | * those bits are associated with the vector number. | ||
440 | */ | ||
441 | void ntb_db_event(struct ntb_dev *ntb, int vector); | ||
442 | |||
443 | /** | ||
444 | * ntb_mw_count() - get the number of memory windows | ||
445 | * @ntb: NTB device context. | ||
446 | * | ||
447 | * Hardware and topology may support a different number of memory windows. | ||
448 | * | ||
449 | * Return: the number of memory windows. | ||
450 | */ | ||
451 | static inline int ntb_mw_count(struct ntb_dev *ntb) | ||
452 | { | ||
453 | return ntb->ops->mw_count(ntb); | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * ntb_mw_get_range() - get the range of a memory window | ||
458 | * @ntb: NTB device context. | ||
459 | * @idx: Memory window number. | ||
460 | * @base: OUT - the base address for mapping the memory window | ||
461 | * @size: OUT - the size for mapping the memory window | ||
462 | * @align: OUT - the base alignment for translating the memory window | ||
463 | * @align_size: OUT - the size alignment for translating the memory window | ||
464 | * | ||
465 | * Get the range of a memory window. NULL may be given for any output | ||
466 | * parameter if the value is not needed. The base and size may be used for | ||
467 | * mapping the memory window, to access the peer memory. The alignment and | ||
468 | * size may be used for translating the memory window, for the peer to access | ||
469 | * memory on the local system. | ||
470 | * | ||
471 | * Return: Zero on success, otherwise an error number. | ||
472 | */ | ||
473 | static inline int ntb_mw_get_range(struct ntb_dev *ntb, int idx, | ||
474 | phys_addr_t *base, resource_size_t *size, | ||
475 | resource_size_t *align, resource_size_t *align_size) | ||
476 | { | ||
477 | return ntb->ops->mw_get_range(ntb, idx, base, size, | ||
478 | align, align_size); | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * ntb_mw_set_trans() - set the translation of a memory window | ||
483 | * @ntb: NTB device context. | ||
484 | * @idx: Memory window number. | ||
485 | * @addr: The dma address local memory to expose to the peer. | ||
486 | * @size: The size of the local memory to expose to the peer. | ||
487 | * | ||
488 | * Set the translation of a memory window. The peer may access local memory | ||
489 | * through the window starting at the address, up to the size. The address | ||
490 | * must be aligned to the alignment specified by ntb_mw_get_range(). The size | ||
491 | * must be aligned to the size alignment specified by ntb_mw_get_range(). | ||
492 | * | ||
493 | * Return: Zero on success, otherwise an error number. | ||
494 | */ | ||
495 | static inline int ntb_mw_set_trans(struct ntb_dev *ntb, int idx, | ||
496 | dma_addr_t addr, resource_size_t size) | ||
497 | { | ||
498 | return ntb->ops->mw_set_trans(ntb, idx, addr, size); | ||
499 | } | ||
500 | |||
501 | /** | ||
502 | * ntb_mw_clear_trans() - clear the translation of a memory window | ||
503 | * @ntb: NTB device context. | ||
504 | * @idx: Memory window number. | ||
505 | * | ||
506 | * Clear the translation of a memory window. The peer may no longer access | ||
507 | * local memory through the window. | ||
508 | * | ||
509 | * Return: Zero on success, otherwise an error number. | ||
510 | */ | ||
511 | static inline int ntb_mw_clear_trans(struct ntb_dev *ntb, int idx) | ||
512 | { | ||
513 | if (!ntb->ops->mw_clear_trans) | ||
514 | return ntb->ops->mw_set_trans(ntb, idx, 0, 0); | ||
515 | |||
516 | return ntb->ops->mw_clear_trans(ntb, idx); | ||
517 | } | ||
518 | |||
519 | /** | ||
520 | * ntb_link_is_up() - get the current ntb link state | ||
521 | * @ntb: NTB device context. | ||
522 | * @speed: OUT - The link speed expressed as PCIe generation number. | ||
523 | * @width: OUT - The link width expressed as the number of PCIe lanes. | ||
524 | * | ||
525 | * Set the translation of a memory window. The peer may access local memory | ||
526 | * through the window starting at the address, up to the size. The address | ||
527 | * must be aligned to the alignment specified by ntb_mw_get_range(). The size | ||
528 | * must be aligned to the size alignment specified by ntb_mw_get_range(). | ||
529 | * | ||
530 | * Return: One if the link is up, zero if the link is down, otherwise a | ||
531 | * negative value indicating the error number. | ||
532 | */ | ||
533 | static inline int ntb_link_is_up(struct ntb_dev *ntb, | ||
534 | enum ntb_speed *speed, enum ntb_width *width) | ||
535 | { | ||
536 | return ntb->ops->link_is_up(ntb, speed, width); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * ntb_link_enable() - enable the link on the secondary side of the ntb | ||
541 | * @ntb: NTB device context. | ||
542 | * @max_speed: The maximum link speed expressed as PCIe generation number. | ||
543 | * @max_width: The maximum link width expressed as the number of PCIe lanes. | ||
544 | * | ||
545 | * Enable the link on the secondary side of the ntb. This can only be done | ||
546 | * from the primary side of the ntb in primary or b2b topology. The ntb device | ||
547 | * should train the link to its maximum speed and width, or the requested speed | ||
548 | * and width, whichever is smaller, if supported. | ||
549 | * | ||
550 | * Return: Zero on success, otherwise an error number. | ||
551 | */ | ||
552 | static inline int ntb_link_enable(struct ntb_dev *ntb, | ||
553 | enum ntb_speed max_speed, | ||
554 | enum ntb_width max_width) | ||
555 | { | ||
556 | return ntb->ops->link_enable(ntb, max_speed, max_width); | ||
557 | } | ||
558 | |||
559 | /** | ||
560 | * ntb_link_disable() - disable the link on the secondary side of the ntb | ||
561 | * @ntb: NTB device context. | ||
562 | * | ||
563 | * Disable the link on the secondary side of the ntb. This can only be | ||
564 | * done from the primary side of the ntb in primary or b2b topology. The ntb | ||
565 | * device should disable the link. Returning from this call must indicate that | ||
566 | * a barrier has passed, though with no more writes may pass in either | ||
567 | * direction across the link, except if this call returns an error number. | ||
568 | * | ||
569 | * Return: Zero on success, otherwise an error number. | ||
570 | */ | ||
571 | static inline int ntb_link_disable(struct ntb_dev *ntb) | ||
572 | { | ||
573 | return ntb->ops->link_disable(ntb); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * ntb_db_is_unsafe() - check if it is safe to use hardware doorbell | ||
578 | * @ntb: NTB device context. | ||
579 | * | ||
580 | * It is possible for some ntb hardware to be affected by errata. Hardware | ||
581 | * drivers can advise clients to avoid using doorbells. Clients may ignore | ||
582 | * this advice, though caution is recommended. | ||
583 | * | ||
584 | * Return: Zero if it is safe to use doorbells, or One if it is not safe. | ||
585 | */ | ||
586 | static inline int ntb_db_is_unsafe(struct ntb_dev *ntb) | ||
587 | { | ||
588 | if (!ntb->ops->db_is_unsafe) | ||
589 | return 0; | ||
590 | |||
591 | return ntb->ops->db_is_unsafe(ntb); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * ntb_db_valid_mask() - get a mask of doorbell bits supported by the ntb | ||
596 | * @ntb: NTB device context. | ||
597 | * | ||
598 | * Hardware may support different number or arrangement of doorbell bits. | ||
599 | * | ||
600 | * Return: A mask of doorbell bits supported by the ntb. | ||
601 | */ | ||
602 | static inline u64 ntb_db_valid_mask(struct ntb_dev *ntb) | ||
603 | { | ||
604 | return ntb->ops->db_valid_mask(ntb); | ||
605 | } | ||
606 | |||
607 | /** | ||
608 | * ntb_db_vector_count() - get the number of doorbell interrupt vectors | ||
609 | * @ntb: NTB device context. | ||
610 | * | ||
611 | * Hardware may support different number of interrupt vectors. | ||
612 | * | ||
613 | * Return: The number of doorbell interrupt vectors. | ||
614 | */ | ||
615 | static inline int ntb_db_vector_count(struct ntb_dev *ntb) | ||
616 | { | ||
617 | if (!ntb->ops->db_vector_count) | ||
618 | return 1; | ||
619 | |||
620 | return ntb->ops->db_vector_count(ntb); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * ntb_db_vector_mask() - get a mask of doorbell bits serviced by a vector | ||
625 | * @ntb: NTB device context. | ||
626 | * @vector: Doorbell vector number. | ||
627 | * | ||
628 | * Each interrupt vector may have a different number or arrangement of bits. | ||
629 | * | ||
630 | * Return: A mask of doorbell bits serviced by a vector. | ||
631 | */ | ||
632 | static inline u64 ntb_db_vector_mask(struct ntb_dev *ntb, int vector) | ||
633 | { | ||
634 | if (!ntb->ops->db_vector_mask) | ||
635 | return ntb_db_valid_mask(ntb); | ||
636 | |||
637 | return ntb->ops->db_vector_mask(ntb, vector); | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * ntb_db_read() - read the local doorbell register | ||
642 | * @ntb: NTB device context. | ||
643 | * | ||
644 | * Read the local doorbell register, and return the bits that are set. | ||
645 | * | ||
646 | * Return: The bits currently set in the local doorbell register. | ||
647 | */ | ||
648 | static inline u64 ntb_db_read(struct ntb_dev *ntb) | ||
649 | { | ||
650 | return ntb->ops->db_read(ntb); | ||
651 | } | ||
652 | |||
653 | /** | ||
654 | * ntb_db_set() - set bits in the local doorbell register | ||
655 | * @ntb: NTB device context. | ||
656 | * @db_bits: Doorbell bits to set. | ||
657 | * | ||
658 | * Set bits in the local doorbell register, which may generate a local doorbell | ||
659 | * interrupt. Bits that were already set must remain set. | ||
660 | * | ||
661 | * This is unusual, and hardware may not support it. | ||
662 | * | ||
663 | * Return: Zero on success, otherwise an error number. | ||
664 | */ | ||
665 | static inline int ntb_db_set(struct ntb_dev *ntb, u64 db_bits) | ||
666 | { | ||
667 | if (!ntb->ops->db_set) | ||
668 | return -EINVAL; | ||
669 | |||
670 | return ntb->ops->db_set(ntb, db_bits); | ||
671 | } | ||
672 | |||
673 | /** | ||
674 | * ntb_db_clear() - clear bits in the local doorbell register | ||
675 | * @ntb: NTB device context. | ||
676 | * @db_bits: Doorbell bits to clear. | ||
677 | * | ||
678 | * Clear bits in the local doorbell register, arming the bits for the next | ||
679 | * doorbell. | ||
680 | * | ||
681 | * Return: Zero on success, otherwise an error number. | ||
682 | */ | ||
683 | static inline int ntb_db_clear(struct ntb_dev *ntb, u64 db_bits) | ||
684 | { | ||
685 | return ntb->ops->db_clear(ntb, db_bits); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * ntb_db_read_mask() - read the local doorbell mask | ||
690 | * @ntb: NTB device context. | ||
691 | * | ||
692 | * Read the local doorbell mask register, and return the bits that are set. | ||
693 | * | ||
694 | * This is unusual, though hardware is likely to support it. | ||
695 | * | ||
696 | * Return: The bits currently set in the local doorbell mask register. | ||
697 | */ | ||
698 | static inline u64 ntb_db_read_mask(struct ntb_dev *ntb) | ||
699 | { | ||
700 | if (!ntb->ops->db_read_mask) | ||
701 | return 0; | ||
702 | |||
703 | return ntb->ops->db_read_mask(ntb); | ||
704 | } | ||
705 | |||
706 | /** | ||
707 | * ntb_db_set_mask() - set bits in the local doorbell mask | ||
708 | * @ntb: NTB device context. | ||
709 | * @db_bits: Doorbell mask bits to set. | ||
710 | * | ||
711 | * Set bits in the local doorbell mask register, preventing doorbell interrupts | ||
712 | * from being generated for those doorbell bits. Bits that were already set | ||
713 | * must remain set. | ||
714 | * | ||
715 | * Return: Zero on success, otherwise an error number. | ||
716 | */ | ||
717 | static inline int ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits) | ||
718 | { | ||
719 | return ntb->ops->db_set_mask(ntb, db_bits); | ||
720 | } | ||
721 | |||
722 | /** | ||
723 | * ntb_db_clear_mask() - clear bits in the local doorbell mask | ||
724 | * @ntb: NTB device context. | ||
725 | * @db_bits: Doorbell bits to clear. | ||
726 | * | ||
727 | * Clear bits in the local doorbell mask register, allowing doorbell interrupts | ||
728 | * from being generated for those doorbell bits. If a doorbell bit is already | ||
729 | * set at the time the mask is cleared, and the corresponding mask bit is | ||
730 | * changed from set to clear, then the ntb driver must ensure that | ||
731 | * ntb_db_event() is called. If the hardware does not generate the interrupt | ||
732 | * on clearing the mask bit, then the driver must call ntb_db_event() anyway. | ||
733 | * | ||
734 | * Return: Zero on success, otherwise an error number. | ||
735 | */ | ||
736 | static inline int ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits) | ||
737 | { | ||
738 | return ntb->ops->db_clear_mask(ntb, db_bits); | ||
739 | } | ||
740 | |||
741 | /** | ||
742 | * ntb_peer_db_addr() - address and size of the peer doorbell register | ||
743 | * @ntb: NTB device context. | ||
744 | * @db_addr: OUT - The address of the peer doorbell register. | ||
745 | * @db_size: OUT - The number of bytes to write the peer doorbell register. | ||
746 | * | ||
747 | * Return the address of the peer doorbell register. This may be used, for | ||
748 | * example, by drivers that offload memory copy operations to a dma engine. | ||
749 | * The drivers may wish to ring the peer doorbell at the completion of memory | ||
750 | * copy operations. For efficiency, and to simplify ordering of operations | ||
751 | * between the dma memory copies and the ringing doorbell, the driver may | ||
752 | * append one additional dma memory copy with the doorbell register as the | ||
753 | * destination, after the memory copy operations. | ||
754 | * | ||
755 | * Return: Zero on success, otherwise an error number. | ||
756 | */ | ||
757 | static inline int ntb_peer_db_addr(struct ntb_dev *ntb, | ||
758 | phys_addr_t *db_addr, | ||
759 | resource_size_t *db_size) | ||
760 | { | ||
761 | return ntb->ops->peer_db_addr(ntb, db_addr, db_size); | ||
762 | } | ||
763 | |||
764 | /** | ||
765 | * ntb_peer_db_read() - read the peer doorbell register | ||
766 | * @ntb: NTB device context. | ||
767 | * | ||
768 | * Read the peer doorbell register, and return the bits that are set. | ||
769 | * | ||
770 | * This is unusual, and hardware may not support it. | ||
771 | * | ||
772 | * Return: The bits currently set in the peer doorbell register. | ||
773 | */ | ||
774 | static inline u64 ntb_peer_db_read(struct ntb_dev *ntb) | ||
775 | { | ||
776 | if (!ntb->ops->peer_db_read) | ||
777 | return 0; | ||
778 | |||
779 | return ntb->ops->peer_db_read(ntb); | ||
780 | } | ||
781 | |||
782 | /** | ||
783 | * ntb_peer_db_set() - set bits in the peer doorbell register | ||
784 | * @ntb: NTB device context. | ||
785 | * @db_bits: Doorbell bits to set. | ||
786 | * | ||
787 | * Set bits in the peer doorbell register, which may generate a peer doorbell | ||
788 | * interrupt. Bits that were already set must remain set. | ||
789 | * | ||
790 | * Return: Zero on success, otherwise an error number. | ||
791 | */ | ||
792 | static inline int ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits) | ||
793 | { | ||
794 | return ntb->ops->peer_db_set(ntb, db_bits); | ||
795 | } | ||
796 | |||
797 | /** | ||
798 | * ntb_peer_db_clear() - clear bits in the local doorbell register | ||
799 | * @ntb: NTB device context. | ||
800 | * @db_bits: Doorbell bits to clear. | ||
801 | * | ||
802 | * Clear bits in the peer doorbell register, arming the bits for the next | ||
803 | * doorbell. | ||
804 | * | ||
805 | * This is unusual, and hardware may not support it. | ||
806 | * | ||
807 | * Return: Zero on success, otherwise an error number. | ||
808 | */ | ||
809 | static inline int ntb_peer_db_clear(struct ntb_dev *ntb, u64 db_bits) | ||
810 | { | ||
811 | if (!ntb->ops->db_clear) | ||
812 | return -EINVAL; | ||
813 | |||
814 | return ntb->ops->peer_db_clear(ntb, db_bits); | ||
815 | } | ||
816 | |||
817 | /** | ||
818 | * ntb_peer_db_read_mask() - read the peer doorbell mask | ||
819 | * @ntb: NTB device context. | ||
820 | * | ||
821 | * Read the peer doorbell mask register, and return the bits that are set. | ||
822 | * | ||
823 | * This is unusual, and hardware may not support it. | ||
824 | * | ||
825 | * Return: The bits currently set in the peer doorbell mask register. | ||
826 | */ | ||
827 | static inline u64 ntb_peer_db_read_mask(struct ntb_dev *ntb) | ||
828 | { | ||
829 | if (!ntb->ops->db_read_mask) | ||
830 | return 0; | ||
831 | |||
832 | return ntb->ops->peer_db_read_mask(ntb); | ||
833 | } | ||
834 | |||
835 | /** | ||
836 | * ntb_peer_db_set_mask() - set bits in the peer doorbell mask | ||
837 | * @ntb: NTB device context. | ||
838 | * @db_bits: Doorbell mask bits to set. | ||
839 | * | ||
840 | * Set bits in the peer doorbell mask register, preventing doorbell interrupts | ||
841 | * from being generated for those doorbell bits. Bits that were already set | ||
842 | * must remain set. | ||
843 | * | ||
844 | * This is unusual, and hardware may not support it. | ||
845 | * | ||
846 | * Return: Zero on success, otherwise an error number. | ||
847 | */ | ||
848 | static inline int ntb_peer_db_set_mask(struct ntb_dev *ntb, u64 db_bits) | ||
849 | { | ||
850 | if (!ntb->ops->db_set_mask) | ||
851 | return -EINVAL; | ||
852 | |||
853 | return ntb->ops->peer_db_set_mask(ntb, db_bits); | ||
854 | } | ||
855 | |||
856 | /** | ||
857 | * ntb_peer_db_clear_mask() - clear bits in the peer doorbell mask | ||
858 | * @ntb: NTB device context. | ||
859 | * @db_bits: Doorbell bits to clear. | ||
860 | * | ||
861 | * Clear bits in the peer doorbell mask register, allowing doorbell interrupts | ||
862 | * from being generated for those doorbell bits. If the hardware does not | ||
863 | * generate the interrupt on clearing the mask bit, then the driver should not | ||
864 | * implement this function! | ||
865 | * | ||
866 | * This is unusual, and hardware may not support it. | ||
867 | * | ||
868 | * Return: Zero on success, otherwise an error number. | ||
869 | */ | ||
870 | static inline int ntb_peer_db_clear_mask(struct ntb_dev *ntb, u64 db_bits) | ||
871 | { | ||
872 | if (!ntb->ops->db_clear_mask) | ||
873 | return -EINVAL; | ||
874 | |||
875 | return ntb->ops->peer_db_clear_mask(ntb, db_bits); | ||
876 | } | ||
877 | |||
878 | /** | ||
879 | * ntb_spad_is_unsafe() - check if it is safe to use the hardware scratchpads | ||
880 | * @ntb: NTB device context. | ||
881 | * | ||
882 | * It is possible for some ntb hardware to be affected by errata. Hardware | ||
883 | * drivers can advise clients to avoid using scratchpads. Clients may ignore | ||
884 | * this advice, though caution is recommended. | ||
885 | * | ||
886 | * Return: Zero if it is safe to use scratchpads, or One if it is not safe. | ||
887 | */ | ||
888 | static inline int ntb_spad_is_unsafe(struct ntb_dev *ntb) | ||
889 | { | ||
890 | if (!ntb->ops->spad_is_unsafe) | ||
891 | return 0; | ||
892 | |||
893 | return ntb->ops->spad_is_unsafe(ntb); | ||
894 | } | ||
895 | |||
896 | /** | ||
897 | * ntb_mw_count() - get the number of scratchpads | ||
898 | * @ntb: NTB device context. | ||
899 | * | ||
900 | * Hardware and topology may support a different number of scratchpads. | ||
901 | * | ||
902 | * Return: the number of scratchpads. | ||
903 | */ | ||
904 | static inline int ntb_spad_count(struct ntb_dev *ntb) | ||
905 | { | ||
906 | return ntb->ops->spad_count(ntb); | ||
907 | } | ||
908 | |||
909 | /** | ||
910 | * ntb_spad_read() - read the local scratchpad register | ||
911 | * @ntb: NTB device context. | ||
912 | * @idx: Scratchpad index. | ||
913 | * | ||
914 | * Read the local scratchpad register, and return the value. | ||
915 | * | ||
916 | * Return: The value of the local scratchpad register. | ||
917 | */ | ||
918 | static inline u32 ntb_spad_read(struct ntb_dev *ntb, int idx) | ||
919 | { | ||
920 | return ntb->ops->spad_read(ntb, idx); | ||
921 | } | ||
922 | |||
923 | /** | ||
924 | * ntb_spad_write() - write the local scratchpad register | ||
925 | * @ntb: NTB device context. | ||
926 | * @idx: Scratchpad index. | ||
927 | * @val: Scratchpad value. | ||
928 | * | ||
929 | * Write the value to the local scratchpad register. | ||
930 | * | ||
931 | * Return: Zero on success, otherwise an error number. | ||
932 | */ | ||
933 | static inline int ntb_spad_write(struct ntb_dev *ntb, int idx, u32 val) | ||
934 | { | ||
935 | return ntb->ops->spad_write(ntb, idx, val); | ||
936 | } | ||
937 | |||
938 | /** | ||
939 | * ntb_peer_spad_addr() - address of the peer scratchpad register | ||
940 | * @ntb: NTB device context. | ||
941 | * @idx: Scratchpad index. | ||
942 | * @spad_addr: OUT - The address of the peer scratchpad register. | ||
943 | * | ||
944 | * Return the address of the peer doorbell register. This may be used, for | ||
945 | * example, by drivers that offload memory copy operations to a dma engine. | ||
946 | * | ||
947 | * Return: Zero on success, otherwise an error number. | ||
948 | */ | ||
949 | static inline int ntb_peer_spad_addr(struct ntb_dev *ntb, int idx, | ||
950 | phys_addr_t *spad_addr) | ||
951 | { | ||
952 | return ntb->ops->peer_spad_addr(ntb, idx, spad_addr); | ||
953 | } | ||
954 | |||
955 | /** | ||
956 | * ntb_peer_spad_read() - read the peer scratchpad register | ||
957 | * @ntb: NTB device context. | ||
958 | * @idx: Scratchpad index. | ||
959 | * | ||
960 | * Read the peer scratchpad register, and return the value. | ||
961 | * | ||
962 | * Return: The value of the local scratchpad register. | ||
963 | */ | ||
964 | static inline u32 ntb_peer_spad_read(struct ntb_dev *ntb, int idx) | ||
965 | { | ||
966 | return ntb->ops->peer_spad_read(ntb, idx); | ||
967 | } | ||
968 | |||
969 | /** | ||
970 | * ntb_peer_spad_write() - write the peer scratchpad register | ||
971 | * @ntb: NTB device context. | ||
972 | * @idx: Scratchpad index. | ||
973 | * @val: Scratchpad value. | ||
974 | * | ||
975 | * Write the value to the peer scratchpad register. | ||
976 | * | ||
977 | * Return: Zero on success, otherwise an error number. | ||
978 | */ | ||
979 | static inline int ntb_peer_spad_write(struct ntb_dev *ntb, int idx, u32 val) | ||
980 | { | ||
981 | return ntb->ops->peer_spad_write(ntb, idx, val); | ||
982 | } | ||
983 | |||
984 | #endif | ||