aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/infiniband/core
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/Makefile12
-rw-r--r--drivers/infiniband/core/agent.c373
-rw-r--r--drivers/infiniband/core/agent.h55
-rw-r--r--drivers/infiniband/core/agent_priv.h63
-rw-r--r--drivers/infiniband/core/cache.c365
-rw-r--r--drivers/infiniband/core/core_priv.h52
-rw-r--r--drivers/infiniband/core/device.c614
-rw-r--r--drivers/infiniband/core/fmr_pool.c507
-rw-r--r--drivers/infiniband/core/mad.c2714
-rw-r--r--drivers/infiniband/core/mad_priv.h199
-rw-r--r--drivers/infiniband/core/packer.c201
-rw-r--r--drivers/infiniband/core/sa_query.c866
-rw-r--r--drivers/infiniband/core/smi.c234
-rw-r--r--drivers/infiniband/core/smi.h67
-rw-r--r--drivers/infiniband/core/sysfs.c762
-rw-r--r--drivers/infiniband/core/ud_header.c365
-rw-r--r--drivers/infiniband/core/user_mad.c840
-rw-r--r--drivers/infiniband/core/verbs.c434
18 files changed, 8723 insertions, 0 deletions
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
new file mode 100644
index 000000000000..d2dbfb52c0a3
--- /dev/null
+++ b/drivers/infiniband/core/Makefile
@@ -0,0 +1,12 @@
1EXTRA_CFLAGS += -Idrivers/infiniband/include
2
3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o ib_umad.o
4
5ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
6 device.o fmr_pool.o cache.o
7
8ib_mad-y := mad.o smi.o agent.o
9
10ib_sa-y := sa_query.o
11
12ib_umad-y := user_mad.o
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
new file mode 100644
index 000000000000..7aee5ebf3f01
--- /dev/null
+++ b/drivers/infiniband/core/agent.c
@@ -0,0 +1,373 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
37 */
38
39#include <linux/dma-mapping.h>
40
41#include <asm/bug.h>
42
43#include <ib_smi.h>
44
45#include "smi.h"
46#include "agent_priv.h"
47#include "mad_priv.h"
48#include "agent.h"
49
50spinlock_t ib_agent_port_list_lock;
51static LIST_HEAD(ib_agent_port_list);
52
53/*
54 * Caller must hold ib_agent_port_list_lock
55 */
56static inline struct ib_agent_port_private *
57__ib_get_agent_port(struct ib_device *device, int port_num,
58 struct ib_mad_agent *mad_agent)
59{
60 struct ib_agent_port_private *entry;
61
62 BUG_ON(!(!!device ^ !!mad_agent)); /* Exactly one MUST be (!NULL) */
63
64 if (device) {
65 list_for_each_entry(entry, &ib_agent_port_list, port_list) {
66 if (entry->smp_agent->device == device &&
67 entry->port_num == port_num)
68 return entry;
69 }
70 } else {
71 list_for_each_entry(entry, &ib_agent_port_list, port_list) {
72 if ((entry->smp_agent == mad_agent) ||
73 (entry->perf_mgmt_agent == mad_agent))
74 return entry;
75 }
76 }
77 return NULL;
78}
79
80static inline struct ib_agent_port_private *
81ib_get_agent_port(struct ib_device *device, int port_num,
82 struct ib_mad_agent *mad_agent)
83{
84 struct ib_agent_port_private *entry;
85 unsigned long flags;
86
87 spin_lock_irqsave(&ib_agent_port_list_lock, flags);
88 entry = __ib_get_agent_port(device, port_num, mad_agent);
89 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
90
91 return entry;
92}
93
94int smi_check_local_dr_smp(struct ib_smp *smp,
95 struct ib_device *device,
96 int port_num)
97{
98 struct ib_agent_port_private *port_priv;
99
100 if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
101 return 1;
102 port_priv = ib_get_agent_port(device, port_num, NULL);
103 if (!port_priv) {
104 printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d "
105 "not open\n",
106 device->name, port_num);
107 return 1;
108 }
109
110 return smi_check_local_smp(port_priv->smp_agent, smp);
111}
112
113static int agent_mad_send(struct ib_mad_agent *mad_agent,
114 struct ib_agent_port_private *port_priv,
115 struct ib_mad_private *mad_priv,
116 struct ib_grh *grh,
117 struct ib_wc *wc)
118{
119 struct ib_agent_send_wr *agent_send_wr;
120 struct ib_sge gather_list;
121 struct ib_send_wr send_wr;
122 struct ib_send_wr *bad_send_wr;
123 struct ib_ah_attr ah_attr;
124 unsigned long flags;
125 int ret = 1;
126
127 agent_send_wr = kmalloc(sizeof(*agent_send_wr), GFP_KERNEL);
128 if (!agent_send_wr)
129 goto out;
130 agent_send_wr->mad = mad_priv;
131
132 /* PCI mapping */
133 gather_list.addr = dma_map_single(mad_agent->device->dma_device,
134 &mad_priv->mad,
135 sizeof(mad_priv->mad),
136 DMA_TO_DEVICE);
137 gather_list.length = sizeof(mad_priv->mad);
138 gather_list.lkey = (*port_priv->mr).lkey;
139
140 send_wr.next = NULL;
141 send_wr.opcode = IB_WR_SEND;
142 send_wr.sg_list = &gather_list;
143 send_wr.num_sge = 1;
144 send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */
145 send_wr.wr.ud.timeout_ms = 0;
146 send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED;
147
148 ah_attr.dlid = wc->slid;
149 ah_attr.port_num = mad_agent->port_num;
150 ah_attr.src_path_bits = wc->dlid_path_bits;
151 ah_attr.sl = wc->sl;
152 ah_attr.static_rate = 0;
153 ah_attr.ah_flags = 0; /* No GRH */
154 if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
155 if (wc->wc_flags & IB_WC_GRH) {
156 ah_attr.ah_flags = IB_AH_GRH;
157 /* Should sgid be looked up ? */
158 ah_attr.grh.sgid_index = 0;
159 ah_attr.grh.hop_limit = grh->hop_limit;
160 ah_attr.grh.flow_label = be32_to_cpup(
161 &grh->version_tclass_flow) & 0xfffff;
162 ah_attr.grh.traffic_class = (be32_to_cpup(
163 &grh->version_tclass_flow) >> 20) & 0xff;
164 memcpy(ah_attr.grh.dgid.raw,
165 grh->sgid.raw,
166 sizeof(ah_attr.grh.dgid));
167 }
168 }
169
170 agent_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr);
171 if (IS_ERR(agent_send_wr->ah)) {
172 printk(KERN_ERR SPFX "No memory for address handle\n");
173 kfree(agent_send_wr);
174 goto out;
175 }
176
177 send_wr.wr.ud.ah = agent_send_wr->ah;
178 if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
179 send_wr.wr.ud.pkey_index = wc->pkey_index;
180 send_wr.wr.ud.remote_qkey = IB_QP1_QKEY;
181 } else { /* for SMPs */
182 send_wr.wr.ud.pkey_index = 0;
183 send_wr.wr.ud.remote_qkey = 0;
184 }
185 send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr;
186 send_wr.wr_id = (unsigned long)agent_send_wr;
187
188 pci_unmap_addr_set(agent_send_wr, mapping, gather_list.addr);
189
190 /* Send */
191 spin_lock_irqsave(&port_priv->send_list_lock, flags);
192 if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) {
193 spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
194 dma_unmap_single(mad_agent->device->dma_device,
195 pci_unmap_addr(agent_send_wr, mapping),
196 sizeof(mad_priv->mad),
197 DMA_TO_DEVICE);
198 ib_destroy_ah(agent_send_wr->ah);
199 kfree(agent_send_wr);
200 } else {
201 list_add_tail(&agent_send_wr->send_list,
202 &port_priv->send_posted_list);
203 spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
204 ret = 0;
205 }
206
207out:
208 return ret;
209}
210
211int agent_send(struct ib_mad_private *mad,
212 struct ib_grh *grh,
213 struct ib_wc *wc,
214 struct ib_device *device,
215 int port_num)
216{
217 struct ib_agent_port_private *port_priv;
218 struct ib_mad_agent *mad_agent;
219
220 port_priv = ib_get_agent_port(device, port_num, NULL);
221 if (!port_priv) {
222 printk(KERN_DEBUG SPFX "agent_send %s port %d not open\n",
223 device->name, port_num);
224 return 1;
225 }
226
227 /* Get mad agent based on mgmt_class in MAD */
228 switch (mad->mad.mad.mad_hdr.mgmt_class) {
229 case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
230 case IB_MGMT_CLASS_SUBN_LID_ROUTED:
231 mad_agent = port_priv->smp_agent;
232 break;
233 case IB_MGMT_CLASS_PERF_MGMT:
234 mad_agent = port_priv->perf_mgmt_agent;
235 break;
236 default:
237 return 1;
238 }
239
240 return agent_mad_send(mad_agent, port_priv, mad, grh, wc);
241}
242
243static void agent_send_handler(struct ib_mad_agent *mad_agent,
244 struct ib_mad_send_wc *mad_send_wc)
245{
246 struct ib_agent_port_private *port_priv;
247 struct ib_agent_send_wr *agent_send_wr;
248 unsigned long flags;
249
250 /* Find matching MAD agent */
251 port_priv = ib_get_agent_port(NULL, 0, mad_agent);
252 if (!port_priv) {
253 printk(KERN_ERR SPFX "agent_send_handler: no matching MAD "
254 "agent %p\n", mad_agent);
255 return;
256 }
257
258 agent_send_wr = (struct ib_agent_send_wr *)(unsigned long)mad_send_wc->wr_id;
259 spin_lock_irqsave(&port_priv->send_list_lock, flags);
260 /* Remove completed send from posted send MAD list */
261 list_del(&agent_send_wr->send_list);
262 spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
263
264 /* Unmap PCI */
265 dma_unmap_single(mad_agent->device->dma_device,
266 pci_unmap_addr(agent_send_wr, mapping),
267 sizeof(agent_send_wr->mad->mad),
268 DMA_TO_DEVICE);
269
270 ib_destroy_ah(agent_send_wr->ah);
271
272 /* Release allocated memory */
273 kmem_cache_free(ib_mad_cache, agent_send_wr->mad);
274 kfree(agent_send_wr);
275}
276
277int ib_agent_port_open(struct ib_device *device, int port_num)
278{
279 int ret;
280 struct ib_agent_port_private *port_priv;
281 unsigned long flags;
282
283 /* First, check if port already open for SMI */
284 port_priv = ib_get_agent_port(device, port_num, NULL);
285 if (port_priv) {
286 printk(KERN_DEBUG SPFX "%s port %d already open\n",
287 device->name, port_num);
288 return 0;
289 }
290
291 /* Create new device info */
292 port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
293 if (!port_priv) {
294 printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n");
295 ret = -ENOMEM;
296 goto error1;
297 }
298
299 memset(port_priv, 0, sizeof *port_priv);
300 port_priv->port_num = port_num;
301 spin_lock_init(&port_priv->send_list_lock);
302 INIT_LIST_HEAD(&port_priv->send_posted_list);
303
304 /* Obtain send only MAD agent for SM class (SMI QP) */
305 port_priv->smp_agent = ib_register_mad_agent(device, port_num,
306 IB_QPT_SMI,
307 NULL, 0,
308 &agent_send_handler,
309 NULL, NULL);
310
311 if (IS_ERR(port_priv->smp_agent)) {
312 ret = PTR_ERR(port_priv->smp_agent);
313 goto error2;
314 }
315
316 /* Obtain send only MAD agent for PerfMgmt class (GSI QP) */
317 port_priv->perf_mgmt_agent = ib_register_mad_agent(device, port_num,
318 IB_QPT_GSI,
319 NULL, 0,
320 &agent_send_handler,
321 NULL, NULL);
322 if (IS_ERR(port_priv->perf_mgmt_agent)) {
323 ret = PTR_ERR(port_priv->perf_mgmt_agent);
324 goto error3;
325 }
326
327 port_priv->mr = ib_get_dma_mr(port_priv->smp_agent->qp->pd,
328 IB_ACCESS_LOCAL_WRITE);
329 if (IS_ERR(port_priv->mr)) {
330 printk(KERN_ERR SPFX "Couldn't get DMA MR\n");
331 ret = PTR_ERR(port_priv->mr);
332 goto error4;
333 }
334
335 spin_lock_irqsave(&ib_agent_port_list_lock, flags);
336 list_add_tail(&port_priv->port_list, &ib_agent_port_list);
337 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
338
339 return 0;
340
341error4:
342 ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
343error3:
344 ib_unregister_mad_agent(port_priv->smp_agent);
345error2:
346 kfree(port_priv);
347error1:
348 return ret;
349}
350
351int ib_agent_port_close(struct ib_device *device, int port_num)
352{
353 struct ib_agent_port_private *port_priv;
354 unsigned long flags;
355
356 spin_lock_irqsave(&ib_agent_port_list_lock, flags);
357 port_priv = __ib_get_agent_port(device, port_num, NULL);
358 if (port_priv == NULL) {
359 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
360 printk(KERN_ERR SPFX "Port %d not found\n", port_num);
361 return -ENODEV;
362 }
363 list_del(&port_priv->port_list);
364 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
365
366 ib_dereg_mr(port_priv->mr);
367
368 ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
369 ib_unregister_mad_agent(port_priv->smp_agent);
370 kfree(port_priv);
371
372 return 0;
373}
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
new file mode 100644
index 000000000000..d9426842254a
--- /dev/null
+++ b/drivers/infiniband/core/agent.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: agent.h 1389 2004-12-27 22:56:47Z roland $
37 */
38
39#ifndef __AGENT_H_
40#define __AGENT_H_
41
42extern spinlock_t ib_agent_port_list_lock;
43
44extern int ib_agent_port_open(struct ib_device *device,
45 int port_num);
46
47extern int ib_agent_port_close(struct ib_device *device, int port_num);
48
49extern int agent_send(struct ib_mad_private *mad,
50 struct ib_grh *grh,
51 struct ib_wc *wc,
52 struct ib_device *device,
53 int port_num);
54
55#endif /* __AGENT_H_ */
diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
new file mode 100644
index 000000000000..17a0cce5813c
--- /dev/null
+++ b/drivers/infiniband/core/agent_priv.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: agent_priv.h 1389 2004-12-27 22:56:47Z roland $
37 */
38
39#ifndef __IB_AGENT_PRIV_H__
40#define __IB_AGENT_PRIV_H__
41
42#include <linux/pci.h>
43
44#define SPFX "ib_agent: "
45
46struct ib_agent_send_wr {
47 struct list_head send_list;
48 struct ib_ah *ah;
49 struct ib_mad_private *mad;
50 DECLARE_PCI_UNMAP_ADDR(mapping)
51};
52
53struct ib_agent_port_private {
54 struct list_head port_list;
55 struct list_head send_posted_list;
56 spinlock_t send_list_lock;
57 int port_num;
58 struct ib_mad_agent *smp_agent; /* SM class */
59 struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
60 struct ib_mr *mr;
61};
62
63#endif /* __IB_AGENT_PRIV_H__ */
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
new file mode 100644
index 000000000000..3042360c97e1
--- /dev/null
+++ b/drivers/infiniband/core/cache.c
@@ -0,0 +1,365 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include <linux/version.h>
36#include <linux/module.h>
37#include <linux/errno.h>
38#include <linux/slab.h>
39
40#include <ib_cache.h>
41
42#include "core_priv.h"
43
44struct ib_pkey_cache {
45 int table_len;
46 u16 table[0];
47};
48
49struct ib_gid_cache {
50 int table_len;
51 union ib_gid table[0];
52};
53
54struct ib_update_work {
55 struct work_struct work;
56 struct ib_device *device;
57 u8 port_num;
58};
59
60static inline int start_port(struct ib_device *device)
61{
62 return device->node_type == IB_NODE_SWITCH ? 0 : 1;
63}
64
65static inline int end_port(struct ib_device *device)
66{
67 return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt;
68}
69
70int ib_get_cached_gid(struct ib_device *device,
71 u8 port_num,
72 int index,
73 union ib_gid *gid)
74{
75 struct ib_gid_cache *cache;
76 unsigned long flags;
77 int ret = 0;
78
79 if (port_num < start_port(device) || port_num > end_port(device))
80 return -EINVAL;
81
82 read_lock_irqsave(&device->cache.lock, flags);
83
84 cache = device->cache.gid_cache[port_num - start_port(device)];
85
86 if (index < 0 || index >= cache->table_len)
87 ret = -EINVAL;
88 else
89 *gid = cache->table[index];
90
91 read_unlock_irqrestore(&device->cache.lock, flags);
92
93 return ret;
94}
95EXPORT_SYMBOL(ib_get_cached_gid);
96
97int ib_find_cached_gid(struct ib_device *device,
98 union ib_gid *gid,
99 u8 *port_num,
100 u16 *index)
101{
102 struct ib_gid_cache *cache;
103 unsigned long flags;
104 int p, i;
105 int ret = -ENOENT;
106
107 *port_num = -1;
108 if (index)
109 *index = -1;
110
111 read_lock_irqsave(&device->cache.lock, flags);
112
113 for (p = 0; p <= end_port(device) - start_port(device); ++p) {
114 cache = device->cache.gid_cache[p];
115 for (i = 0; i < cache->table_len; ++i) {
116 if (!memcmp(gid, &cache->table[i], sizeof *gid)) {
117 *port_num = p + start_port(device);
118 if (index)
119 *index = i;
120 ret = 0;
121 goto found;
122 }
123 }
124 }
125found:
126 read_unlock_irqrestore(&device->cache.lock, flags);
127
128 return ret;
129}
130EXPORT_SYMBOL(ib_find_cached_gid);
131
132int ib_get_cached_pkey(struct ib_device *device,
133 u8 port_num,
134 int index,
135 u16 *pkey)
136{
137 struct ib_pkey_cache *cache;
138 unsigned long flags;
139 int ret = 0;
140
141 if (port_num < start_port(device) || port_num > end_port(device))
142 return -EINVAL;
143
144 read_lock_irqsave(&device->cache.lock, flags);
145
146 cache = device->cache.pkey_cache[port_num - start_port(device)];
147
148 if (index < 0 || index >= cache->table_len)
149 ret = -EINVAL;
150 else
151 *pkey = cache->table[index];
152
153 read_unlock_irqrestore(&device->cache.lock, flags);
154
155 return ret;
156}
157EXPORT_SYMBOL(ib_get_cached_pkey);
158
159int ib_find_cached_pkey(struct ib_device *device,
160 u8 port_num,
161 u16 pkey,
162 u16 *index)
163{
164 struct ib_pkey_cache *cache;
165 unsigned long flags;
166 int i;
167 int ret = -ENOENT;
168
169 if (port_num < start_port(device) || port_num > end_port(device))
170 return -EINVAL;
171
172 read_lock_irqsave(&device->cache.lock, flags);
173
174 cache = device->cache.pkey_cache[port_num - start_port(device)];
175
176 *index = -1;
177
178 for (i = 0; i < cache->table_len; ++i)
179 if ((cache->table[i] & 0x7fff) == (pkey & 0x7fff)) {
180 *index = i;
181 ret = 0;
182 break;
183 }
184
185 read_unlock_irqrestore(&device->cache.lock, flags);
186
187 return ret;
188}
189EXPORT_SYMBOL(ib_find_cached_pkey);
190
191static void ib_cache_update(struct ib_device *device,
192 u8 port)
193{
194 struct ib_port_attr *tprops = NULL;
195 struct ib_pkey_cache *pkey_cache = NULL, *old_pkey_cache;
196 struct ib_gid_cache *gid_cache = NULL, *old_gid_cache;
197 int i;
198 int ret;
199
200 tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
201 if (!tprops)
202 return;
203
204 ret = ib_query_port(device, port, tprops);
205 if (ret) {
206 printk(KERN_WARNING "ib_query_port failed (%d) for %s\n",
207 ret, device->name);
208 goto err;
209 }
210
211 pkey_cache = kmalloc(sizeof *pkey_cache + tprops->pkey_tbl_len *
212 sizeof *pkey_cache->table, GFP_KERNEL);
213 if (!pkey_cache)
214 goto err;
215
216 pkey_cache->table_len = tprops->pkey_tbl_len;
217
218 gid_cache = kmalloc(sizeof *gid_cache + tprops->gid_tbl_len *
219 sizeof *gid_cache->table, GFP_KERNEL);
220 if (!gid_cache)
221 goto err;
222
223 gid_cache->table_len = tprops->gid_tbl_len;
224
225 for (i = 0; i < pkey_cache->table_len; ++i) {
226 ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
227 if (ret) {
228 printk(KERN_WARNING "ib_query_pkey failed (%d) for %s (index %d)\n",
229 ret, device->name, i);
230 goto err;
231 }
232 }
233
234 for (i = 0; i < gid_cache->table_len; ++i) {
235 ret = ib_query_gid(device, port, i, gid_cache->table + i);
236 if (ret) {
237 printk(KERN_WARNING "ib_query_gid failed (%d) for %s (index %d)\n",
238 ret, device->name, i);
239 goto err;
240 }
241 }
242
243 write_lock_irq(&device->cache.lock);
244
245 old_pkey_cache = device->cache.pkey_cache[port - start_port(device)];
246 old_gid_cache = device->cache.gid_cache [port - start_port(device)];
247
248 device->cache.pkey_cache[port - start_port(device)] = pkey_cache;
249 device->cache.gid_cache [port - start_port(device)] = gid_cache;
250
251 write_unlock_irq(&device->cache.lock);
252
253 kfree(old_pkey_cache);
254 kfree(old_gid_cache);
255 kfree(tprops);
256 return;
257
258err:
259 kfree(pkey_cache);
260 kfree(gid_cache);
261 kfree(tprops);
262}
263
264static void ib_cache_task(void *work_ptr)
265{
266 struct ib_update_work *work = work_ptr;
267
268 ib_cache_update(work->device, work->port_num);
269 kfree(work);
270}
271
272static void ib_cache_event(struct ib_event_handler *handler,
273 struct ib_event *event)
274{
275 struct ib_update_work *work;
276
277 if (event->event == IB_EVENT_PORT_ERR ||
278 event->event == IB_EVENT_PORT_ACTIVE ||
279 event->event == IB_EVENT_LID_CHANGE ||
280 event->event == IB_EVENT_PKEY_CHANGE ||
281 event->event == IB_EVENT_SM_CHANGE) {
282 work = kmalloc(sizeof *work, GFP_ATOMIC);
283 if (work) {
284 INIT_WORK(&work->work, ib_cache_task, work);
285 work->device = event->device;
286 work->port_num = event->element.port_num;
287 schedule_work(&work->work);
288 }
289 }
290}
291
292static void ib_cache_setup_one(struct ib_device *device)
293{
294 int p;
295
296 rwlock_init(&device->cache.lock);
297
298 device->cache.pkey_cache =
299 kmalloc(sizeof *device->cache.pkey_cache *
300 (end_port(device) - start_port(device) + 1), GFP_KERNEL);
301 device->cache.gid_cache =
302 kmalloc(sizeof *device->cache.pkey_cache *
303 (end_port(device) - start_port(device) + 1), GFP_KERNEL);
304
305 if (!device->cache.pkey_cache || !device->cache.gid_cache) {
306 printk(KERN_WARNING "Couldn't allocate cache "
307 "for %s\n", device->name);
308 goto err;
309 }
310
311 for (p = 0; p <= end_port(device) - start_port(device); ++p) {
312 device->cache.pkey_cache[p] = NULL;
313 device->cache.gid_cache [p] = NULL;
314 ib_cache_update(device, p + start_port(device));
315 }
316
317 INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
318 device, ib_cache_event);
319 if (ib_register_event_handler(&device->cache.event_handler))
320 goto err_cache;
321
322 return;
323
324err_cache:
325 for (p = 0; p <= end_port(device) - start_port(device); ++p) {
326 kfree(device->cache.pkey_cache[p]);
327 kfree(device->cache.gid_cache[p]);
328 }
329
330err:
331 kfree(device->cache.pkey_cache);
332 kfree(device->cache.gid_cache);
333}
334
335static void ib_cache_cleanup_one(struct ib_device *device)
336{
337 int p;
338
339 ib_unregister_event_handler(&device->cache.event_handler);
340 flush_scheduled_work();
341
342 for (p = 0; p <= end_port(device) - start_port(device); ++p) {
343 kfree(device->cache.pkey_cache[p]);
344 kfree(device->cache.gid_cache[p]);
345 }
346
347 kfree(device->cache.pkey_cache);
348 kfree(device->cache.gid_cache);
349}
350
351static struct ib_client cache_client = {
352 .name = "cache",
353 .add = ib_cache_setup_one,
354 .remove = ib_cache_cleanup_one
355};
356
357int __init ib_cache_setup(void)
358{
359 return ib_register_client(&cache_client);
360}
361
362void __exit ib_cache_cleanup(void)
363{
364 ib_unregister_client(&cache_client);
365}
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
new file mode 100644
index 000000000000..797049626ff6
--- /dev/null
+++ b/drivers/infiniband/core/core_priv.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: core_priv.h 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#ifndef _CORE_PRIV_H
36#define _CORE_PRIV_H
37
38#include <linux/list.h>
39#include <linux/spinlock.h>
40
41#include <ib_verbs.h>
42
43int ib_device_register_sysfs(struct ib_device *device);
44void ib_device_unregister_sysfs(struct ib_device *device);
45
46int ib_sysfs_setup(void);
47void ib_sysfs_cleanup(void);
48
49int ib_cache_setup(void);
50void ib_cache_cleanup(void);
51
52#endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
new file mode 100644
index 000000000000..9197e92d708a
--- /dev/null
+++ b/drivers/infiniband/core/device.c
@@ -0,0 +1,614 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: device.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include <linux/module.h>
36#include <linux/string.h>
37#include <linux/errno.h>
38#include <linux/slab.h>
39#include <linux/init.h>
40
41#include <asm/semaphore.h>
42
43#include "core_priv.h"
44
45MODULE_AUTHOR("Roland Dreier");
46MODULE_DESCRIPTION("core kernel InfiniBand API");
47MODULE_LICENSE("Dual BSD/GPL");
48
49struct ib_client_data {
50 struct list_head list;
51 struct ib_client *client;
52 void * data;
53};
54
55static LIST_HEAD(device_list);
56static LIST_HEAD(client_list);
57
58/*
59 * device_sem protects access to both device_list and client_list.
60 * There's no real point to using multiple locks or something fancier
61 * like an rwsem: we always access both lists, and we're always
62 * modifying one list or the other list. In any case this is not a
63 * hot path so there's no point in trying to optimize.
64 */
65static DECLARE_MUTEX(device_sem);
66
67static int ib_device_check_mandatory(struct ib_device *device)
68{
69#define IB_MANDATORY_FUNC(x) { offsetof(struct ib_device, x), #x }
70 static const struct {
71 size_t offset;
72 char *name;
73 } mandatory_table[] = {
74 IB_MANDATORY_FUNC(query_device),
75 IB_MANDATORY_FUNC(query_port),
76 IB_MANDATORY_FUNC(query_pkey),
77 IB_MANDATORY_FUNC(query_gid),
78 IB_MANDATORY_FUNC(alloc_pd),
79 IB_MANDATORY_FUNC(dealloc_pd),
80 IB_MANDATORY_FUNC(create_ah),
81 IB_MANDATORY_FUNC(destroy_ah),
82 IB_MANDATORY_FUNC(create_qp),
83 IB_MANDATORY_FUNC(modify_qp),
84 IB_MANDATORY_FUNC(destroy_qp),
85 IB_MANDATORY_FUNC(post_send),
86 IB_MANDATORY_FUNC(post_recv),
87 IB_MANDATORY_FUNC(create_cq),
88 IB_MANDATORY_FUNC(destroy_cq),
89 IB_MANDATORY_FUNC(poll_cq),
90 IB_MANDATORY_FUNC(req_notify_cq),
91 IB_MANDATORY_FUNC(get_dma_mr),
92 IB_MANDATORY_FUNC(dereg_mr)
93 };
94 int i;
95
96 for (i = 0; i < sizeof mandatory_table / sizeof mandatory_table[0]; ++i) {
97 if (!*(void **) ((void *) device + mandatory_table[i].offset)) {
98 printk(KERN_WARNING "Device %s is missing mandatory function %s\n",
99 device->name, mandatory_table[i].name);
100 return -EINVAL;
101 }
102 }
103
104 return 0;
105}
106
107static struct ib_device *__ib_device_get_by_name(const char *name)
108{
109 struct ib_device *device;
110
111 list_for_each_entry(device, &device_list, core_list)
112 if (!strncmp(name, device->name, IB_DEVICE_NAME_MAX))
113 return device;
114
115 return NULL;
116}
117
118
119static int alloc_name(char *name)
120{
121 long *inuse;
122 char buf[IB_DEVICE_NAME_MAX];
123 struct ib_device *device;
124 int i;
125
126 inuse = (long *) get_zeroed_page(GFP_KERNEL);
127 if (!inuse)
128 return -ENOMEM;
129
130 list_for_each_entry(device, &device_list, core_list) {
131 if (!sscanf(device->name, name, &i))
132 continue;
133 if (i < 0 || i >= PAGE_SIZE * 8)
134 continue;
135 snprintf(buf, sizeof buf, name, i);
136 if (!strncmp(buf, device->name, IB_DEVICE_NAME_MAX))
137 set_bit(i, inuse);
138 }
139
140 i = find_first_zero_bit(inuse, PAGE_SIZE * 8);
141 free_page((unsigned long) inuse);
142 snprintf(buf, sizeof buf, name, i);
143
144 if (__ib_device_get_by_name(buf))
145 return -ENFILE;
146
147 strlcpy(name, buf, IB_DEVICE_NAME_MAX);
148 return 0;
149}
150
151/**
152 * ib_alloc_device - allocate an IB device struct
153 * @size:size of structure to allocate
154 *
155 * Low-level drivers should use ib_alloc_device() to allocate &struct
156 * ib_device. @size is the size of the structure to be allocated,
157 * including any private data used by the low-level driver.
158 * ib_dealloc_device() must be used to free structures allocated with
159 * ib_alloc_device().
160 */
161struct ib_device *ib_alloc_device(size_t size)
162{
163 void *dev;
164
165 BUG_ON(size < sizeof (struct ib_device));
166
167 dev = kmalloc(size, GFP_KERNEL);
168 if (!dev)
169 return NULL;
170
171 memset(dev, 0, size);
172
173 return dev;
174}
175EXPORT_SYMBOL(ib_alloc_device);
176
177/**
178 * ib_dealloc_device - free an IB device struct
179 * @device:structure to free
180 *
181 * Free a structure allocated with ib_alloc_device().
182 */
183void ib_dealloc_device(struct ib_device *device)
184{
185 if (device->reg_state == IB_DEV_UNINITIALIZED) {
186 kfree(device);
187 return;
188 }
189
190 BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
191
192 ib_device_unregister_sysfs(device);
193}
194EXPORT_SYMBOL(ib_dealloc_device);
195
196static int add_client_context(struct ib_device *device, struct ib_client *client)
197{
198 struct ib_client_data *context;
199 unsigned long flags;
200
201 context = kmalloc(sizeof *context, GFP_KERNEL);
202 if (!context) {
203 printk(KERN_WARNING "Couldn't allocate client context for %s/%s\n",
204 device->name, client->name);
205 return -ENOMEM;
206 }
207
208 context->client = client;
209 context->data = NULL;
210
211 spin_lock_irqsave(&device->client_data_lock, flags);
212 list_add(&context->list, &device->client_data_list);
213 spin_unlock_irqrestore(&device->client_data_lock, flags);
214
215 return 0;
216}
217
218/**
219 * ib_register_device - Register an IB device with IB core
220 * @device:Device to register
221 *
222 * Low-level drivers use ib_register_device() to register their
223 * devices with the IB core. All registered clients will receive a
224 * callback for each device that is added. @device must be allocated
225 * with ib_alloc_device().
226 */
227int ib_register_device(struct ib_device *device)
228{
229 int ret;
230
231 down(&device_sem);
232
233 if (strchr(device->name, '%')) {
234 ret = alloc_name(device->name);
235 if (ret)
236 goto out;
237 }
238
239 if (ib_device_check_mandatory(device)) {
240 ret = -EINVAL;
241 goto out;
242 }
243
244 INIT_LIST_HEAD(&device->event_handler_list);
245 INIT_LIST_HEAD(&device->client_data_list);
246 spin_lock_init(&device->event_handler_lock);
247 spin_lock_init(&device->client_data_lock);
248
249 ret = ib_device_register_sysfs(device);
250 if (ret) {
251 printk(KERN_WARNING "Couldn't register device %s with driver model\n",
252 device->name);
253 goto out;
254 }
255
256 list_add_tail(&device->core_list, &device_list);
257
258 device->reg_state = IB_DEV_REGISTERED;
259
260 {
261 struct ib_client *client;
262
263 list_for_each_entry(client, &client_list, list)
264 if (client->add && !add_client_context(device, client))
265 client->add(device);
266 }
267
268 out:
269 up(&device_sem);
270 return ret;
271}
272EXPORT_SYMBOL(ib_register_device);
273
274/**
275 * ib_unregister_device - Unregister an IB device
276 * @device:Device to unregister
277 *
278 * Unregister an IB device. All clients will receive a remove callback.
279 */
280void ib_unregister_device(struct ib_device *device)
281{
282 struct ib_client *client;
283 struct ib_client_data *context, *tmp;
284 unsigned long flags;
285
286 down(&device_sem);
287
288 list_for_each_entry_reverse(client, &client_list, list)
289 if (client->remove)
290 client->remove(device);
291
292 list_del(&device->core_list);
293
294 up(&device_sem);
295
296 spin_lock_irqsave(&device->client_data_lock, flags);
297 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
298 kfree(context);
299 spin_unlock_irqrestore(&device->client_data_lock, flags);
300
301 device->reg_state = IB_DEV_UNREGISTERED;
302}
303EXPORT_SYMBOL(ib_unregister_device);
304
305/**
306 * ib_register_client - Register an IB client
307 * @client:Client to register
308 *
309 * Upper level users of the IB drivers can use ib_register_client() to
310 * register callbacks for IB device addition and removal. When an IB
311 * device is added, each registered client's add method will be called
312 * (in the order the clients were registered), and when a device is
313 * removed, each client's remove method will be called (in the reverse
314 * order that clients were registered). In addition, when
315 * ib_register_client() is called, the client will receive an add
316 * callback for all devices already registered.
317 */
318int ib_register_client(struct ib_client *client)
319{
320 struct ib_device *device;
321
322 down(&device_sem);
323
324 list_add_tail(&client->list, &client_list);
325 list_for_each_entry(device, &device_list, core_list)
326 if (client->add && !add_client_context(device, client))
327 client->add(device);
328
329 up(&device_sem);
330
331 return 0;
332}
333EXPORT_SYMBOL(ib_register_client);
334
335/**
336 * ib_unregister_client - Unregister an IB client
337 * @client:Client to unregister
338 *
339 * Upper level users use ib_unregister_client() to remove their client
340 * registration. When ib_unregister_client() is called, the client
341 * will receive a remove callback for each IB device still registered.
342 */
343void ib_unregister_client(struct ib_client *client)
344{
345 struct ib_client_data *context, *tmp;
346 struct ib_device *device;
347 unsigned long flags;
348
349 down(&device_sem);
350
351 list_for_each_entry(device, &device_list, core_list) {
352 if (client->remove)
353 client->remove(device);
354
355 spin_lock_irqsave(&device->client_data_lock, flags);
356 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
357 if (context->client == client) {
358 list_del(&context->list);
359 kfree(context);
360 }
361 spin_unlock_irqrestore(&device->client_data_lock, flags);
362 }
363 list_del(&client->list);
364
365 up(&device_sem);
366}
367EXPORT_SYMBOL(ib_unregister_client);
368
369/**
370 * ib_get_client_data - Get IB client context
371 * @device:Device to get context for
372 * @client:Client to get context for
373 *
374 * ib_get_client_data() returns client context set with
375 * ib_set_client_data().
376 */
377void *ib_get_client_data(struct ib_device *device, struct ib_client *client)
378{
379 struct ib_client_data *context;
380 void *ret = NULL;
381 unsigned long flags;
382
383 spin_lock_irqsave(&device->client_data_lock, flags);
384 list_for_each_entry(context, &device->client_data_list, list)
385 if (context->client == client) {
386 ret = context->data;
387 break;
388 }
389 spin_unlock_irqrestore(&device->client_data_lock, flags);
390
391 return ret;
392}
393EXPORT_SYMBOL(ib_get_client_data);
394
395/**
396 * ib_set_client_data - Get IB client context
397 * @device:Device to set context for
398 * @client:Client to set context for
399 * @data:Context to set
400 *
401 * ib_set_client_data() sets client context that can be retrieved with
402 * ib_get_client_data().
403 */
404void ib_set_client_data(struct ib_device *device, struct ib_client *client,
405 void *data)
406{
407 struct ib_client_data *context;
408 unsigned long flags;
409
410 spin_lock_irqsave(&device->client_data_lock, flags);
411 list_for_each_entry(context, &device->client_data_list, list)
412 if (context->client == client) {
413 context->data = data;
414 goto out;
415 }
416
417 printk(KERN_WARNING "No client context found for %s/%s\n",
418 device->name, client->name);
419
420out:
421 spin_unlock_irqrestore(&device->client_data_lock, flags);
422}
423EXPORT_SYMBOL(ib_set_client_data);
424
425/**
426 * ib_register_event_handler - Register an IB event handler
427 * @event_handler:Handler to register
428 *
429 * ib_register_event_handler() registers an event handler that will be
430 * called back when asynchronous IB events occur (as defined in
431 * chapter 11 of the InfiniBand Architecture Specification). This
432 * callback may occur in interrupt context.
433 */
434int ib_register_event_handler (struct ib_event_handler *event_handler)
435{
436 unsigned long flags;
437
438 spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
439 list_add_tail(&event_handler->list,
440 &event_handler->device->event_handler_list);
441 spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
442
443 return 0;
444}
445EXPORT_SYMBOL(ib_register_event_handler);
446
447/**
448 * ib_unregister_event_handler - Unregister an event handler
449 * @event_handler:Handler to unregister
450 *
451 * Unregister an event handler registered with
452 * ib_register_event_handler().
453 */
454int ib_unregister_event_handler(struct ib_event_handler *event_handler)
455{
456 unsigned long flags;
457
458 spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
459 list_del(&event_handler->list);
460 spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
461
462 return 0;
463}
464EXPORT_SYMBOL(ib_unregister_event_handler);
465
466/**
467 * ib_dispatch_event - Dispatch an asynchronous event
468 * @event:Event to dispatch
469 *
470 * Low-level drivers must call ib_dispatch_event() to dispatch the
471 * event to all registered event handlers when an asynchronous event
472 * occurs.
473 */
474void ib_dispatch_event(struct ib_event *event)
475{
476 unsigned long flags;
477 struct ib_event_handler *handler;
478
479 spin_lock_irqsave(&event->device->event_handler_lock, flags);
480
481 list_for_each_entry(handler, &event->device->event_handler_list, list)
482 handler->handler(handler, event);
483
484 spin_unlock_irqrestore(&event->device->event_handler_lock, flags);
485}
486EXPORT_SYMBOL(ib_dispatch_event);
487
488/**
489 * ib_query_device - Query IB device attributes
490 * @device:Device to query
491 * @device_attr:Device attributes
492 *
493 * ib_query_device() returns the attributes of a device through the
494 * @device_attr pointer.
495 */
496int ib_query_device(struct ib_device *device,
497 struct ib_device_attr *device_attr)
498{
499 return device->query_device(device, device_attr);
500}
501EXPORT_SYMBOL(ib_query_device);
502
503/**
504 * ib_query_port - Query IB port attributes
505 * @device:Device to query
506 * @port_num:Port number to query
507 * @port_attr:Port attributes
508 *
509 * ib_query_port() returns the attributes of a port through the
510 * @port_attr pointer.
511 */
512int ib_query_port(struct ib_device *device,
513 u8 port_num,
514 struct ib_port_attr *port_attr)
515{
516 return device->query_port(device, port_num, port_attr);
517}
518EXPORT_SYMBOL(ib_query_port);
519
520/**
521 * ib_query_gid - Get GID table entry
522 * @device:Device to query
523 * @port_num:Port number to query
524 * @index:GID table index to query
525 * @gid:Returned GID
526 *
527 * ib_query_gid() fetches the specified GID table entry.
528 */
529int ib_query_gid(struct ib_device *device,
530 u8 port_num, int index, union ib_gid *gid)
531{
532 return device->query_gid(device, port_num, index, gid);
533}
534EXPORT_SYMBOL(ib_query_gid);
535
536/**
537 * ib_query_pkey - Get P_Key table entry
538 * @device:Device to query
539 * @port_num:Port number to query
540 * @index:P_Key table index to query
541 * @pkey:Returned P_Key
542 *
543 * ib_query_pkey() fetches the specified P_Key table entry.
544 */
545int ib_query_pkey(struct ib_device *device,
546 u8 port_num, u16 index, u16 *pkey)
547{
548 return device->query_pkey(device, port_num, index, pkey);
549}
550EXPORT_SYMBOL(ib_query_pkey);
551
552/**
553 * ib_modify_device - Change IB device attributes
554 * @device:Device to modify
555 * @device_modify_mask:Mask of attributes to change
556 * @device_modify:New attribute values
557 *
558 * ib_modify_device() changes a device's attributes as specified by
559 * the @device_modify_mask and @device_modify structure.
560 */
561int ib_modify_device(struct ib_device *device,
562 int device_modify_mask,
563 struct ib_device_modify *device_modify)
564{
565 return device->modify_device(device, device_modify_mask,
566 device_modify);
567}
568EXPORT_SYMBOL(ib_modify_device);
569
570/**
571 * ib_modify_port - Modifies the attributes for the specified port.
572 * @device: The device to modify.
573 * @port_num: The number of the port to modify.
574 * @port_modify_mask: Mask used to specify which attributes of the port
575 * to change.
576 * @port_modify: New attribute values for the port.
577 *
578 * ib_modify_port() changes a port's attributes as specified by the
579 * @port_modify_mask and @port_modify structure.
580 */
581int ib_modify_port(struct ib_device *device,
582 u8 port_num, int port_modify_mask,
583 struct ib_port_modify *port_modify)
584{
585 return device->modify_port(device, port_num, port_modify_mask,
586 port_modify);
587}
588EXPORT_SYMBOL(ib_modify_port);
589
590static int __init ib_core_init(void)
591{
592 int ret;
593
594 ret = ib_sysfs_setup();
595 if (ret)
596 printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
597
598 ret = ib_cache_setup();
599 if (ret) {
600 printk(KERN_WARNING "Couldn't set up InfiniBand P_Key/GID cache\n");
601 ib_sysfs_cleanup();
602 }
603
604 return ret;
605}
606
607static void __exit ib_core_cleanup(void)
608{
609 ib_cache_cleanup();
610 ib_sysfs_cleanup();
611}
612
613module_init(ib_core_init);
614module_exit(ib_core_cleanup);
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
new file mode 100644
index 000000000000..2e9469f18926
--- /dev/null
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -0,0 +1,507 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: fmr_pool.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include <linux/errno.h>
36#include <linux/spinlock.h>
37#include <linux/slab.h>
38#include <linux/jhash.h>
39#include <linux/kthread.h>
40
41#include <ib_fmr_pool.h>
42
43#include "core_priv.h"
44
45enum {
46 IB_FMR_MAX_REMAPS = 32,
47
48 IB_FMR_HASH_BITS = 8,
49 IB_FMR_HASH_SIZE = 1 << IB_FMR_HASH_BITS,
50 IB_FMR_HASH_MASK = IB_FMR_HASH_SIZE - 1
51};
52
53/*
54 * If an FMR is not in use, then the list member will point to either
55 * its pool's free_list (if the FMR can be mapped again; that is,
56 * remap_count < IB_FMR_MAX_REMAPS) or its pool's dirty_list (if the
57 * FMR needs to be unmapped before being remapped). In either of
58 * these cases it is a bug if the ref_count is not 0. In other words,
59 * if ref_count is > 0, then the list member must not be linked into
60 * either free_list or dirty_list.
61 *
62 * The cache_node member is used to link the FMR into a cache bucket
63 * (if caching is enabled). This is independent of the reference
64 * count of the FMR. When a valid FMR is released, its ref_count is
65 * decremented, and if ref_count reaches 0, the FMR is placed in
66 * either free_list or dirty_list as appropriate. However, it is not
67 * removed from the cache and may be "revived" if a call to
68 * ib_fmr_register_physical() occurs before the FMR is remapped. In
69 * this case we just increment the ref_count and remove the FMR from
70 * free_list/dirty_list.
71 *
72 * Before we remap an FMR from free_list, we remove it from the cache
73 * (to prevent another user from obtaining a stale FMR). When an FMR
74 * is released, we add it to the tail of the free list, so that our
75 * cache eviction policy is "least recently used."
76 *
77 * All manipulation of ref_count, list and cache_node is protected by
78 * pool_lock to maintain consistency.
79 */
80
81struct ib_fmr_pool {
82 spinlock_t pool_lock;
83
84 int pool_size;
85 int max_pages;
86 int dirty_watermark;
87 int dirty_len;
88 struct list_head free_list;
89 struct list_head dirty_list;
90 struct hlist_head *cache_bucket;
91
92 void (*flush_function)(struct ib_fmr_pool *pool,
93 void * arg);
94 void *flush_arg;
95
96 struct task_struct *thread;
97
98 atomic_t req_ser;
99 atomic_t flush_ser;
100
101 wait_queue_head_t force_wait;
102};
103
104static inline u32 ib_fmr_hash(u64 first_page)
105{
106 return jhash_2words((u32) first_page,
107 (u32) (first_page >> 32),
108 0);
109}
110
111/* Caller must hold pool_lock */
112static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool,
113 u64 *page_list,
114 int page_list_len,
115 u64 io_virtual_address)
116{
117 struct hlist_head *bucket;
118 struct ib_pool_fmr *fmr;
119 struct hlist_node *pos;
120
121 if (!pool->cache_bucket)
122 return NULL;
123
124 bucket = pool->cache_bucket + ib_fmr_hash(*page_list);
125
126 hlist_for_each_entry(fmr, pos, bucket, cache_node)
127 if (io_virtual_address == fmr->io_virtual_address &&
128 page_list_len == fmr->page_list_len &&
129 !memcmp(page_list, fmr->page_list,
130 page_list_len * sizeof *page_list))
131 return fmr;
132
133 return NULL;
134}
135
136static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
137{
138 int ret;
139 struct ib_pool_fmr *fmr;
140 LIST_HEAD(unmap_list);
141 LIST_HEAD(fmr_list);
142
143 spin_lock_irq(&pool->pool_lock);
144
145 list_for_each_entry(fmr, &pool->dirty_list, list) {
146 hlist_del_init(&fmr->cache_node);
147 fmr->remap_count = 0;
148 list_add_tail(&fmr->fmr->list, &fmr_list);
149
150#ifdef DEBUG
151 if (fmr->ref_count !=0) {
152 printk(KERN_WARNING "Unmapping FMR 0x%08x with ref count %d",
153 fmr, fmr->ref_count);
154 }
155#endif
156 }
157
158 list_splice(&pool->dirty_list, &unmap_list);
159 INIT_LIST_HEAD(&pool->dirty_list);
160 pool->dirty_len = 0;
161
162 spin_unlock_irq(&pool->pool_lock);
163
164 if (list_empty(&unmap_list)) {
165 return;
166 }
167
168 ret = ib_unmap_fmr(&fmr_list);
169 if (ret)
170 printk(KERN_WARNING "ib_unmap_fmr returned %d", ret);
171
172 spin_lock_irq(&pool->pool_lock);
173 list_splice(&unmap_list, &pool->free_list);
174 spin_unlock_irq(&pool->pool_lock);
175}
176
177static int ib_fmr_cleanup_thread(void *pool_ptr)
178{
179 struct ib_fmr_pool *pool = pool_ptr;
180
181 do {
182 if (pool->dirty_len >= pool->dirty_watermark ||
183 atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) < 0) {
184 ib_fmr_batch_release(pool);
185
186 atomic_inc(&pool->flush_ser);
187 wake_up_interruptible(&pool->force_wait);
188
189 if (pool->flush_function)
190 pool->flush_function(pool, pool->flush_arg);
191 }
192
193 set_current_state(TASK_INTERRUPTIBLE);
194 if (pool->dirty_len < pool->dirty_watermark &&
195 atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) >= 0 &&
196 !kthread_should_stop())
197 schedule();
198 __set_current_state(TASK_RUNNING);
199 } while (!kthread_should_stop());
200
201 return 0;
202}
203
204/**
205 * ib_create_fmr_pool - Create an FMR pool
206 * @pd:Protection domain for FMRs
207 * @params:FMR pool parameters
208 *
209 * Create a pool of FMRs. Return value is pointer to new pool or
210 * error code if creation failed.
211 */
212struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
213 struct ib_fmr_pool_param *params)
214{
215 struct ib_device *device;
216 struct ib_fmr_pool *pool;
217 int i;
218 int ret;
219
220 if (!params)
221 return ERR_PTR(-EINVAL);
222
223 device = pd->device;
224 if (!device->alloc_fmr || !device->dealloc_fmr ||
225 !device->map_phys_fmr || !device->unmap_fmr) {
226 printk(KERN_WARNING "Device %s does not support fast memory regions",
227 device->name);
228 return ERR_PTR(-ENOSYS);
229 }
230
231 pool = kmalloc(sizeof *pool, GFP_KERNEL);
232 if (!pool) {
233 printk(KERN_WARNING "couldn't allocate pool struct");
234 return ERR_PTR(-ENOMEM);
235 }
236
237 pool->cache_bucket = NULL;
238
239 pool->flush_function = params->flush_function;
240 pool->flush_arg = params->flush_arg;
241
242 INIT_LIST_HEAD(&pool->free_list);
243 INIT_LIST_HEAD(&pool->dirty_list);
244
245 if (params->cache) {
246 pool->cache_bucket =
247 kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket,
248 GFP_KERNEL);
249 if (!pool->cache_bucket) {
250 printk(KERN_WARNING "Failed to allocate cache in pool");
251 ret = -ENOMEM;
252 goto out_free_pool;
253 }
254
255 for (i = 0; i < IB_FMR_HASH_SIZE; ++i)
256 INIT_HLIST_HEAD(pool->cache_bucket + i);
257 }
258
259 pool->pool_size = 0;
260 pool->max_pages = params->max_pages_per_fmr;
261 pool->dirty_watermark = params->dirty_watermark;
262 pool->dirty_len = 0;
263 spin_lock_init(&pool->pool_lock);
264 atomic_set(&pool->req_ser, 0);
265 atomic_set(&pool->flush_ser, 0);
266 init_waitqueue_head(&pool->force_wait);
267
268 pool->thread = kthread_create(ib_fmr_cleanup_thread,
269 pool,
270 "ib_fmr(%s)",
271 device->name);
272 if (IS_ERR(pool->thread)) {
273 printk(KERN_WARNING "couldn't start cleanup thread");
274 ret = PTR_ERR(pool->thread);
275 goto out_free_pool;
276 }
277
278 {
279 struct ib_pool_fmr *fmr;
280 struct ib_fmr_attr attr = {
281 .max_pages = params->max_pages_per_fmr,
282 .max_maps = IB_FMR_MAX_REMAPS,
283 .page_size = PAGE_SHIFT
284 };
285
286 for (i = 0; i < params->pool_size; ++i) {
287 fmr = kmalloc(sizeof *fmr + params->max_pages_per_fmr * sizeof (u64),
288 GFP_KERNEL);
289 if (!fmr) {
290 printk(KERN_WARNING "failed to allocate fmr struct "
291 "for FMR %d", i);
292 goto out_fail;
293 }
294
295 fmr->pool = pool;
296 fmr->remap_count = 0;
297 fmr->ref_count = 0;
298 INIT_HLIST_NODE(&fmr->cache_node);
299
300 fmr->fmr = ib_alloc_fmr(pd, params->access, &attr);
301 if (IS_ERR(fmr->fmr)) {
302 printk(KERN_WARNING "fmr_create failed for FMR %d", i);
303 kfree(fmr);
304 goto out_fail;
305 }
306
307 list_add_tail(&fmr->list, &pool->free_list);
308 ++pool->pool_size;
309 }
310 }
311
312 return pool;
313
314 out_free_pool:
315 kfree(pool->cache_bucket);
316 kfree(pool);
317
318 return ERR_PTR(ret);
319
320 out_fail:
321 ib_destroy_fmr_pool(pool);
322
323 return ERR_PTR(-ENOMEM);
324}
325EXPORT_SYMBOL(ib_create_fmr_pool);
326
327/**
328 * ib_destroy_fmr_pool - Free FMR pool
329 * @pool:FMR pool to free
330 *
331 * Destroy an FMR pool and free all associated resources.
332 */
333int ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
334{
335 struct ib_pool_fmr *fmr;
336 struct ib_pool_fmr *tmp;
337 int i;
338
339 kthread_stop(pool->thread);
340 ib_fmr_batch_release(pool);
341
342 i = 0;
343 list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
344 ib_dealloc_fmr(fmr->fmr);
345 list_del(&fmr->list);
346 kfree(fmr);
347 ++i;
348 }
349
350 if (i < pool->pool_size)
351 printk(KERN_WARNING "pool still has %d regions registered",
352 pool->pool_size - i);
353
354 kfree(pool->cache_bucket);
355 kfree(pool);
356
357 return 0;
358}
359EXPORT_SYMBOL(ib_destroy_fmr_pool);
360
361/**
362 * ib_flush_fmr_pool - Invalidate all unmapped FMRs
363 * @pool:FMR pool to flush
364 *
365 * Ensure that all unmapped FMRs are fully invalidated.
366 */
367int ib_flush_fmr_pool(struct ib_fmr_pool *pool)
368{
369 int serial;
370
371 atomic_inc(&pool->req_ser);
372 /*
373 * It's OK if someone else bumps req_ser again here -- we'll
374 * just wait a little longer.
375 */
376 serial = atomic_read(&pool->req_ser);
377
378 wake_up_process(pool->thread);
379
380 if (wait_event_interruptible(pool->force_wait,
381 atomic_read(&pool->flush_ser) -
382 atomic_read(&pool->req_ser) >= 0))
383 return -EINTR;
384
385 return 0;
386}
387EXPORT_SYMBOL(ib_flush_fmr_pool);
388
389/**
390 * ib_fmr_pool_map_phys -
391 * @pool:FMR pool to allocate FMR from
392 * @page_list:List of pages to map
393 * @list_len:Number of pages in @page_list
394 * @io_virtual_address:I/O virtual address for new FMR
395 *
396 * Map an FMR from an FMR pool.
397 */
398struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
399 u64 *page_list,
400 int list_len,
401 u64 *io_virtual_address)
402{
403 struct ib_fmr_pool *pool = pool_handle;
404 struct ib_pool_fmr *fmr;
405 unsigned long flags;
406 int result;
407
408 if (list_len < 1 || list_len > pool->max_pages)
409 return ERR_PTR(-EINVAL);
410
411 spin_lock_irqsave(&pool->pool_lock, flags);
412 fmr = ib_fmr_cache_lookup(pool,
413 page_list,
414 list_len,
415 *io_virtual_address);
416 if (fmr) {
417 /* found in cache */
418 ++fmr->ref_count;
419 if (fmr->ref_count == 1) {
420 list_del(&fmr->list);
421 }
422
423 spin_unlock_irqrestore(&pool->pool_lock, flags);
424
425 return fmr;
426 }
427
428 if (list_empty(&pool->free_list)) {
429 spin_unlock_irqrestore(&pool->pool_lock, flags);
430 return ERR_PTR(-EAGAIN);
431 }
432
433 fmr = list_entry(pool->free_list.next, struct ib_pool_fmr, list);
434 list_del(&fmr->list);
435 hlist_del_init(&fmr->cache_node);
436 spin_unlock_irqrestore(&pool->pool_lock, flags);
437
438 result = ib_map_phys_fmr(fmr->fmr, page_list, list_len,
439 *io_virtual_address);
440
441 if (result) {
442 spin_lock_irqsave(&pool->pool_lock, flags);
443 list_add(&fmr->list, &pool->free_list);
444 spin_unlock_irqrestore(&pool->pool_lock, flags);
445
446 printk(KERN_WARNING "fmr_map returns %d",
447 result);
448
449 return ERR_PTR(result);
450 }
451
452 ++fmr->remap_count;
453 fmr->ref_count = 1;
454
455 if (pool->cache_bucket) {
456 fmr->io_virtual_address = *io_virtual_address;
457 fmr->page_list_len = list_len;
458 memcpy(fmr->page_list, page_list, list_len * sizeof(*page_list));
459
460 spin_lock_irqsave(&pool->pool_lock, flags);
461 hlist_add_head(&fmr->cache_node,
462 pool->cache_bucket + ib_fmr_hash(fmr->page_list[0]));
463 spin_unlock_irqrestore(&pool->pool_lock, flags);
464 }
465
466 return fmr;
467}
468EXPORT_SYMBOL(ib_fmr_pool_map_phys);
469
470/**
471 * ib_fmr_pool_unmap - Unmap FMR
472 * @fmr:FMR to unmap
473 *
474 * Unmap an FMR. The FMR mapping may remain valid until the FMR is
475 * reused (or until ib_flush_fmr_pool() is called).
476 */
477int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr)
478{
479 struct ib_fmr_pool *pool;
480 unsigned long flags;
481
482 pool = fmr->pool;
483
484 spin_lock_irqsave(&pool->pool_lock, flags);
485
486 --fmr->ref_count;
487 if (!fmr->ref_count) {
488 if (fmr->remap_count < IB_FMR_MAX_REMAPS) {
489 list_add_tail(&fmr->list, &pool->free_list);
490 } else {
491 list_add_tail(&fmr->list, &pool->dirty_list);
492 ++pool->dirty_len;
493 wake_up_process(pool->thread);
494 }
495 }
496
497#ifdef DEBUG
498 if (fmr->ref_count < 0)
499 printk(KERN_WARNING "FMR %p has ref count %d < 0",
500 fmr, fmr->ref_count);
501#endif
502
503 spin_unlock_irqrestore(&pool->pool_lock, flags);
504
505 return 0;
506}
507EXPORT_SYMBOL(ib_fmr_pool_unmap);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
new file mode 100644
index 000000000000..4ec7fff29b5d
--- /dev/null
+++ b/drivers/infiniband/core/mad.c
@@ -0,0 +1,2714 @@
1/*
2 * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: mad.c 1389 2004-12-27 22:56:47Z roland $
33 */
34
35#include <linux/dma-mapping.h>
36#include <linux/interrupt.h>
37
38#include <ib_mad.h>
39
40#include "mad_priv.h"
41#include "smi.h"
42#include "agent.h"
43
44MODULE_LICENSE("Dual BSD/GPL");
45MODULE_DESCRIPTION("kernel IB MAD API");
46MODULE_AUTHOR("Hal Rosenstock");
47MODULE_AUTHOR("Sean Hefty");
48
49
50kmem_cache_t *ib_mad_cache;
51static struct list_head ib_mad_port_list;
52static u32 ib_mad_client_id = 0;
53
54/* Port list lock */
55static spinlock_t ib_mad_port_list_lock;
56
57
58/* Forward declarations */
59static int method_in_use(struct ib_mad_mgmt_method_table **method,
60 struct ib_mad_reg_req *mad_reg_req);
61static void remove_mad_reg_req(struct ib_mad_agent_private *priv);
62static struct ib_mad_agent_private *find_mad_agent(
63 struct ib_mad_port_private *port_priv,
64 struct ib_mad *mad, int solicited);
65static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
66 struct ib_mad_private *mad);
67static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
68static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
69 struct ib_mad_send_wc *mad_send_wc);
70static void timeout_sends(void *data);
71static void cancel_sends(void *data);
72static void local_completions(void *data);
73static int solicited_mad(struct ib_mad *mad);
74static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
75 struct ib_mad_agent_private *agent_priv,
76 u8 mgmt_class);
77static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
78 struct ib_mad_agent_private *agent_priv);
79
80/*
81 * Returns a ib_mad_port_private structure or NULL for a device/port
82 * Assumes ib_mad_port_list_lock is being held
83 */
84static inline struct ib_mad_port_private *
85__ib_get_mad_port(struct ib_device *device, int port_num)
86{
87 struct ib_mad_port_private *entry;
88
89 list_for_each_entry(entry, &ib_mad_port_list, port_list) {
90 if (entry->device == device && entry->port_num == port_num)
91 return entry;
92 }
93 return NULL;
94}
95
96/*
97 * Wrapper function to return a ib_mad_port_private structure or NULL
98 * for a device/port
99 */
100static inline struct ib_mad_port_private *
101ib_get_mad_port(struct ib_device *device, int port_num)
102{
103 struct ib_mad_port_private *entry;
104 unsigned long flags;
105
106 spin_lock_irqsave(&ib_mad_port_list_lock, flags);
107 entry = __ib_get_mad_port(device, port_num);
108 spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
109
110 return entry;
111}
112
113static inline u8 convert_mgmt_class(u8 mgmt_class)
114{
115 /* Alias IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE to 0 */
116 return mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ?
117 0 : mgmt_class;
118}
119
120static int get_spl_qp_index(enum ib_qp_type qp_type)
121{
122 switch (qp_type)
123 {
124 case IB_QPT_SMI:
125 return 0;
126 case IB_QPT_GSI:
127 return 1;
128 default:
129 return -1;
130 }
131}
132
133static int vendor_class_index(u8 mgmt_class)
134{
135 return mgmt_class - IB_MGMT_CLASS_VENDOR_RANGE2_START;
136}
137
138static int is_vendor_class(u8 mgmt_class)
139{
140 if ((mgmt_class < IB_MGMT_CLASS_VENDOR_RANGE2_START) ||
141 (mgmt_class > IB_MGMT_CLASS_VENDOR_RANGE2_END))
142 return 0;
143 return 1;
144}
145
146static int is_vendor_oui(char *oui)
147{
148 if (oui[0] || oui[1] || oui[2])
149 return 1;
150 return 0;
151}
152
153static int is_vendor_method_in_use(
154 struct ib_mad_mgmt_vendor_class *vendor_class,
155 struct ib_mad_reg_req *mad_reg_req)
156{
157 struct ib_mad_mgmt_method_table *method;
158 int i;
159
160 for (i = 0; i < MAX_MGMT_OUI; i++) {
161 if (!memcmp(vendor_class->oui[i], mad_reg_req->oui, 3)) {
162 method = vendor_class->method_table[i];
163 if (method) {
164 if (method_in_use(&method, mad_reg_req))
165 return 1;
166 else
167 break;
168 }
169 }
170 }
171 return 0;
172}
173
174/*
175 * ib_register_mad_agent - Register to send/receive MADs
176 */
177struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
178 u8 port_num,
179 enum ib_qp_type qp_type,
180 struct ib_mad_reg_req *mad_reg_req,
181 u8 rmpp_version,
182 ib_mad_send_handler send_handler,
183 ib_mad_recv_handler recv_handler,
184 void *context)
185{
186 struct ib_mad_port_private *port_priv;
187 struct ib_mad_agent *ret = ERR_PTR(-EINVAL);
188 struct ib_mad_agent_private *mad_agent_priv;
189 struct ib_mad_reg_req *reg_req = NULL;
190 struct ib_mad_mgmt_class_table *class;
191 struct ib_mad_mgmt_vendor_class_table *vendor;
192 struct ib_mad_mgmt_vendor_class *vendor_class;
193 struct ib_mad_mgmt_method_table *method;
194 int ret2, qpn;
195 unsigned long flags;
196 u8 mgmt_class, vclass;
197
198 /* Validate parameters */
199 qpn = get_spl_qp_index(qp_type);
200 if (qpn == -1)
201 goto error1;
202
203 if (rmpp_version)
204 goto error1; /* XXX: until RMPP implemented */
205
206 /* Validate MAD registration request if supplied */
207 if (mad_reg_req) {
208 if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION)
209 goto error1;
210 if (!recv_handler)
211 goto error1;
212 if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) {
213 /*
214 * IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE is the only
215 * one in this range currently allowed
216 */
217 if (mad_reg_req->mgmt_class !=
218 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
219 goto error1;
220 } else if (mad_reg_req->mgmt_class == 0) {
221 /*
222 * Class 0 is reserved in IBA and is used for
223 * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
224 */
225 goto error1;
226 } else if (is_vendor_class(mad_reg_req->mgmt_class)) {
227 /*
228 * If class is in "new" vendor range,
229 * ensure supplied OUI is not zero
230 */
231 if (!is_vendor_oui(mad_reg_req->oui))
232 goto error1;
233 }
234 /* Make sure class supplied is consistent with QP type */
235 if (qp_type == IB_QPT_SMI) {
236 if ((mad_reg_req->mgmt_class !=
237 IB_MGMT_CLASS_SUBN_LID_ROUTED) &&
238 (mad_reg_req->mgmt_class !=
239 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE))
240 goto error1;
241 } else {
242 if ((mad_reg_req->mgmt_class ==
243 IB_MGMT_CLASS_SUBN_LID_ROUTED) ||
244 (mad_reg_req->mgmt_class ==
245 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE))
246 goto error1;
247 }
248 } else {
249 /* No registration request supplied */
250 if (!send_handler)
251 goto error1;
252 }
253
254 /* Validate device and port */
255 port_priv = ib_get_mad_port(device, port_num);
256 if (!port_priv) {
257 ret = ERR_PTR(-ENODEV);
258 goto error1;
259 }
260
261 /* Allocate structures */
262 mad_agent_priv = kmalloc(sizeof *mad_agent_priv, GFP_KERNEL);
263 if (!mad_agent_priv) {
264 ret = ERR_PTR(-ENOMEM);
265 goto error1;
266 }
267
268 if (mad_reg_req) {
269 reg_req = kmalloc(sizeof *reg_req, GFP_KERNEL);
270 if (!reg_req) {
271 ret = ERR_PTR(-ENOMEM);
272 goto error2;
273 }
274 /* Make a copy of the MAD registration request */
275 memcpy(reg_req, mad_reg_req, sizeof *reg_req);
276 }
277
278 /* Now, fill in the various structures */
279 memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
280 mad_agent_priv->qp_info = &port_priv->qp_info[qpn];
281 mad_agent_priv->reg_req = reg_req;
282 mad_agent_priv->rmpp_version = rmpp_version;
283 mad_agent_priv->agent.device = device;
284 mad_agent_priv->agent.recv_handler = recv_handler;
285 mad_agent_priv->agent.send_handler = send_handler;
286 mad_agent_priv->agent.context = context;
287 mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
288 mad_agent_priv->agent.port_num = port_num;
289
290 spin_lock_irqsave(&port_priv->reg_lock, flags);
291 mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
292
293 /*
294 * Make sure MAD registration (if supplied)
295 * is non overlapping with any existing ones
296 */
297 if (mad_reg_req) {
298 mgmt_class = convert_mgmt_class(mad_reg_req->mgmt_class);
299 if (!is_vendor_class(mgmt_class)) {
300 class = port_priv->version[mad_reg_req->
301 mgmt_class_version].class;
302 if (class) {
303 method = class->method_table[mgmt_class];
304 if (method) {
305 if (method_in_use(&method,
306 mad_reg_req))
307 goto error3;
308 }
309 }
310 ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
311 mgmt_class);
312 } else {
313 /* "New" vendor class range */
314 vendor = port_priv->version[mad_reg_req->
315 mgmt_class_version].vendor;
316 if (vendor) {
317 vclass = vendor_class_index(mgmt_class);
318 vendor_class = vendor->vendor_class[vclass];
319 if (vendor_class) {
320 if (is_vendor_method_in_use(
321 vendor_class,
322 mad_reg_req))
323 goto error3;
324 }
325 }
326 ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
327 }
328 if (ret2) {
329 ret = ERR_PTR(ret2);
330 goto error3;
331 }
332 }
333
334 /* Add mad agent into port's agent list */
335 list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
336 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
337
338 spin_lock_init(&mad_agent_priv->lock);
339 INIT_LIST_HEAD(&mad_agent_priv->send_list);
340 INIT_LIST_HEAD(&mad_agent_priv->wait_list);
341 INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv);
342 INIT_LIST_HEAD(&mad_agent_priv->local_list);
343 INIT_WORK(&mad_agent_priv->local_work, local_completions,
344 mad_agent_priv);
345 INIT_LIST_HEAD(&mad_agent_priv->canceled_list);
346 INIT_WORK(&mad_agent_priv->canceled_work, cancel_sends, mad_agent_priv);
347 atomic_set(&mad_agent_priv->refcount, 1);
348 init_waitqueue_head(&mad_agent_priv->wait);
349
350 return &mad_agent_priv->agent;
351
352error3:
353 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
354 kfree(reg_req);
355error2:
356 kfree(mad_agent_priv);
357error1:
358 return ret;
359}
360EXPORT_SYMBOL(ib_register_mad_agent);
361
362static inline int is_snooping_sends(int mad_snoop_flags)
363{
364 return (mad_snoop_flags &
365 (/*IB_MAD_SNOOP_POSTED_SENDS |
366 IB_MAD_SNOOP_RMPP_SENDS |*/
367 IB_MAD_SNOOP_SEND_COMPLETIONS /*|
368 IB_MAD_SNOOP_RMPP_SEND_COMPLETIONS*/));
369}
370
371static inline int is_snooping_recvs(int mad_snoop_flags)
372{
373 return (mad_snoop_flags &
374 (IB_MAD_SNOOP_RECVS /*|
375 IB_MAD_SNOOP_RMPP_RECVS*/));
376}
377
378static int register_snoop_agent(struct ib_mad_qp_info *qp_info,
379 struct ib_mad_snoop_private *mad_snoop_priv)
380{
381 struct ib_mad_snoop_private **new_snoop_table;
382 unsigned long flags;
383 int i;
384
385 spin_lock_irqsave(&qp_info->snoop_lock, flags);
386 /* Check for empty slot in array. */
387 for (i = 0; i < qp_info->snoop_table_size; i++)
388 if (!qp_info->snoop_table[i])
389 break;
390
391 if (i == qp_info->snoop_table_size) {
392 /* Grow table. */
393 new_snoop_table = kmalloc(sizeof mad_snoop_priv *
394 qp_info->snoop_table_size + 1,
395 GFP_ATOMIC);
396 if (!new_snoop_table) {
397 i = -ENOMEM;
398 goto out;
399 }
400 if (qp_info->snoop_table) {
401 memcpy(new_snoop_table, qp_info->snoop_table,
402 sizeof mad_snoop_priv *
403 qp_info->snoop_table_size);
404 kfree(qp_info->snoop_table);
405 }
406 qp_info->snoop_table = new_snoop_table;
407 qp_info->snoop_table_size++;
408 }
409 qp_info->snoop_table[i] = mad_snoop_priv;
410 atomic_inc(&qp_info->snoop_count);
411out:
412 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
413 return i;
414}
415
416struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
417 u8 port_num,
418 enum ib_qp_type qp_type,
419 int mad_snoop_flags,
420 ib_mad_snoop_handler snoop_handler,
421 ib_mad_recv_handler recv_handler,
422 void *context)
423{
424 struct ib_mad_port_private *port_priv;
425 struct ib_mad_agent *ret;
426 struct ib_mad_snoop_private *mad_snoop_priv;
427 int qpn;
428
429 /* Validate parameters */
430 if ((is_snooping_sends(mad_snoop_flags) && !snoop_handler) ||
431 (is_snooping_recvs(mad_snoop_flags) && !recv_handler)) {
432 ret = ERR_PTR(-EINVAL);
433 goto error1;
434 }
435 qpn = get_spl_qp_index(qp_type);
436 if (qpn == -1) {
437 ret = ERR_PTR(-EINVAL);
438 goto error1;
439 }
440 port_priv = ib_get_mad_port(device, port_num);
441 if (!port_priv) {
442 ret = ERR_PTR(-ENODEV);
443 goto error1;
444 }
445 /* Allocate structures */
446 mad_snoop_priv = kmalloc(sizeof *mad_snoop_priv, GFP_KERNEL);
447 if (!mad_snoop_priv) {
448 ret = ERR_PTR(-ENOMEM);
449 goto error1;
450 }
451
452 /* Now, fill in the various structures */
453 memset(mad_snoop_priv, 0, sizeof *mad_snoop_priv);
454 mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
455 mad_snoop_priv->agent.device = device;
456 mad_snoop_priv->agent.recv_handler = recv_handler;
457 mad_snoop_priv->agent.snoop_handler = snoop_handler;
458 mad_snoop_priv->agent.context = context;
459 mad_snoop_priv->agent.qp = port_priv->qp_info[qpn].qp;
460 mad_snoop_priv->agent.port_num = port_num;
461 mad_snoop_priv->mad_snoop_flags = mad_snoop_flags;
462 init_waitqueue_head(&mad_snoop_priv->wait);
463 mad_snoop_priv->snoop_index = register_snoop_agent(
464 &port_priv->qp_info[qpn],
465 mad_snoop_priv);
466 if (mad_snoop_priv->snoop_index < 0) {
467 ret = ERR_PTR(mad_snoop_priv->snoop_index);
468 goto error2;
469 }
470
471 atomic_set(&mad_snoop_priv->refcount, 1);
472 return &mad_snoop_priv->agent;
473
474error2:
475 kfree(mad_snoop_priv);
476error1:
477 return ret;
478}
479EXPORT_SYMBOL(ib_register_mad_snoop);
480
481static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
482{
483 struct ib_mad_port_private *port_priv;
484 unsigned long flags;
485
486 /* Note that we could still be handling received MADs */
487
488 /*
489 * Canceling all sends results in dropping received response
490 * MADs, preventing us from queuing additional work
491 */
492 cancel_mads(mad_agent_priv);
493
494 port_priv = mad_agent_priv->qp_info->port_priv;
495
496 cancel_delayed_work(&mad_agent_priv->timed_work);
497 flush_workqueue(port_priv->wq);
498
499 spin_lock_irqsave(&port_priv->reg_lock, flags);
500 remove_mad_reg_req(mad_agent_priv);
501 list_del(&mad_agent_priv->agent_list);
502 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
503
504 /* XXX: Cleanup pending RMPP receives for this agent */
505
506 atomic_dec(&mad_agent_priv->refcount);
507 wait_event(mad_agent_priv->wait,
508 !atomic_read(&mad_agent_priv->refcount));
509
510 if (mad_agent_priv->reg_req)
511 kfree(mad_agent_priv->reg_req);
512 kfree(mad_agent_priv);
513}
514
515static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv)
516{
517 struct ib_mad_qp_info *qp_info;
518 unsigned long flags;
519
520 qp_info = mad_snoop_priv->qp_info;
521 spin_lock_irqsave(&qp_info->snoop_lock, flags);
522 qp_info->snoop_table[mad_snoop_priv->snoop_index] = NULL;
523 atomic_dec(&qp_info->snoop_count);
524 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
525
526 atomic_dec(&mad_snoop_priv->refcount);
527 wait_event(mad_snoop_priv->wait,
528 !atomic_read(&mad_snoop_priv->refcount));
529
530 kfree(mad_snoop_priv);
531}
532
533/*
534 * ib_unregister_mad_agent - Unregisters a client from using MAD services
535 */
536int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent)
537{
538 struct ib_mad_agent_private *mad_agent_priv;
539 struct ib_mad_snoop_private *mad_snoop_priv;
540
541 /* If the TID is zero, the agent can only snoop. */
542 if (mad_agent->hi_tid) {
543 mad_agent_priv = container_of(mad_agent,
544 struct ib_mad_agent_private,
545 agent);
546 unregister_mad_agent(mad_agent_priv);
547 } else {
548 mad_snoop_priv = container_of(mad_agent,
549 struct ib_mad_snoop_private,
550 agent);
551 unregister_mad_snoop(mad_snoop_priv);
552 }
553 return 0;
554}
555EXPORT_SYMBOL(ib_unregister_mad_agent);
556
557static void dequeue_mad(struct ib_mad_list_head *mad_list)
558{
559 struct ib_mad_queue *mad_queue;
560 unsigned long flags;
561
562 BUG_ON(!mad_list->mad_queue);
563 mad_queue = mad_list->mad_queue;
564 spin_lock_irqsave(&mad_queue->lock, flags);
565 list_del(&mad_list->list);
566 mad_queue->count--;
567 spin_unlock_irqrestore(&mad_queue->lock, flags);
568}
569
570static void snoop_send(struct ib_mad_qp_info *qp_info,
571 struct ib_send_wr *send_wr,
572 struct ib_mad_send_wc *mad_send_wc,
573 int mad_snoop_flags)
574{
575 struct ib_mad_snoop_private *mad_snoop_priv;
576 unsigned long flags;
577 int i;
578
579 spin_lock_irqsave(&qp_info->snoop_lock, flags);
580 for (i = 0; i < qp_info->snoop_table_size; i++) {
581 mad_snoop_priv = qp_info->snoop_table[i];
582 if (!mad_snoop_priv ||
583 !(mad_snoop_priv->mad_snoop_flags & mad_snoop_flags))
584 continue;
585
586 atomic_inc(&mad_snoop_priv->refcount);
587 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
588 mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent,
589 send_wr, mad_send_wc);
590 if (atomic_dec_and_test(&mad_snoop_priv->refcount))
591 wake_up(&mad_snoop_priv->wait);
592 spin_lock_irqsave(&qp_info->snoop_lock, flags);
593 }
594 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
595}
596
597static void snoop_recv(struct ib_mad_qp_info *qp_info,
598 struct ib_mad_recv_wc *mad_recv_wc,
599 int mad_snoop_flags)
600{
601 struct ib_mad_snoop_private *mad_snoop_priv;
602 unsigned long flags;
603 int i;
604
605 spin_lock_irqsave(&qp_info->snoop_lock, flags);
606 for (i = 0; i < qp_info->snoop_table_size; i++) {
607 mad_snoop_priv = qp_info->snoop_table[i];
608 if (!mad_snoop_priv ||
609 !(mad_snoop_priv->mad_snoop_flags & mad_snoop_flags))
610 continue;
611
612 atomic_inc(&mad_snoop_priv->refcount);
613 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
614 mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent,
615 mad_recv_wc);
616 if (atomic_dec_and_test(&mad_snoop_priv->refcount))
617 wake_up(&mad_snoop_priv->wait);
618 spin_lock_irqsave(&qp_info->snoop_lock, flags);
619 }
620 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
621}
622
623static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
624 struct ib_wc *wc)
625{
626 memset(wc, 0, sizeof *wc);
627 wc->wr_id = wr_id;
628 wc->status = IB_WC_SUCCESS;
629 wc->opcode = IB_WC_RECV;
630 wc->pkey_index = pkey_index;
631 wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh);
632 wc->src_qp = IB_QP0;
633 wc->qp_num = IB_QP0;
634 wc->slid = slid;
635 wc->sl = 0;
636 wc->dlid_path_bits = 0;
637 wc->port_num = port_num;
638}
639
640/*
641 * Return 0 if SMP is to be sent
642 * Return 1 if SMP was consumed locally (whether or not solicited)
643 * Return < 0 if error
644 */
645static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
646 struct ib_smp *smp,
647 struct ib_send_wr *send_wr)
648{
649 int ret, solicited;
650 unsigned long flags;
651 struct ib_mad_local_private *local;
652 struct ib_mad_private *mad_priv;
653 struct ib_mad_port_private *port_priv;
654 struct ib_mad_agent_private *recv_mad_agent = NULL;
655 struct ib_device *device = mad_agent_priv->agent.device;
656 u8 port_num = mad_agent_priv->agent.port_num;
657 struct ib_wc mad_wc;
658
659 if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
660 ret = -EINVAL;
661 printk(KERN_ERR PFX "Invalid directed route\n");
662 goto out;
663 }
664 /* Check to post send on QP or process locally */
665 ret = smi_check_local_dr_smp(smp, device, port_num);
666 if (!ret || !device->process_mad)
667 goto out;
668
669 local = kmalloc(sizeof *local, GFP_ATOMIC);
670 if (!local) {
671 ret = -ENOMEM;
672 printk(KERN_ERR PFX "No memory for ib_mad_local_private\n");
673 goto out;
674 }
675 local->mad_priv = NULL;
676 local->recv_mad_agent = NULL;
677 mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_ATOMIC);
678 if (!mad_priv) {
679 ret = -ENOMEM;
680 printk(KERN_ERR PFX "No memory for local response MAD\n");
681 kfree(local);
682 goto out;
683 }
684
685 build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index,
686 send_wr->wr.ud.port_num, &mad_wc);
687
688 /* No GRH for DR SMP */
689 ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
690 (struct ib_mad *)smp,
691 (struct ib_mad *)&mad_priv->mad);
692 switch (ret)
693 {
694 case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
695 /*
696 * See if response is solicited and
697 * there is a recv handler
698 */
699 if (solicited_mad(&mad_priv->mad.mad) &&
700 mad_agent_priv->agent.recv_handler) {
701 local->mad_priv = mad_priv;
702 local->recv_mad_agent = mad_agent_priv;
703 /*
704 * Reference MAD agent until receive
705 * side of local completion handled
706 */
707 atomic_inc(&mad_agent_priv->refcount);
708 } else
709 kmem_cache_free(ib_mad_cache, mad_priv);
710 break;
711 case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
712 kmem_cache_free(ib_mad_cache, mad_priv);
713 break;
714 case IB_MAD_RESULT_SUCCESS:
715 /* Treat like an incoming receive MAD */
716 solicited = solicited_mad(&mad_priv->mad.mad);
717 port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
718 mad_agent_priv->agent.port_num);
719 if (port_priv) {
720 mad_priv->mad.mad.mad_hdr.tid =
721 ((struct ib_mad *)smp)->mad_hdr.tid;
722 recv_mad_agent = find_mad_agent(port_priv,
723 &mad_priv->mad.mad,
724 solicited);
725 }
726 if (!port_priv || !recv_mad_agent) {
727 kmem_cache_free(ib_mad_cache, mad_priv);
728 kfree(local);
729 ret = 0;
730 goto out;
731 }
732 local->mad_priv = mad_priv;
733 local->recv_mad_agent = recv_mad_agent;
734 break;
735 default:
736 kmem_cache_free(ib_mad_cache, mad_priv);
737 kfree(local);
738 ret = -EINVAL;
739 goto out;
740 }
741
742 local->send_wr = *send_wr;
743 local->send_wr.sg_list = local->sg_list;
744 memcpy(local->sg_list, send_wr->sg_list,
745 sizeof *send_wr->sg_list * send_wr->num_sge);
746 local->send_wr.next = NULL;
747 local->tid = send_wr->wr.ud.mad_hdr->tid;
748 local->wr_id = send_wr->wr_id;
749 /* Reference MAD agent until send side of local completion handled */
750 atomic_inc(&mad_agent_priv->refcount);
751 /* Queue local completion to local list */
752 spin_lock_irqsave(&mad_agent_priv->lock, flags);
753 list_add_tail(&local->completion_list, &mad_agent_priv->local_list);
754 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
755 queue_work(mad_agent_priv->qp_info->port_priv->wq,
756 &mad_agent_priv->local_work);
757 ret = 1;
758out:
759 return ret;
760}
761
762static int ib_send_mad(struct ib_mad_agent_private *mad_agent_priv,
763 struct ib_mad_send_wr_private *mad_send_wr)
764{
765 struct ib_mad_qp_info *qp_info;
766 struct ib_send_wr *bad_send_wr;
767 unsigned long flags;
768 int ret;
769
770 /* Replace user's WR ID with our own to find WR upon completion */
771 qp_info = mad_agent_priv->qp_info;
772 mad_send_wr->wr_id = mad_send_wr->send_wr.wr_id;
773 mad_send_wr->send_wr.wr_id = (unsigned long)&mad_send_wr->mad_list;
774 mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
775
776 spin_lock_irqsave(&qp_info->send_queue.lock, flags);
777 if (qp_info->send_queue.count++ < qp_info->send_queue.max_active) {
778 list_add_tail(&mad_send_wr->mad_list.list,
779 &qp_info->send_queue.list);
780 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
781 ret = ib_post_send(mad_agent_priv->agent.qp,
782 &mad_send_wr->send_wr, &bad_send_wr);
783 if (ret) {
784 printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
785 dequeue_mad(&mad_send_wr->mad_list);
786 }
787 } else {
788 list_add_tail(&mad_send_wr->mad_list.list,
789 &qp_info->overflow_list);
790 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
791 ret = 0;
792 }
793 return ret;
794}
795
796/*
797 * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
798 * with the registered client
799 */
800int ib_post_send_mad(struct ib_mad_agent *mad_agent,
801 struct ib_send_wr *send_wr,
802 struct ib_send_wr **bad_send_wr)
803{
804 int ret = -EINVAL;
805 struct ib_mad_agent_private *mad_agent_priv;
806
807 /* Validate supplied parameters */
808 if (!bad_send_wr)
809 goto error1;
810
811 if (!mad_agent || !send_wr)
812 goto error2;
813
814 if (!mad_agent->send_handler)
815 goto error2;
816
817 mad_agent_priv = container_of(mad_agent,
818 struct ib_mad_agent_private,
819 agent);
820
821 /* Walk list of send WRs and post each on send list */
822 while (send_wr) {
823 unsigned long flags;
824 struct ib_send_wr *next_send_wr;
825 struct ib_mad_send_wr_private *mad_send_wr;
826 struct ib_smp *smp;
827
828 /* Validate more parameters */
829 if (send_wr->num_sge > IB_MAD_SEND_REQ_MAX_SG)
830 goto error2;
831
832 if (send_wr->wr.ud.timeout_ms && !mad_agent->recv_handler)
833 goto error2;
834
835 if (!send_wr->wr.ud.mad_hdr) {
836 printk(KERN_ERR PFX "MAD header must be supplied "
837 "in WR %p\n", send_wr);
838 goto error2;
839 }
840
841 /*
842 * Save pointer to next work request to post in case the
843 * current one completes, and the user modifies the work
844 * request associated with the completion
845 */
846 next_send_wr = (struct ib_send_wr *)send_wr->next;
847
848 smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr;
849 if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
850 ret = handle_outgoing_dr_smp(mad_agent_priv, smp,
851 send_wr);
852 if (ret < 0) /* error */
853 goto error2;
854 else if (ret == 1) /* locally consumed */
855 goto next;
856 }
857
858 /* Allocate MAD send WR tracking structure */
859 mad_send_wr = kmalloc(sizeof *mad_send_wr, GFP_ATOMIC);
860 if (!mad_send_wr) {
861 printk(KERN_ERR PFX "No memory for "
862 "ib_mad_send_wr_private\n");
863 ret = -ENOMEM;
864 goto error2;
865 }
866
867 mad_send_wr->send_wr = *send_wr;
868 mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
869 memcpy(mad_send_wr->sg_list, send_wr->sg_list,
870 sizeof *send_wr->sg_list * send_wr->num_sge);
871 mad_send_wr->send_wr.next = NULL;
872 mad_send_wr->tid = send_wr->wr.ud.mad_hdr->tid;
873 mad_send_wr->agent = mad_agent;
874 /* Timeout will be updated after send completes */
875 mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr.
876 ud.timeout_ms);
877 mad_send_wr->retry = 0;
878 /* One reference for each work request to QP + response */
879 mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
880 mad_send_wr->status = IB_WC_SUCCESS;
881
882 /* Reference MAD agent until send completes */
883 atomic_inc(&mad_agent_priv->refcount);
884 spin_lock_irqsave(&mad_agent_priv->lock, flags);
885 list_add_tail(&mad_send_wr->agent_list,
886 &mad_agent_priv->send_list);
887 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
888
889 ret = ib_send_mad(mad_agent_priv, mad_send_wr);
890 if (ret) {
891 /* Fail send request */
892 spin_lock_irqsave(&mad_agent_priv->lock, flags);
893 list_del(&mad_send_wr->agent_list);
894 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
895 atomic_dec(&mad_agent_priv->refcount);
896 goto error2;
897 }
898next:
899 send_wr = next_send_wr;
900 }
901 return 0;
902
903error2:
904 *bad_send_wr = send_wr;
905error1:
906 return ret;
907}
908EXPORT_SYMBOL(ib_post_send_mad);
909
910/*
911 * ib_free_recv_mad - Returns data buffers used to receive
912 * a MAD to the access layer
913 */
914void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc)
915{
916 struct ib_mad_recv_buf *entry;
917 struct ib_mad_private_header *mad_priv_hdr;
918 struct ib_mad_private *priv;
919
920 mad_priv_hdr = container_of(mad_recv_wc,
921 struct ib_mad_private_header,
922 recv_wc);
923 priv = container_of(mad_priv_hdr, struct ib_mad_private, header);
924
925 /*
926 * Walk receive buffer list associated with this WC
927 * No need to remove them from list of receive buffers
928 */
929 list_for_each_entry(entry, &mad_recv_wc->recv_buf.list, list) {
930 /* Free previous receive buffer */
931 kmem_cache_free(ib_mad_cache, priv);
932 mad_priv_hdr = container_of(mad_recv_wc,
933 struct ib_mad_private_header,
934 recv_wc);
935 priv = container_of(mad_priv_hdr, struct ib_mad_private,
936 header);
937 }
938
939 /* Free last buffer */
940 kmem_cache_free(ib_mad_cache, priv);
941}
942EXPORT_SYMBOL(ib_free_recv_mad);
943
944void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc,
945 void *buf)
946{
947 printk(KERN_ERR PFX "ib_coalesce_recv_mad() not implemented yet\n");
948}
949EXPORT_SYMBOL(ib_coalesce_recv_mad);
950
951struct ib_mad_agent *ib_redirect_mad_qp(struct ib_qp *qp,
952 u8 rmpp_version,
953 ib_mad_send_handler send_handler,
954 ib_mad_recv_handler recv_handler,
955 void *context)
956{
957 return ERR_PTR(-EINVAL); /* XXX: for now */
958}
959EXPORT_SYMBOL(ib_redirect_mad_qp);
960
961int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
962 struct ib_wc *wc)
963{
964 printk(KERN_ERR PFX "ib_process_mad_wc() not implemented yet\n");
965 return 0;
966}
967EXPORT_SYMBOL(ib_process_mad_wc);
968
969static int method_in_use(struct ib_mad_mgmt_method_table **method,
970 struct ib_mad_reg_req *mad_reg_req)
971{
972 int i;
973
974 for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS);
975 i < IB_MGMT_MAX_METHODS;
976 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
977 1+i)) {
978 if ((*method)->agent[i]) {
979 printk(KERN_ERR PFX "Method %d already in use\n", i);
980 return -EINVAL;
981 }
982 }
983 return 0;
984}
985
986static int allocate_method_table(struct ib_mad_mgmt_method_table **method)
987{
988 /* Allocate management method table */
989 *method = kmalloc(sizeof **method, GFP_ATOMIC);
990 if (!*method) {
991 printk(KERN_ERR PFX "No memory for "
992 "ib_mad_mgmt_method_table\n");
993 return -ENOMEM;
994 }
995 /* Clear management method table */
996 memset(*method, 0, sizeof **method);
997
998 return 0;
999}
1000
1001/*
1002 * Check to see if there are any methods still in use
1003 */
1004static int check_method_table(struct ib_mad_mgmt_method_table *method)
1005{
1006 int i;
1007
1008 for (i = 0; i < IB_MGMT_MAX_METHODS; i++)
1009 if (method->agent[i])
1010 return 1;
1011 return 0;
1012}
1013
1014/*
1015 * Check to see if there are any method tables for this class still in use
1016 */
1017static int check_class_table(struct ib_mad_mgmt_class_table *class)
1018{
1019 int i;
1020
1021 for (i = 0; i < MAX_MGMT_CLASS; i++)
1022 if (class->method_table[i])
1023 return 1;
1024 return 0;
1025}
1026
1027static int check_vendor_class(struct ib_mad_mgmt_vendor_class *vendor_class)
1028{
1029 int i;
1030
1031 for (i = 0; i < MAX_MGMT_OUI; i++)
1032 if (vendor_class->method_table[i])
1033 return 1;
1034 return 0;
1035}
1036
1037static int find_vendor_oui(struct ib_mad_mgmt_vendor_class *vendor_class,
1038 char *oui)
1039{
1040 int i;
1041
1042 for (i = 0; i < MAX_MGMT_OUI; i++)
1043 /* Is there matching OUI for this vendor class ? */
1044 if (!memcmp(vendor_class->oui[i], oui, 3))
1045 return i;
1046
1047 return -1;
1048}
1049
1050static int check_vendor_table(struct ib_mad_mgmt_vendor_class_table *vendor)
1051{
1052 int i;
1053
1054 for (i = 0; i < MAX_MGMT_VENDOR_RANGE2; i++)
1055 if (vendor->vendor_class[i])
1056 return 1;
1057
1058 return 0;
1059}
1060
1061static void remove_methods_mad_agent(struct ib_mad_mgmt_method_table *method,
1062 struct ib_mad_agent_private *agent)
1063{
1064 int i;
1065
1066 /* Remove any methods for this mad agent */
1067 for (i = 0; i < IB_MGMT_MAX_METHODS; i++) {
1068 if (method->agent[i] == agent) {
1069 method->agent[i] = NULL;
1070 }
1071 }
1072}
1073
1074static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
1075 struct ib_mad_agent_private *agent_priv,
1076 u8 mgmt_class)
1077{
1078 struct ib_mad_port_private *port_priv;
1079 struct ib_mad_mgmt_class_table **class;
1080 struct ib_mad_mgmt_method_table **method;
1081 int i, ret;
1082
1083 port_priv = agent_priv->qp_info->port_priv;
1084 class = &port_priv->version[mad_reg_req->mgmt_class_version].class;
1085 if (!*class) {
1086 /* Allocate management class table for "new" class version */
1087 *class = kmalloc(sizeof **class, GFP_ATOMIC);
1088 if (!*class) {
1089 printk(KERN_ERR PFX "No memory for "
1090 "ib_mad_mgmt_class_table\n");
1091 ret = -ENOMEM;
1092 goto error1;
1093 }
1094 /* Clear management class table */
1095 memset(*class, 0, sizeof(**class));
1096 /* Allocate method table for this management class */
1097 method = &(*class)->method_table[mgmt_class];
1098 if ((ret = allocate_method_table(method)))
1099 goto error2;
1100 } else {
1101 method = &(*class)->method_table[mgmt_class];
1102 if (!*method) {
1103 /* Allocate method table for this management class */
1104 if ((ret = allocate_method_table(method)))
1105 goto error1;
1106 }
1107 }
1108
1109 /* Now, make sure methods are not already in use */
1110 if (method_in_use(method, mad_reg_req))
1111 goto error3;
1112
1113 /* Finally, add in methods being registered */
1114 for (i = find_first_bit(mad_reg_req->method_mask,
1115 IB_MGMT_MAX_METHODS);
1116 i < IB_MGMT_MAX_METHODS;
1117 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
1118 1+i)) {
1119 (*method)->agent[i] = agent_priv;
1120 }
1121 return 0;
1122
1123error3:
1124 /* Remove any methods for this mad agent */
1125 remove_methods_mad_agent(*method, agent_priv);
1126 /* Now, check to see if there are any methods in use */
1127 if (!check_method_table(*method)) {
1128 /* If not, release management method table */
1129 kfree(*method);
1130 *method = NULL;
1131 }
1132 ret = -EINVAL;
1133 goto error1;
1134error2:
1135 kfree(*class);
1136 *class = NULL;
1137error1:
1138 return ret;
1139}
1140
1141static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
1142 struct ib_mad_agent_private *agent_priv)
1143{
1144 struct ib_mad_port_private *port_priv;
1145 struct ib_mad_mgmt_vendor_class_table **vendor_table;
1146 struct ib_mad_mgmt_vendor_class_table *vendor = NULL;
1147 struct ib_mad_mgmt_vendor_class *vendor_class = NULL;
1148 struct ib_mad_mgmt_method_table **method;
1149 int i, ret = -ENOMEM;
1150 u8 vclass;
1151
1152 /* "New" vendor (with OUI) class */
1153 vclass = vendor_class_index(mad_reg_req->mgmt_class);
1154 port_priv = agent_priv->qp_info->port_priv;
1155 vendor_table = &port_priv->version[
1156 mad_reg_req->mgmt_class_version].vendor;
1157 if (!*vendor_table) {
1158 /* Allocate mgmt vendor class table for "new" class version */
1159 vendor = kmalloc(sizeof *vendor, GFP_ATOMIC);
1160 if (!vendor) {
1161 printk(KERN_ERR PFX "No memory for "
1162 "ib_mad_mgmt_vendor_class_table\n");
1163 goto error1;
1164 }
1165 /* Clear management vendor class table */
1166 memset(vendor, 0, sizeof(*vendor));
1167 *vendor_table = vendor;
1168 }
1169 if (!(*vendor_table)->vendor_class[vclass]) {
1170 /* Allocate table for this management vendor class */
1171 vendor_class = kmalloc(sizeof *vendor_class, GFP_ATOMIC);
1172 if (!vendor_class) {
1173 printk(KERN_ERR PFX "No memory for "
1174 "ib_mad_mgmt_vendor_class\n");
1175 goto error2;
1176 }
1177 memset(vendor_class, 0, sizeof(*vendor_class));
1178 (*vendor_table)->vendor_class[vclass] = vendor_class;
1179 }
1180 for (i = 0; i < MAX_MGMT_OUI; i++) {
1181 /* Is there matching OUI for this vendor class ? */
1182 if (!memcmp((*vendor_table)->vendor_class[vclass]->oui[i],
1183 mad_reg_req->oui, 3)) {
1184 method = &(*vendor_table)->vendor_class[
1185 vclass]->method_table[i];
1186 BUG_ON(!*method);
1187 goto check_in_use;
1188 }
1189 }
1190 for (i = 0; i < MAX_MGMT_OUI; i++) {
1191 /* OUI slot available ? */
1192 if (!is_vendor_oui((*vendor_table)->vendor_class[
1193 vclass]->oui[i])) {
1194 method = &(*vendor_table)->vendor_class[
1195 vclass]->method_table[i];
1196 BUG_ON(*method);
1197 /* Allocate method table for this OUI */
1198 if ((ret = allocate_method_table(method)))
1199 goto error3;
1200 memcpy((*vendor_table)->vendor_class[vclass]->oui[i],
1201 mad_reg_req->oui, 3);
1202 goto check_in_use;
1203 }
1204 }
1205 printk(KERN_ERR PFX "All OUI slots in use\n");
1206 goto error3;
1207
1208check_in_use:
1209 /* Now, make sure methods are not already in use */
1210 if (method_in_use(method, mad_reg_req))
1211 goto error4;
1212
1213 /* Finally, add in methods being registered */
1214 for (i = find_first_bit(mad_reg_req->method_mask,
1215 IB_MGMT_MAX_METHODS);
1216 i < IB_MGMT_MAX_METHODS;
1217 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
1218 1+i)) {
1219 (*method)->agent[i] = agent_priv;
1220 }
1221 return 0;
1222
1223error4:
1224 /* Remove any methods for this mad agent */
1225 remove_methods_mad_agent(*method, agent_priv);
1226 /* Now, check to see if there are any methods in use */
1227 if (!check_method_table(*method)) {
1228 /* If not, release management method table */
1229 kfree(*method);
1230 *method = NULL;
1231 }
1232 ret = -EINVAL;
1233error3:
1234 if (vendor_class) {
1235 (*vendor_table)->vendor_class[vclass] = NULL;
1236 kfree(vendor_class);
1237 }
1238error2:
1239 if (vendor) {
1240 *vendor_table = NULL;
1241 kfree(vendor);
1242 }
1243error1:
1244 return ret;
1245}
1246
1247static void remove_mad_reg_req(struct ib_mad_agent_private *agent_priv)
1248{
1249 struct ib_mad_port_private *port_priv;
1250 struct ib_mad_mgmt_class_table *class;
1251 struct ib_mad_mgmt_method_table *method;
1252 struct ib_mad_mgmt_vendor_class_table *vendor;
1253 struct ib_mad_mgmt_vendor_class *vendor_class;
1254 int index;
1255 u8 mgmt_class;
1256
1257 /*
1258 * Was MAD registration request supplied
1259 * with original registration ?
1260 */
1261 if (!agent_priv->reg_req) {
1262 goto out;
1263 }
1264
1265 port_priv = agent_priv->qp_info->port_priv;
1266 mgmt_class = convert_mgmt_class(agent_priv->reg_req->mgmt_class);
1267 class = port_priv->version[
1268 agent_priv->reg_req->mgmt_class_version].class;
1269 if (!class)
1270 goto vendor_check;
1271
1272 method = class->method_table[mgmt_class];
1273 if (method) {
1274 /* Remove any methods for this mad agent */
1275 remove_methods_mad_agent(method, agent_priv);
1276 /* Now, check to see if there are any methods still in use */
1277 if (!check_method_table(method)) {
1278 /* If not, release management method table */
1279 kfree(method);
1280 class->method_table[mgmt_class] = NULL;
1281 /* Any management classes left ? */
1282 if (!check_class_table(class)) {
1283 /* If not, release management class table */
1284 kfree(class);
1285 port_priv->version[
1286 agent_priv->reg_req->
1287 mgmt_class_version].class = NULL;
1288 }
1289 }
1290 }
1291
1292vendor_check:
1293 if (!is_vendor_class(mgmt_class))
1294 goto out;
1295
1296 /* normalize mgmt_class to vendor range 2 */
1297 mgmt_class = vendor_class_index(agent_priv->reg_req->mgmt_class);
1298 vendor = port_priv->version[
1299 agent_priv->reg_req->mgmt_class_version].vendor;
1300
1301 if (!vendor)
1302 goto out;
1303
1304 vendor_class = vendor->vendor_class[mgmt_class];
1305 if (vendor_class) {
1306 index = find_vendor_oui(vendor_class, agent_priv->reg_req->oui);
1307 if (index < 0)
1308 goto out;
1309 method = vendor_class->method_table[index];
1310 if (method) {
1311 /* Remove any methods for this mad agent */
1312 remove_methods_mad_agent(method, agent_priv);
1313 /*
1314 * Now, check to see if there are
1315 * any methods still in use
1316 */
1317 if (!check_method_table(method)) {
1318 /* If not, release management method table */
1319 kfree(method);
1320 vendor_class->method_table[index] = NULL;
1321 memset(vendor_class->oui[index], 0, 3);
1322 /* Any OUIs left ? */
1323 if (!check_vendor_class(vendor_class)) {
1324 /* If not, release vendor class table */
1325 kfree(vendor_class);
1326 vendor->vendor_class[mgmt_class] = NULL;
1327 /* Any other vendor classes left ? */
1328 if (!check_vendor_table(vendor)) {
1329 kfree(vendor);
1330 port_priv->version[
1331 agent_priv->reg_req->
1332 mgmt_class_version].
1333 vendor = NULL;
1334 }
1335 }
1336 }
1337 }
1338 }
1339
1340out:
1341 return;
1342}
1343
1344static int response_mad(struct ib_mad *mad)
1345{
1346 /* Trap represses are responses although response bit is reset */
1347 return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
1348 (mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
1349}
1350
1351static int solicited_mad(struct ib_mad *mad)
1352{
1353 /* CM MADs are never solicited */
1354 if (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CM) {
1355 return 0;
1356 }
1357
1358 /* XXX: Determine whether MAD is using RMPP */
1359
1360 /* Not using RMPP */
1361 /* Is this MAD a response to a previous MAD ? */
1362 return response_mad(mad);
1363}
1364
1365static struct ib_mad_agent_private *
1366find_mad_agent(struct ib_mad_port_private *port_priv,
1367 struct ib_mad *mad,
1368 int solicited)
1369{
1370 struct ib_mad_agent_private *mad_agent = NULL;
1371 unsigned long flags;
1372
1373 spin_lock_irqsave(&port_priv->reg_lock, flags);
1374
1375 /*
1376 * Whether MAD was solicited determines type of routing to
1377 * MAD client.
1378 */
1379 if (solicited) {
1380 u32 hi_tid;
1381 struct ib_mad_agent_private *entry;
1382
1383 /*
1384 * Routing is based on high 32 bits of transaction ID
1385 * of MAD.
1386 */
1387 hi_tid = be64_to_cpu(mad->mad_hdr.tid) >> 32;
1388 list_for_each_entry(entry, &port_priv->agent_list,
1389 agent_list) {
1390 if (entry->agent.hi_tid == hi_tid) {
1391 mad_agent = entry;
1392 break;
1393 }
1394 }
1395 } else {
1396 struct ib_mad_mgmt_class_table *class;
1397 struct ib_mad_mgmt_method_table *method;
1398 struct ib_mad_mgmt_vendor_class_table *vendor;
1399 struct ib_mad_mgmt_vendor_class *vendor_class;
1400 struct ib_vendor_mad *vendor_mad;
1401 int index;
1402
1403 /*
1404 * Routing is based on version, class, and method
1405 * For "newer" vendor MADs, also based on OUI
1406 */
1407 if (mad->mad_hdr.class_version >= MAX_MGMT_VERSION)
1408 goto out;
1409 if (!is_vendor_class(mad->mad_hdr.mgmt_class)) {
1410 class = port_priv->version[
1411 mad->mad_hdr.class_version].class;
1412 if (!class)
1413 goto out;
1414 method = class->method_table[convert_mgmt_class(
1415 mad->mad_hdr.mgmt_class)];
1416 if (method)
1417 mad_agent = method->agent[mad->mad_hdr.method &
1418 ~IB_MGMT_METHOD_RESP];
1419 } else {
1420 vendor = port_priv->version[
1421 mad->mad_hdr.class_version].vendor;
1422 if (!vendor)
1423 goto out;
1424 vendor_class = vendor->vendor_class[vendor_class_index(
1425 mad->mad_hdr.mgmt_class)];
1426 if (!vendor_class)
1427 goto out;
1428 /* Find matching OUI */
1429 vendor_mad = (struct ib_vendor_mad *)mad;
1430 index = find_vendor_oui(vendor_class, vendor_mad->oui);
1431 if (index == -1)
1432 goto out;
1433 method = vendor_class->method_table[index];
1434 if (method) {
1435 mad_agent = method->agent[mad->mad_hdr.method &
1436 ~IB_MGMT_METHOD_RESP];
1437 }
1438 }
1439 }
1440
1441 if (mad_agent) {
1442 if (mad_agent->agent.recv_handler)
1443 atomic_inc(&mad_agent->refcount);
1444 else {
1445 printk(KERN_NOTICE PFX "No receive handler for client "
1446 "%p on port %d\n",
1447 &mad_agent->agent, port_priv->port_num);
1448 mad_agent = NULL;
1449 }
1450 }
1451out:
1452 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
1453
1454 return mad_agent;
1455}
1456
1457static int validate_mad(struct ib_mad *mad, u32 qp_num)
1458{
1459 int valid = 0;
1460
1461 /* Make sure MAD base version is understood */
1462 if (mad->mad_hdr.base_version != IB_MGMT_BASE_VERSION) {
1463 printk(KERN_ERR PFX "MAD received with unsupported base "
1464 "version %d\n", mad->mad_hdr.base_version);
1465 goto out;
1466 }
1467
1468 /* Filter SMI packets sent to other than QP0 */
1469 if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED) ||
1470 (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) {
1471 if (qp_num == 0)
1472 valid = 1;
1473 } else {
1474 /* Filter GSI packets sent to QP0 */
1475 if (qp_num != 0)
1476 valid = 1;
1477 }
1478
1479out:
1480 return valid;
1481}
1482
1483/*
1484 * Return start of fully reassembled MAD, or NULL, if MAD isn't assembled yet
1485 */
1486static struct ib_mad_private *
1487reassemble_recv(struct ib_mad_agent_private *mad_agent_priv,
1488 struct ib_mad_private *recv)
1489{
1490 /* Until we have RMPP, all receives are reassembled!... */
1491 INIT_LIST_HEAD(&recv->header.recv_wc.recv_buf.list);
1492 return recv;
1493}
1494
1495static struct ib_mad_send_wr_private*
1496find_send_req(struct ib_mad_agent_private *mad_agent_priv,
1497 u64 tid)
1498{
1499 struct ib_mad_send_wr_private *mad_send_wr;
1500
1501 list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
1502 agent_list) {
1503 if (mad_send_wr->tid == tid)
1504 return mad_send_wr;
1505 }
1506
1507 /*
1508 * It's possible to receive the response before we've
1509 * been notified that the send has completed
1510 */
1511 list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
1512 agent_list) {
1513 if (mad_send_wr->tid == tid && mad_send_wr->timeout) {
1514 /* Verify request has not been canceled */
1515 return (mad_send_wr->status == IB_WC_SUCCESS) ?
1516 mad_send_wr : NULL;
1517 }
1518 }
1519 return NULL;
1520}
1521
1522static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
1523 struct ib_mad_private *recv,
1524 int solicited)
1525{
1526 struct ib_mad_send_wr_private *mad_send_wr;
1527 struct ib_mad_send_wc mad_send_wc;
1528 unsigned long flags;
1529
1530 /* Fully reassemble receive before processing */
1531 recv = reassemble_recv(mad_agent_priv, recv);
1532 if (!recv) {
1533 if (atomic_dec_and_test(&mad_agent_priv->refcount))
1534 wake_up(&mad_agent_priv->wait);
1535 return;
1536 }
1537
1538 /* Complete corresponding request */
1539 if (solicited) {
1540 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1541 mad_send_wr = find_send_req(mad_agent_priv,
1542 recv->mad.mad.mad_hdr.tid);
1543 if (!mad_send_wr) {
1544 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1545 ib_free_recv_mad(&recv->header.recv_wc);
1546 if (atomic_dec_and_test(&mad_agent_priv->refcount))
1547 wake_up(&mad_agent_priv->wait);
1548 return;
1549 }
1550 /* Timeout = 0 means that we won't wait for a response */
1551 mad_send_wr->timeout = 0;
1552 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1553
1554 /* Defined behavior is to complete response before request */
1555 recv->header.recv_wc.wc->wr_id = mad_send_wr->wr_id;
1556 mad_agent_priv->agent.recv_handler(
1557 &mad_agent_priv->agent,
1558 &recv->header.recv_wc);
1559 atomic_dec(&mad_agent_priv->refcount);
1560
1561 mad_send_wc.status = IB_WC_SUCCESS;
1562 mad_send_wc.vendor_err = 0;
1563 mad_send_wc.wr_id = mad_send_wr->wr_id;
1564 ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
1565 } else {
1566 mad_agent_priv->agent.recv_handler(
1567 &mad_agent_priv->agent,
1568 &recv->header.recv_wc);
1569 if (atomic_dec_and_test(&mad_agent_priv->refcount))
1570 wake_up(&mad_agent_priv->wait);
1571 }
1572}
1573
1574static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
1575 struct ib_wc *wc)
1576{
1577 struct ib_mad_qp_info *qp_info;
1578 struct ib_mad_private_header *mad_priv_hdr;
1579 struct ib_mad_private *recv, *response;
1580 struct ib_mad_list_head *mad_list;
1581 struct ib_mad_agent_private *mad_agent;
1582 int solicited;
1583
1584 response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
1585 if (!response)
1586 printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
1587 "for response buffer\n");
1588
1589 mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
1590 qp_info = mad_list->mad_queue->qp_info;
1591 dequeue_mad(mad_list);
1592
1593 mad_priv_hdr = container_of(mad_list, struct ib_mad_private_header,
1594 mad_list);
1595 recv = container_of(mad_priv_hdr, struct ib_mad_private, header);
1596 dma_unmap_single(port_priv->device->dma_device,
1597 pci_unmap_addr(&recv->header, mapping),
1598 sizeof(struct ib_mad_private) -
1599 sizeof(struct ib_mad_private_header),
1600 DMA_FROM_DEVICE);
1601
1602 /* Setup MAD receive work completion from "normal" work completion */
1603 recv->header.recv_wc.wc = wc;
1604 recv->header.recv_wc.mad_len = sizeof(struct ib_mad);
1605 recv->header.recv_wc.recv_buf.mad = &recv->mad.mad;
1606 recv->header.recv_wc.recv_buf.grh = &recv->grh;
1607
1608 if (atomic_read(&qp_info->snoop_count))
1609 snoop_recv(qp_info, &recv->header.recv_wc, IB_MAD_SNOOP_RECVS);
1610
1611 /* Validate MAD */
1612 if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
1613 goto out;
1614
1615 if (recv->mad.mad.mad_hdr.mgmt_class ==
1616 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
1617 if (!smi_handle_dr_smp_recv(&recv->mad.smp,
1618 port_priv->device->node_type,
1619 port_priv->port_num,
1620 port_priv->device->phys_port_cnt))
1621 goto out;
1622 if (!smi_check_forward_dr_smp(&recv->mad.smp))
1623 goto local;
1624 if (!smi_handle_dr_smp_send(&recv->mad.smp,
1625 port_priv->device->node_type,
1626 port_priv->port_num))
1627 goto out;
1628 if (!smi_check_local_dr_smp(&recv->mad.smp,
1629 port_priv->device,
1630 port_priv->port_num))
1631 goto out;
1632 }
1633
1634local:
1635 /* Give driver "right of first refusal" on incoming MAD */
1636 if (port_priv->device->process_mad) {
1637 int ret;
1638
1639 if (!response) {
1640 printk(KERN_ERR PFX "No memory for response MAD\n");
1641 /*
1642 * Is it better to assume that
1643 * it wouldn't be processed ?
1644 */
1645 goto out;
1646 }
1647
1648 ret = port_priv->device->process_mad(port_priv->device, 0,
1649 port_priv->port_num,
1650 wc, &recv->grh,
1651 &recv->mad.mad,
1652 &response->mad.mad);
1653 if (ret & IB_MAD_RESULT_SUCCESS) {
1654 if (ret & IB_MAD_RESULT_CONSUMED)
1655 goto out;
1656 if (ret & IB_MAD_RESULT_REPLY) {
1657 /* Send response */
1658 if (!agent_send(response, &recv->grh, wc,
1659 port_priv->device,
1660 port_priv->port_num))
1661 response = NULL;
1662 goto out;
1663 }
1664 }
1665 }
1666
1667 /* Determine corresponding MAD agent for incoming receive MAD */
1668 solicited = solicited_mad(&recv->mad.mad);
1669 mad_agent = find_mad_agent(port_priv, &recv->mad.mad, solicited);
1670 if (mad_agent) {
1671 ib_mad_complete_recv(mad_agent, recv, solicited);
1672 /*
1673 * recv is freed up in error cases in ib_mad_complete_recv
1674 * or via recv_handler in ib_mad_complete_recv()
1675 */
1676 recv = NULL;
1677 }
1678
1679out:
1680 /* Post another receive request for this QP */
1681 if (response) {
1682 ib_mad_post_receive_mads(qp_info, response);
1683 if (recv)
1684 kmem_cache_free(ib_mad_cache, recv);
1685 } else
1686 ib_mad_post_receive_mads(qp_info, recv);
1687}
1688
1689static void adjust_timeout(struct ib_mad_agent_private *mad_agent_priv)
1690{
1691 struct ib_mad_send_wr_private *mad_send_wr;
1692 unsigned long delay;
1693
1694 if (list_empty(&mad_agent_priv->wait_list)) {
1695 cancel_delayed_work(&mad_agent_priv->timed_work);
1696 } else {
1697 mad_send_wr = list_entry(mad_agent_priv->wait_list.next,
1698 struct ib_mad_send_wr_private,
1699 agent_list);
1700
1701 if (time_after(mad_agent_priv->timeout,
1702 mad_send_wr->timeout)) {
1703 mad_agent_priv->timeout = mad_send_wr->timeout;
1704 cancel_delayed_work(&mad_agent_priv->timed_work);
1705 delay = mad_send_wr->timeout - jiffies;
1706 if ((long)delay <= 0)
1707 delay = 1;
1708 queue_delayed_work(mad_agent_priv->qp_info->
1709 port_priv->wq,
1710 &mad_agent_priv->timed_work, delay);
1711 }
1712 }
1713}
1714
1715static void wait_for_response(struct ib_mad_agent_private *mad_agent_priv,
1716 struct ib_mad_send_wr_private *mad_send_wr )
1717{
1718 struct ib_mad_send_wr_private *temp_mad_send_wr;
1719 struct list_head *list_item;
1720 unsigned long delay;
1721
1722 list_del(&mad_send_wr->agent_list);
1723
1724 delay = mad_send_wr->timeout;
1725 mad_send_wr->timeout += jiffies;
1726
1727 list_for_each_prev(list_item, &mad_agent_priv->wait_list) {
1728 temp_mad_send_wr = list_entry(list_item,
1729 struct ib_mad_send_wr_private,
1730 agent_list);
1731 if (time_after(mad_send_wr->timeout,
1732 temp_mad_send_wr->timeout))
1733 break;
1734 }
1735 list_add(&mad_send_wr->agent_list, list_item);
1736
1737 /* Reschedule a work item if we have a shorter timeout */
1738 if (mad_agent_priv->wait_list.next == &mad_send_wr->agent_list) {
1739 cancel_delayed_work(&mad_agent_priv->timed_work);
1740 queue_delayed_work(mad_agent_priv->qp_info->port_priv->wq,
1741 &mad_agent_priv->timed_work, delay);
1742 }
1743}
1744
1745/*
1746 * Process a send work completion
1747 */
1748static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
1749 struct ib_mad_send_wc *mad_send_wc)
1750{
1751 struct ib_mad_agent_private *mad_agent_priv;
1752 unsigned long flags;
1753
1754 mad_agent_priv = container_of(mad_send_wr->agent,
1755 struct ib_mad_agent_private, agent);
1756
1757 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1758 if (mad_send_wc->status != IB_WC_SUCCESS &&
1759 mad_send_wr->status == IB_WC_SUCCESS) {
1760 mad_send_wr->status = mad_send_wc->status;
1761 mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
1762 }
1763
1764 if (--mad_send_wr->refcount > 0) {
1765 if (mad_send_wr->refcount == 1 && mad_send_wr->timeout &&
1766 mad_send_wr->status == IB_WC_SUCCESS) {
1767 wait_for_response(mad_agent_priv, mad_send_wr);
1768 }
1769 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1770 return;
1771 }
1772
1773 /* Remove send from MAD agent and notify client of completion */
1774 list_del(&mad_send_wr->agent_list);
1775 adjust_timeout(mad_agent_priv);
1776 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1777
1778 if (mad_send_wr->status != IB_WC_SUCCESS )
1779 mad_send_wc->status = mad_send_wr->status;
1780 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
1781 mad_send_wc);
1782
1783 /* Release reference on agent taken when sending */
1784 if (atomic_dec_and_test(&mad_agent_priv->refcount))
1785 wake_up(&mad_agent_priv->wait);
1786
1787 kfree(mad_send_wr);
1788}
1789
1790static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
1791 struct ib_wc *wc)
1792{
1793 struct ib_mad_send_wr_private *mad_send_wr, *queued_send_wr;
1794 struct ib_mad_list_head *mad_list;
1795 struct ib_mad_qp_info *qp_info;
1796 struct ib_mad_queue *send_queue;
1797 struct ib_send_wr *bad_send_wr;
1798 unsigned long flags;
1799 int ret;
1800
1801 mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
1802 mad_send_wr = container_of(mad_list, struct ib_mad_send_wr_private,
1803 mad_list);
1804 send_queue = mad_list->mad_queue;
1805 qp_info = send_queue->qp_info;
1806
1807retry:
1808 queued_send_wr = NULL;
1809 spin_lock_irqsave(&send_queue->lock, flags);
1810 list_del(&mad_list->list);
1811
1812 /* Move queued send to the send queue */
1813 if (send_queue->count-- > send_queue->max_active) {
1814 mad_list = container_of(qp_info->overflow_list.next,
1815 struct ib_mad_list_head, list);
1816 queued_send_wr = container_of(mad_list,
1817 struct ib_mad_send_wr_private,
1818 mad_list);
1819 list_del(&mad_list->list);
1820 list_add_tail(&mad_list->list, &send_queue->list);
1821 }
1822 spin_unlock_irqrestore(&send_queue->lock, flags);
1823
1824 /* Restore client wr_id in WC and complete send */
1825 wc->wr_id = mad_send_wr->wr_id;
1826 if (atomic_read(&qp_info->snoop_count))
1827 snoop_send(qp_info, &mad_send_wr->send_wr,
1828 (struct ib_mad_send_wc *)wc,
1829 IB_MAD_SNOOP_SEND_COMPLETIONS);
1830 ib_mad_complete_send_wr(mad_send_wr, (struct ib_mad_send_wc *)wc);
1831
1832 if (queued_send_wr) {
1833 ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr,
1834 &bad_send_wr);
1835 if (ret) {
1836 printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
1837 mad_send_wr = queued_send_wr;
1838 wc->status = IB_WC_LOC_QP_OP_ERR;
1839 goto retry;
1840 }
1841 }
1842}
1843
1844static void mark_sends_for_retry(struct ib_mad_qp_info *qp_info)
1845{
1846 struct ib_mad_send_wr_private *mad_send_wr;
1847 struct ib_mad_list_head *mad_list;
1848 unsigned long flags;
1849
1850 spin_lock_irqsave(&qp_info->send_queue.lock, flags);
1851 list_for_each_entry(mad_list, &qp_info->send_queue.list, list) {
1852 mad_send_wr = container_of(mad_list,
1853 struct ib_mad_send_wr_private,
1854 mad_list);
1855 mad_send_wr->retry = 1;
1856 }
1857 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
1858}
1859
1860static void mad_error_handler(struct ib_mad_port_private *port_priv,
1861 struct ib_wc *wc)
1862{
1863 struct ib_mad_list_head *mad_list;
1864 struct ib_mad_qp_info *qp_info;
1865 struct ib_mad_send_wr_private *mad_send_wr;
1866 int ret;
1867
1868 /* Determine if failure was a send or receive */
1869 mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
1870 qp_info = mad_list->mad_queue->qp_info;
1871 if (mad_list->mad_queue == &qp_info->recv_queue)
1872 /*
1873 * Receive errors indicate that the QP has entered the error
1874 * state - error handling/shutdown code will cleanup
1875 */
1876 return;
1877
1878 /*
1879 * Send errors will transition the QP to SQE - move
1880 * QP to RTS and repost flushed work requests
1881 */
1882 mad_send_wr = container_of(mad_list, struct ib_mad_send_wr_private,
1883 mad_list);
1884 if (wc->status == IB_WC_WR_FLUSH_ERR) {
1885 if (mad_send_wr->retry) {
1886 /* Repost send */
1887 struct ib_send_wr *bad_send_wr;
1888
1889 mad_send_wr->retry = 0;
1890 ret = ib_post_send(qp_info->qp, &mad_send_wr->send_wr,
1891 &bad_send_wr);
1892 if (ret)
1893 ib_mad_send_done_handler(port_priv, wc);
1894 } else
1895 ib_mad_send_done_handler(port_priv, wc);
1896 } else {
1897 struct ib_qp_attr *attr;
1898
1899 /* Transition QP to RTS and fail offending send */
1900 attr = kmalloc(sizeof *attr, GFP_KERNEL);
1901 if (attr) {
1902 attr->qp_state = IB_QPS_RTS;
1903 attr->cur_qp_state = IB_QPS_SQE;
1904 ret = ib_modify_qp(qp_info->qp, attr,
1905 IB_QP_STATE | IB_QP_CUR_STATE);
1906 kfree(attr);
1907 if (ret)
1908 printk(KERN_ERR PFX "mad_error_handler - "
1909 "ib_modify_qp to RTS : %d\n", ret);
1910 else
1911 mark_sends_for_retry(qp_info);
1912 }
1913 ib_mad_send_done_handler(port_priv, wc);
1914 }
1915}
1916
1917/*
1918 * IB MAD completion callback
1919 */
1920static void ib_mad_completion_handler(void *data)
1921{
1922 struct ib_mad_port_private *port_priv;
1923 struct ib_wc wc;
1924
1925 port_priv = (struct ib_mad_port_private *)data;
1926 ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
1927
1928 while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
1929 if (wc.status == IB_WC_SUCCESS) {
1930 switch (wc.opcode) {
1931 case IB_WC_SEND:
1932 ib_mad_send_done_handler(port_priv, &wc);
1933 break;
1934 case IB_WC_RECV:
1935 ib_mad_recv_done_handler(port_priv, &wc);
1936 break;
1937 default:
1938 BUG_ON(1);
1939 break;
1940 }
1941 } else
1942 mad_error_handler(port_priv, &wc);
1943 }
1944}
1945
1946static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
1947{
1948 unsigned long flags;
1949 struct ib_mad_send_wr_private *mad_send_wr, *temp_mad_send_wr;
1950 struct ib_mad_send_wc mad_send_wc;
1951 struct list_head cancel_list;
1952
1953 INIT_LIST_HEAD(&cancel_list);
1954
1955 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1956 list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
1957 &mad_agent_priv->send_list, agent_list) {
1958 if (mad_send_wr->status == IB_WC_SUCCESS) {
1959 mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
1960 mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
1961 }
1962 }
1963
1964 /* Empty wait list to prevent receives from finding a request */
1965 list_splice_init(&mad_agent_priv->wait_list, &cancel_list);
1966 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1967
1968 /* Report all cancelled requests */
1969 mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
1970 mad_send_wc.vendor_err = 0;
1971
1972 list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
1973 &cancel_list, agent_list) {
1974 mad_send_wc.wr_id = mad_send_wr->wr_id;
1975 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
1976 &mad_send_wc);
1977
1978 list_del(&mad_send_wr->agent_list);
1979 kfree(mad_send_wr);
1980 atomic_dec(&mad_agent_priv->refcount);
1981 }
1982}
1983
1984static struct ib_mad_send_wr_private*
1985find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv,
1986 u64 wr_id)
1987{
1988 struct ib_mad_send_wr_private *mad_send_wr;
1989
1990 list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
1991 agent_list) {
1992 if (mad_send_wr->wr_id == wr_id)
1993 return mad_send_wr;
1994 }
1995
1996 list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
1997 agent_list) {
1998 if (mad_send_wr->wr_id == wr_id)
1999 return mad_send_wr;
2000 }
2001 return NULL;
2002}
2003
2004void cancel_sends(void *data)
2005{
2006 struct ib_mad_agent_private *mad_agent_priv;
2007 struct ib_mad_send_wr_private *mad_send_wr;
2008 struct ib_mad_send_wc mad_send_wc;
2009 unsigned long flags;
2010
2011 mad_agent_priv = data;
2012
2013 mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
2014 mad_send_wc.vendor_err = 0;
2015
2016 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2017 while (!list_empty(&mad_agent_priv->canceled_list)) {
2018 mad_send_wr = list_entry(mad_agent_priv->canceled_list.next,
2019 struct ib_mad_send_wr_private,
2020 agent_list);
2021
2022 list_del(&mad_send_wr->agent_list);
2023 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2024
2025 mad_send_wc.wr_id = mad_send_wr->wr_id;
2026 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
2027 &mad_send_wc);
2028
2029 kfree(mad_send_wr);
2030 if (atomic_dec_and_test(&mad_agent_priv->refcount))
2031 wake_up(&mad_agent_priv->wait);
2032 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2033 }
2034 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2035}
2036
2037void ib_cancel_mad(struct ib_mad_agent *mad_agent,
2038 u64 wr_id)
2039{
2040 struct ib_mad_agent_private *mad_agent_priv;
2041 struct ib_mad_send_wr_private *mad_send_wr;
2042 unsigned long flags;
2043
2044 mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
2045 agent);
2046 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2047 mad_send_wr = find_send_by_wr_id(mad_agent_priv, wr_id);
2048 if (!mad_send_wr) {
2049 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2050 goto out;
2051 }
2052
2053 if (mad_send_wr->status == IB_WC_SUCCESS)
2054 mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
2055
2056 if (mad_send_wr->refcount != 0) {
2057 mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
2058 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2059 goto out;
2060 }
2061
2062 list_del(&mad_send_wr->agent_list);
2063 list_add_tail(&mad_send_wr->agent_list, &mad_agent_priv->canceled_list);
2064 adjust_timeout(mad_agent_priv);
2065 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2066
2067 queue_work(mad_agent_priv->qp_info->port_priv->wq,
2068 &mad_agent_priv->canceled_work);
2069out:
2070 return;
2071}
2072EXPORT_SYMBOL(ib_cancel_mad);
2073
2074static void local_completions(void *data)
2075{
2076 struct ib_mad_agent_private *mad_agent_priv;
2077 struct ib_mad_local_private *local;
2078 struct ib_mad_agent_private *recv_mad_agent;
2079 unsigned long flags;
2080 struct ib_wc wc;
2081 struct ib_mad_send_wc mad_send_wc;
2082
2083 mad_agent_priv = (struct ib_mad_agent_private *)data;
2084
2085 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2086 while (!list_empty(&mad_agent_priv->local_list)) {
2087 local = list_entry(mad_agent_priv->local_list.next,
2088 struct ib_mad_local_private,
2089 completion_list);
2090 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2091 if (local->mad_priv) {
2092 recv_mad_agent = local->recv_mad_agent;
2093 if (!recv_mad_agent) {
2094 printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
2095 kmem_cache_free(ib_mad_cache, local->mad_priv);
2096 goto local_send_completion;
2097 }
2098
2099 /*
2100 * Defined behavior is to complete response
2101 * before request
2102 */
2103 build_smp_wc(local->wr_id, IB_LID_PERMISSIVE,
2104 0 /* pkey index */,
2105 recv_mad_agent->agent.port_num, &wc);
2106
2107 local->mad_priv->header.recv_wc.wc = &wc;
2108 local->mad_priv->header.recv_wc.mad_len =
2109 sizeof(struct ib_mad);
2110 INIT_LIST_HEAD(&local->mad_priv->header.recv_wc.recv_buf.list);
2111 local->mad_priv->header.recv_wc.recv_buf.grh = NULL;
2112 local->mad_priv->header.recv_wc.recv_buf.mad =
2113 &local->mad_priv->mad.mad;
2114 if (atomic_read(&recv_mad_agent->qp_info->snoop_count))
2115 snoop_recv(recv_mad_agent->qp_info,
2116 &local->mad_priv->header.recv_wc,
2117 IB_MAD_SNOOP_RECVS);
2118 recv_mad_agent->agent.recv_handler(
2119 &recv_mad_agent->agent,
2120 &local->mad_priv->header.recv_wc);
2121 spin_lock_irqsave(&recv_mad_agent->lock, flags);
2122 atomic_dec(&recv_mad_agent->refcount);
2123 spin_unlock_irqrestore(&recv_mad_agent->lock, flags);
2124 }
2125
2126local_send_completion:
2127 /* Complete send */
2128 mad_send_wc.status = IB_WC_SUCCESS;
2129 mad_send_wc.vendor_err = 0;
2130 mad_send_wc.wr_id = local->wr_id;
2131 if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
2132 snoop_send(mad_agent_priv->qp_info, &local->send_wr,
2133 &mad_send_wc,
2134 IB_MAD_SNOOP_SEND_COMPLETIONS);
2135 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
2136 &mad_send_wc);
2137
2138 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2139 list_del(&local->completion_list);
2140 atomic_dec(&mad_agent_priv->refcount);
2141 kfree(local);
2142 }
2143 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2144}
2145
2146static void timeout_sends(void *data)
2147{
2148 struct ib_mad_agent_private *mad_agent_priv;
2149 struct ib_mad_send_wr_private *mad_send_wr;
2150 struct ib_mad_send_wc mad_send_wc;
2151 unsigned long flags, delay;
2152
2153 mad_agent_priv = (struct ib_mad_agent_private *)data;
2154
2155 mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
2156 mad_send_wc.vendor_err = 0;
2157
2158 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2159 while (!list_empty(&mad_agent_priv->wait_list)) {
2160 mad_send_wr = list_entry(mad_agent_priv->wait_list.next,
2161 struct ib_mad_send_wr_private,
2162 agent_list);
2163
2164 if (time_after(mad_send_wr->timeout, jiffies)) {
2165 delay = mad_send_wr->timeout - jiffies;
2166 if ((long)delay <= 0)
2167 delay = 1;
2168 queue_delayed_work(mad_agent_priv->qp_info->
2169 port_priv->wq,
2170 &mad_agent_priv->timed_work, delay);
2171 break;
2172 }
2173
2174 list_del(&mad_send_wr->agent_list);
2175 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2176
2177 mad_send_wc.wr_id = mad_send_wr->wr_id;
2178 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
2179 &mad_send_wc);
2180
2181 kfree(mad_send_wr);
2182 atomic_dec(&mad_agent_priv->refcount);
2183 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2184 }
2185 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2186}
2187
2188static void ib_mad_thread_completion_handler(struct ib_cq *cq)
2189{
2190 struct ib_mad_port_private *port_priv = cq->cq_context;
2191
2192 queue_work(port_priv->wq, &port_priv->work);
2193}
2194
2195/*
2196 * Allocate receive MADs and post receive WRs for them
2197 */
2198static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
2199 struct ib_mad_private *mad)
2200{
2201 unsigned long flags;
2202 int post, ret;
2203 struct ib_mad_private *mad_priv;
2204 struct ib_sge sg_list;
2205 struct ib_recv_wr recv_wr, *bad_recv_wr;
2206 struct ib_mad_queue *recv_queue = &qp_info->recv_queue;
2207
2208 /* Initialize common scatter list fields */
2209 sg_list.length = sizeof *mad_priv - sizeof mad_priv->header;
2210 sg_list.lkey = (*qp_info->port_priv->mr).lkey;
2211
2212 /* Initialize common receive WR fields */
2213 recv_wr.next = NULL;
2214 recv_wr.sg_list = &sg_list;
2215 recv_wr.num_sge = 1;
2216
2217 do {
2218 /* Allocate and map receive buffer */
2219 if (mad) {
2220 mad_priv = mad;
2221 mad = NULL;
2222 } else {
2223 mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
2224 if (!mad_priv) {
2225 printk(KERN_ERR PFX "No memory for receive buffer\n");
2226 ret = -ENOMEM;
2227 break;
2228 }
2229 }
2230 sg_list.addr = dma_map_single(qp_info->port_priv->
2231 device->dma_device,
2232 &mad_priv->grh,
2233 sizeof *mad_priv -
2234 sizeof mad_priv->header,
2235 DMA_FROM_DEVICE);
2236 pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr);
2237 recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
2238 mad_priv->header.mad_list.mad_queue = recv_queue;
2239
2240 /* Post receive WR */
2241 spin_lock_irqsave(&recv_queue->lock, flags);
2242 post = (++recv_queue->count < recv_queue->max_active);
2243 list_add_tail(&mad_priv->header.mad_list.list, &recv_queue->list);
2244 spin_unlock_irqrestore(&recv_queue->lock, flags);
2245 ret = ib_post_recv(qp_info->qp, &recv_wr, &bad_recv_wr);
2246 if (ret) {
2247 spin_lock_irqsave(&recv_queue->lock, flags);
2248 list_del(&mad_priv->header.mad_list.list);
2249 recv_queue->count--;
2250 spin_unlock_irqrestore(&recv_queue->lock, flags);
2251 dma_unmap_single(qp_info->port_priv->device->dma_device,
2252 pci_unmap_addr(&mad_priv->header,
2253 mapping),
2254 sizeof *mad_priv -
2255 sizeof mad_priv->header,
2256 DMA_FROM_DEVICE);
2257 kmem_cache_free(ib_mad_cache, mad_priv);
2258 printk(KERN_ERR PFX "ib_post_recv failed: %d\n", ret);
2259 break;
2260 }
2261 } while (post);
2262
2263 return ret;
2264}
2265
2266/*
2267 * Return all the posted receive MADs
2268 */
2269static void cleanup_recv_queue(struct ib_mad_qp_info *qp_info)
2270{
2271 struct ib_mad_private_header *mad_priv_hdr;
2272 struct ib_mad_private *recv;
2273 struct ib_mad_list_head *mad_list;
2274
2275 while (!list_empty(&qp_info->recv_queue.list)) {
2276
2277 mad_list = list_entry(qp_info->recv_queue.list.next,
2278 struct ib_mad_list_head, list);
2279 mad_priv_hdr = container_of(mad_list,
2280 struct ib_mad_private_header,
2281 mad_list);
2282 recv = container_of(mad_priv_hdr, struct ib_mad_private,
2283 header);
2284
2285 /* Remove from posted receive MAD list */
2286 list_del(&mad_list->list);
2287
2288 /* Undo PCI mapping */
2289 dma_unmap_single(qp_info->port_priv->device->dma_device,
2290 pci_unmap_addr(&recv->header, mapping),
2291 sizeof(struct ib_mad_private) -
2292 sizeof(struct ib_mad_private_header),
2293 DMA_FROM_DEVICE);
2294 kmem_cache_free(ib_mad_cache, recv);
2295 }
2296
2297 qp_info->recv_queue.count = 0;
2298}
2299
2300/*
2301 * Start the port
2302 */
2303static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
2304{
2305 int ret, i;
2306 struct ib_qp_attr *attr;
2307 struct ib_qp *qp;
2308
2309 attr = kmalloc(sizeof *attr, GFP_KERNEL);
2310 if (!attr) {
2311 printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n");
2312 return -ENOMEM;
2313 }
2314
2315 for (i = 0; i < IB_MAD_QPS_CORE; i++) {
2316 qp = port_priv->qp_info[i].qp;
2317 /*
2318 * PKey index for QP1 is irrelevant but
2319 * one is needed for the Reset to Init transition
2320 */
2321 attr->qp_state = IB_QPS_INIT;
2322 attr->pkey_index = 0;
2323 attr->qkey = (qp->qp_num == 0) ? 0 : IB_QP1_QKEY;
2324 ret = ib_modify_qp(qp, attr, IB_QP_STATE |
2325 IB_QP_PKEY_INDEX | IB_QP_QKEY);
2326 if (ret) {
2327 printk(KERN_ERR PFX "Couldn't change QP%d state to "
2328 "INIT: %d\n", i, ret);
2329 goto out;
2330 }
2331
2332 attr->qp_state = IB_QPS_RTR;
2333 ret = ib_modify_qp(qp, attr, IB_QP_STATE);
2334 if (ret) {
2335 printk(KERN_ERR PFX "Couldn't change QP%d state to "
2336 "RTR: %d\n", i, ret);
2337 goto out;
2338 }
2339
2340 attr->qp_state = IB_QPS_RTS;
2341 attr->sq_psn = IB_MAD_SEND_Q_PSN;
2342 ret = ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_SQ_PSN);
2343 if (ret) {
2344 printk(KERN_ERR PFX "Couldn't change QP%d state to "
2345 "RTS: %d\n", i, ret);
2346 goto out;
2347 }
2348 }
2349
2350 ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
2351 if (ret) {
2352 printk(KERN_ERR PFX "Failed to request completion "
2353 "notification: %d\n", ret);
2354 goto out;
2355 }
2356
2357 for (i = 0; i < IB_MAD_QPS_CORE; i++) {
2358 ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL);
2359 if (ret) {
2360 printk(KERN_ERR PFX "Couldn't post receive WRs\n");
2361 goto out;
2362 }
2363 }
2364out:
2365 kfree(attr);
2366 return ret;
2367}
2368
2369static void qp_event_handler(struct ib_event *event, void *qp_context)
2370{
2371 struct ib_mad_qp_info *qp_info = qp_context;
2372
2373 /* It's worse than that! He's dead, Jim! */
2374 printk(KERN_ERR PFX "Fatal error (%d) on MAD QP (%d)\n",
2375 event->event, qp_info->qp->qp_num);
2376}
2377
2378static void init_mad_queue(struct ib_mad_qp_info *qp_info,
2379 struct ib_mad_queue *mad_queue)
2380{
2381 mad_queue->qp_info = qp_info;
2382 mad_queue->count = 0;
2383 spin_lock_init(&mad_queue->lock);
2384 INIT_LIST_HEAD(&mad_queue->list);
2385}
2386
2387static void init_mad_qp(struct ib_mad_port_private *port_priv,
2388 struct ib_mad_qp_info *qp_info)
2389{
2390 qp_info->port_priv = port_priv;
2391 init_mad_queue(qp_info, &qp_info->send_queue);
2392 init_mad_queue(qp_info, &qp_info->recv_queue);
2393 INIT_LIST_HEAD(&qp_info->overflow_list);
2394 spin_lock_init(&qp_info->snoop_lock);
2395 qp_info->snoop_table = NULL;
2396 qp_info->snoop_table_size = 0;
2397 atomic_set(&qp_info->snoop_count, 0);
2398}
2399
2400static int create_mad_qp(struct ib_mad_qp_info *qp_info,
2401 enum ib_qp_type qp_type)
2402{
2403 struct ib_qp_init_attr qp_init_attr;
2404 int ret;
2405
2406 memset(&qp_init_attr, 0, sizeof qp_init_attr);
2407 qp_init_attr.send_cq = qp_info->port_priv->cq;
2408 qp_init_attr.recv_cq = qp_info->port_priv->cq;
2409 qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
2410 qp_init_attr.cap.max_send_wr = IB_MAD_QP_SEND_SIZE;
2411 qp_init_attr.cap.max_recv_wr = IB_MAD_QP_RECV_SIZE;
2412 qp_init_attr.cap.max_send_sge = IB_MAD_SEND_REQ_MAX_SG;
2413 qp_init_attr.cap.max_recv_sge = IB_MAD_RECV_REQ_MAX_SG;
2414 qp_init_attr.qp_type = qp_type;
2415 qp_init_attr.port_num = qp_info->port_priv->port_num;
2416 qp_init_attr.qp_context = qp_info;
2417 qp_init_attr.event_handler = qp_event_handler;
2418 qp_info->qp = ib_create_qp(qp_info->port_priv->pd, &qp_init_attr);
2419 if (IS_ERR(qp_info->qp)) {
2420 printk(KERN_ERR PFX "Couldn't create ib_mad QP%d\n",
2421 get_spl_qp_index(qp_type));
2422 ret = PTR_ERR(qp_info->qp);
2423 goto error;
2424 }
2425 /* Use minimum queue sizes unless the CQ is resized */
2426 qp_info->send_queue.max_active = IB_MAD_QP_SEND_SIZE;
2427 qp_info->recv_queue.max_active = IB_MAD_QP_RECV_SIZE;
2428 return 0;
2429
2430error:
2431 return ret;
2432}
2433
2434static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
2435{
2436 ib_destroy_qp(qp_info->qp);
2437 if (qp_info->snoop_table)
2438 kfree(qp_info->snoop_table);
2439}
2440
2441/*
2442 * Open the port
2443 * Create the QP, PD, MR, and CQ if needed
2444 */
2445static int ib_mad_port_open(struct ib_device *device,
2446 int port_num)
2447{
2448 int ret, cq_size;
2449 struct ib_mad_port_private *port_priv;
2450 unsigned long flags;
2451 char name[sizeof "ib_mad123"];
2452
2453 /* First, check if port already open at MAD layer */
2454 port_priv = ib_get_mad_port(device, port_num);
2455 if (port_priv) {
2456 printk(KERN_DEBUG PFX "%s port %d already open\n",
2457 device->name, port_num);
2458 return 0;
2459 }
2460
2461 /* Create new device info */
2462 port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
2463 if (!port_priv) {
2464 printk(KERN_ERR PFX "No memory for ib_mad_port_private\n");
2465 return -ENOMEM;
2466 }
2467 memset(port_priv, 0, sizeof *port_priv);
2468 port_priv->device = device;
2469 port_priv->port_num = port_num;
2470 spin_lock_init(&port_priv->reg_lock);
2471 INIT_LIST_HEAD(&port_priv->agent_list);
2472 init_mad_qp(port_priv, &port_priv->qp_info[0]);
2473 init_mad_qp(port_priv, &port_priv->qp_info[1]);
2474
2475 cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
2476 port_priv->cq = ib_create_cq(port_priv->device,
2477 (ib_comp_handler)
2478 ib_mad_thread_completion_handler,
2479 NULL, port_priv, cq_size);
2480 if (IS_ERR(port_priv->cq)) {
2481 printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n");
2482 ret = PTR_ERR(port_priv->cq);
2483 goto error3;
2484 }
2485
2486 port_priv->pd = ib_alloc_pd(device);
2487 if (IS_ERR(port_priv->pd)) {
2488 printk(KERN_ERR PFX "Couldn't create ib_mad PD\n");
2489 ret = PTR_ERR(port_priv->pd);
2490 goto error4;
2491 }
2492
2493 port_priv->mr = ib_get_dma_mr(port_priv->pd, IB_ACCESS_LOCAL_WRITE);
2494 if (IS_ERR(port_priv->mr)) {
2495 printk(KERN_ERR PFX "Couldn't get ib_mad DMA MR\n");
2496 ret = PTR_ERR(port_priv->mr);
2497 goto error5;
2498 }
2499
2500 ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI);
2501 if (ret)
2502 goto error6;
2503 ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI);
2504 if (ret)
2505 goto error7;
2506
2507 snprintf(name, sizeof name, "ib_mad%d", port_num);
2508 port_priv->wq = create_singlethread_workqueue(name);
2509 if (!port_priv->wq) {
2510 ret = -ENOMEM;
2511 goto error8;
2512 }
2513 INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv);
2514
2515 ret = ib_mad_port_start(port_priv);
2516 if (ret) {
2517 printk(KERN_ERR PFX "Couldn't start port\n");
2518 goto error9;
2519 }
2520
2521 spin_lock_irqsave(&ib_mad_port_list_lock, flags);
2522 list_add_tail(&port_priv->port_list, &ib_mad_port_list);
2523 spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
2524 return 0;
2525
2526error9:
2527 destroy_workqueue(port_priv->wq);
2528error8:
2529 destroy_mad_qp(&port_priv->qp_info[1]);
2530error7:
2531 destroy_mad_qp(&port_priv->qp_info[0]);
2532error6:
2533 ib_dereg_mr(port_priv->mr);
2534error5:
2535 ib_dealloc_pd(port_priv->pd);
2536error4:
2537 ib_destroy_cq(port_priv->cq);
2538 cleanup_recv_queue(&port_priv->qp_info[1]);
2539 cleanup_recv_queue(&port_priv->qp_info[0]);
2540error3:
2541 kfree(port_priv);
2542
2543 return ret;
2544}
2545
2546/*
2547 * Close the port
2548 * If there are no classes using the port, free the port
2549 * resources (CQ, MR, PD, QP) and remove the port's info structure
2550 */
2551static int ib_mad_port_close(struct ib_device *device, int port_num)
2552{
2553 struct ib_mad_port_private *port_priv;
2554 unsigned long flags;
2555
2556 spin_lock_irqsave(&ib_mad_port_list_lock, flags);
2557 port_priv = __ib_get_mad_port(device, port_num);
2558 if (port_priv == NULL) {
2559 spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
2560 printk(KERN_ERR PFX "Port %d not found\n", port_num);
2561 return -ENODEV;
2562 }
2563 list_del(&port_priv->port_list);
2564 spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
2565
2566 /* Stop processing completions. */
2567 flush_workqueue(port_priv->wq);
2568 destroy_workqueue(port_priv->wq);
2569 destroy_mad_qp(&port_priv->qp_info[1]);
2570 destroy_mad_qp(&port_priv->qp_info[0]);
2571 ib_dereg_mr(port_priv->mr);
2572 ib_dealloc_pd(port_priv->pd);
2573 ib_destroy_cq(port_priv->cq);
2574 cleanup_recv_queue(&port_priv->qp_info[1]);
2575 cleanup_recv_queue(&port_priv->qp_info[0]);
2576 /* XXX: Handle deallocation of MAD registration tables */
2577
2578 kfree(port_priv);
2579
2580 return 0;
2581}
2582
2583static void ib_mad_init_device(struct ib_device *device)
2584{
2585 int ret, num_ports, cur_port, i, ret2;
2586
2587 if (device->node_type == IB_NODE_SWITCH) {
2588 num_ports = 1;
2589 cur_port = 0;
2590 } else {
2591 num_ports = device->phys_port_cnt;
2592 cur_port = 1;
2593 }
2594 for (i = 0; i < num_ports; i++, cur_port++) {
2595 ret = ib_mad_port_open(device, cur_port);
2596 if (ret) {
2597 printk(KERN_ERR PFX "Couldn't open %s port %d\n",
2598 device->name, cur_port);
2599 goto error_device_open;
2600 }
2601 ret = ib_agent_port_open(device, cur_port);
2602 if (ret) {
2603 printk(KERN_ERR PFX "Couldn't open %s port %d "
2604 "for agents\n",
2605 device->name, cur_port);
2606 goto error_device_open;
2607 }
2608 }
2609
2610 goto error_device_query;
2611
2612error_device_open:
2613 while (i > 0) {
2614 cur_port--;
2615 ret2 = ib_agent_port_close(device, cur_port);
2616 if (ret2) {
2617 printk(KERN_ERR PFX "Couldn't close %s port %d "
2618 "for agents\n",
2619 device->name, cur_port);
2620 }
2621 ret2 = ib_mad_port_close(device, cur_port);
2622 if (ret2) {
2623 printk(KERN_ERR PFX "Couldn't close %s port %d\n",
2624 device->name, cur_port);
2625 }
2626 i--;
2627 }
2628
2629error_device_query:
2630 return;
2631}
2632
2633static void ib_mad_remove_device(struct ib_device *device)
2634{
2635 int ret = 0, i, num_ports, cur_port, ret2;
2636
2637 if (device->node_type == IB_NODE_SWITCH) {
2638 num_ports = 1;
2639 cur_port = 0;
2640 } else {
2641 num_ports = device->phys_port_cnt;
2642 cur_port = 1;
2643 }
2644 for (i = 0; i < num_ports; i++, cur_port++) {
2645 ret2 = ib_agent_port_close(device, cur_port);
2646 if (ret2) {
2647 printk(KERN_ERR PFX "Couldn't close %s port %d "
2648 "for agents\n",
2649 device->name, cur_port);
2650 if (!ret)
2651 ret = ret2;
2652 }
2653 ret2 = ib_mad_port_close(device, cur_port);
2654 if (ret2) {
2655 printk(KERN_ERR PFX "Couldn't close %s port %d\n",
2656 device->name, cur_port);
2657 if (!ret)
2658 ret = ret2;
2659 }
2660 }
2661}
2662
2663static struct ib_client mad_client = {
2664 .name = "mad",
2665 .add = ib_mad_init_device,
2666 .remove = ib_mad_remove_device
2667};
2668
2669static int __init ib_mad_init_module(void)
2670{
2671 int ret;
2672
2673 spin_lock_init(&ib_mad_port_list_lock);
2674 spin_lock_init(&ib_agent_port_list_lock);
2675
2676 ib_mad_cache = kmem_cache_create("ib_mad",
2677 sizeof(struct ib_mad_private),
2678 0,
2679 SLAB_HWCACHE_ALIGN,
2680 NULL,
2681 NULL);
2682 if (!ib_mad_cache) {
2683 printk(KERN_ERR PFX "Couldn't create ib_mad cache\n");
2684 ret = -ENOMEM;
2685 goto error1;
2686 }
2687
2688 INIT_LIST_HEAD(&ib_mad_port_list);
2689
2690 if (ib_register_client(&mad_client)) {
2691 printk(KERN_ERR PFX "Couldn't register ib_mad client\n");
2692 ret = -EINVAL;
2693 goto error2;
2694 }
2695
2696 return 0;
2697
2698error2:
2699 kmem_cache_destroy(ib_mad_cache);
2700error1:
2701 return ret;
2702}
2703
2704static void __exit ib_mad_cleanup_module(void)
2705{
2706 ib_unregister_client(&mad_client);
2707
2708 if (kmem_cache_destroy(ib_mad_cache)) {
2709 printk(KERN_DEBUG PFX "Failed to destroy ib_mad cache\n");
2710 }
2711}
2712
2713module_init(ib_mad_init_module);
2714module_exit(ib_mad_cleanup_module);
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
new file mode 100644
index 000000000000..4ba9f726bf1d
--- /dev/null
+++ b/drivers/infiniband/core/mad_priv.h
@@ -0,0 +1,199 @@
1/*
2 * Copyright (c) 2004, 2005, Voltaire, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: mad_priv.h 1389 2004-12-27 22:56:47Z roland $
33 */
34
35#ifndef __IB_MAD_PRIV_H__
36#define __IB_MAD_PRIV_H__
37
38#include <linux/pci.h>
39#include <linux/kthread.h>
40#include <linux/workqueue.h>
41#include <ib_mad.h>
42#include <ib_smi.h>
43
44
45#define PFX "ib_mad: "
46
47#define IB_MAD_QPS_CORE 2 /* Always QP0 and QP1 as a minimum */
48
49/* QP and CQ parameters */
50#define IB_MAD_QP_SEND_SIZE 128
51#define IB_MAD_QP_RECV_SIZE 512
52#define IB_MAD_SEND_REQ_MAX_SG 2
53#define IB_MAD_RECV_REQ_MAX_SG 1
54
55#define IB_MAD_SEND_Q_PSN 0
56
57/* Registration table sizes */
58#define MAX_MGMT_CLASS 80
59#define MAX_MGMT_VERSION 8
60#define MAX_MGMT_OUI 8
61#define MAX_MGMT_VENDOR_RANGE2 (IB_MGMT_CLASS_VENDOR_RANGE2_END - \
62 IB_MGMT_CLASS_VENDOR_RANGE2_START + 1)
63
64struct ib_mad_list_head {
65 struct list_head list;
66 struct ib_mad_queue *mad_queue;
67};
68
69struct ib_mad_private_header {
70 struct ib_mad_list_head mad_list;
71 struct ib_mad_recv_wc recv_wc;
72 DECLARE_PCI_UNMAP_ADDR(mapping)
73} __attribute__ ((packed));
74
75struct ib_mad_private {
76 struct ib_mad_private_header header;
77 struct ib_grh grh;
78 union {
79 struct ib_mad mad;
80 struct ib_rmpp_mad rmpp_mad;
81 struct ib_smp smp;
82 } mad;
83} __attribute__ ((packed));
84
85struct ib_mad_agent_private {
86 struct list_head agent_list;
87 struct ib_mad_agent agent;
88 struct ib_mad_reg_req *reg_req;
89 struct ib_mad_qp_info *qp_info;
90
91 spinlock_t lock;
92 struct list_head send_list;
93 struct list_head wait_list;
94 struct work_struct timed_work;
95 unsigned long timeout;
96 struct list_head local_list;
97 struct work_struct local_work;
98 struct list_head canceled_list;
99 struct work_struct canceled_work;
100
101 atomic_t refcount;
102 wait_queue_head_t wait;
103 u8 rmpp_version;
104};
105
106struct ib_mad_snoop_private {
107 struct ib_mad_agent agent;
108 struct ib_mad_qp_info *qp_info;
109 int snoop_index;
110 int mad_snoop_flags;
111 atomic_t refcount;
112 wait_queue_head_t wait;
113};
114
115struct ib_mad_send_wr_private {
116 struct ib_mad_list_head mad_list;
117 struct list_head agent_list;
118 struct ib_mad_agent *agent;
119 struct ib_send_wr send_wr;
120 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
121 u64 wr_id; /* client WR ID */
122 u64 tid;
123 unsigned long timeout;
124 int retry;
125 int refcount;
126 enum ib_wc_status status;
127};
128
129struct ib_mad_local_private {
130 struct list_head completion_list;
131 struct ib_mad_private *mad_priv;
132 struct ib_mad_agent_private *recv_mad_agent;
133 struct ib_send_wr send_wr;
134 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
135 u64 wr_id; /* client WR ID */
136 u64 tid;
137};
138
139struct ib_mad_mgmt_method_table {
140 struct ib_mad_agent_private *agent[IB_MGMT_MAX_METHODS];
141};
142
143struct ib_mad_mgmt_class_table {
144 struct ib_mad_mgmt_method_table *method_table[MAX_MGMT_CLASS];
145};
146
147struct ib_mad_mgmt_vendor_class {
148 u8 oui[MAX_MGMT_OUI][3];
149 struct ib_mad_mgmt_method_table *method_table[MAX_MGMT_OUI];
150};
151
152struct ib_mad_mgmt_vendor_class_table {
153 struct ib_mad_mgmt_vendor_class *vendor_class[MAX_MGMT_VENDOR_RANGE2];
154};
155
156struct ib_mad_mgmt_version_table {
157 struct ib_mad_mgmt_class_table *class;
158 struct ib_mad_mgmt_vendor_class_table *vendor;
159};
160
161struct ib_mad_queue {
162 spinlock_t lock;
163 struct list_head list;
164 int count;
165 int max_active;
166 struct ib_mad_qp_info *qp_info;
167};
168
169struct ib_mad_qp_info {
170 struct ib_mad_port_private *port_priv;
171 struct ib_qp *qp;
172 struct ib_mad_queue send_queue;
173 struct ib_mad_queue recv_queue;
174 struct list_head overflow_list;
175 spinlock_t snoop_lock;
176 struct ib_mad_snoop_private **snoop_table;
177 int snoop_table_size;
178 atomic_t snoop_count;
179};
180
181struct ib_mad_port_private {
182 struct list_head port_list;
183 struct ib_device *device;
184 int port_num;
185 struct ib_cq *cq;
186 struct ib_pd *pd;
187 struct ib_mr *mr;
188
189 spinlock_t reg_lock;
190 struct ib_mad_mgmt_version_table version[MAX_MGMT_VERSION];
191 struct list_head agent_list;
192 struct workqueue_struct *wq;
193 struct work_struct work;
194 struct ib_mad_qp_info qp_info[IB_MAD_QPS_CORE];
195};
196
197extern kmem_cache_t *ib_mad_cache;
198
199#endif /* __IB_MAD_PRIV_H__ */
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
new file mode 100644
index 000000000000..5f15feffeae2
--- /dev/null
+++ b/drivers/infiniband/core/packer.c
@@ -0,0 +1,201 @@
1/*
2 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include <ib_pack.h>
36
37static u64 value_read(int offset, int size, void *structure)
38{
39 switch (size) {
40 case 1: return *(u8 *) (structure + offset);
41 case 2: return be16_to_cpup((__be16 *) (structure + offset));
42 case 4: return be32_to_cpup((__be32 *) (structure + offset));
43 case 8: return be64_to_cpup((__be64 *) (structure + offset));
44 default:
45 printk(KERN_WARNING "Field size %d bits not handled\n", size * 8);
46 return 0;
47 }
48}
49
50/**
51 * ib_pack - Pack a structure into a buffer
52 * @desc:Array of structure field descriptions
53 * @desc_len:Number of entries in @desc
54 * @structure:Structure to pack from
55 * @buf:Buffer to pack into
56 *
57 * ib_pack() packs a list of structure fields into a buffer,
58 * controlled by the array of fields in @desc.
59 */
60void ib_pack(const struct ib_field *desc,
61 int desc_len,
62 void *structure,
63 void *buf)
64{
65 int i;
66
67 for (i = 0; i < desc_len; ++i) {
68 if (desc[i].size_bits <= 32) {
69 int shift;
70 u32 val;
71 __be32 mask;
72 __be32 *addr;
73
74 shift = 32 - desc[i].offset_bits - desc[i].size_bits;
75 if (desc[i].struct_size_bytes)
76 val = value_read(desc[i].struct_offset_bytes,
77 desc[i].struct_size_bytes,
78 structure) << shift;
79 else
80 val = 0;
81
82 mask = cpu_to_be32(((1ull << desc[i].size_bits) - 1) << shift);
83 addr = (__be32 *) buf + desc[i].offset_words;
84 *addr = (*addr & ~mask) | (cpu_to_be32(val) & mask);
85 } else if (desc[i].size_bits <= 64) {
86 int shift;
87 u64 val;
88 __be64 mask;
89 __be64 *addr;
90
91 shift = 64 - desc[i].offset_bits - desc[i].size_bits;
92 if (desc[i].struct_size_bytes)
93 val = value_read(desc[i].struct_offset_bytes,
94 desc[i].struct_size_bytes,
95 structure) << shift;
96 else
97 val = 0;
98
99 mask = cpu_to_be64(((1ull << desc[i].size_bits) - 1) << shift);
100 addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words);
101 *addr = (*addr & ~mask) | (cpu_to_be64(val) & mask);
102 } else {
103 if (desc[i].offset_bits % 8 ||
104 desc[i].size_bits % 8) {
105 printk(KERN_WARNING "Structure field %s of size %d "
106 "bits is not byte-aligned\n",
107 desc[i].field_name, desc[i].size_bits);
108 }
109
110 if (desc[i].struct_size_bytes)
111 memcpy(buf + desc[i].offset_words * 4 +
112 desc[i].offset_bits / 8,
113 structure + desc[i].struct_offset_bytes,
114 desc[i].size_bits / 8);
115 else
116 memset(buf + desc[i].offset_words * 4 +
117 desc[i].offset_bits / 8,
118 0,
119 desc[i].size_bits / 8);
120 }
121 }
122}
123EXPORT_SYMBOL(ib_pack);
124
125static void value_write(int offset, int size, u64 val, void *structure)
126{
127 switch (size * 8) {
128 case 8: *( u8 *) (structure + offset) = val; break;
129 case 16: *(__be16 *) (structure + offset) = cpu_to_be16(val); break;
130 case 32: *(__be32 *) (structure + offset) = cpu_to_be32(val); break;
131 case 64: *(__be64 *) (structure + offset) = cpu_to_be64(val); break;
132 default:
133 printk(KERN_WARNING "Field size %d bits not handled\n", size * 8);
134 }
135}
136
137/**
138 * ib_unpack - Unpack a buffer into a structure
139 * @desc:Array of structure field descriptions
140 * @desc_len:Number of entries in @desc
141 * @buf:Buffer to unpack from
142 * @structure:Structure to unpack into
143 *
144 * ib_pack() unpacks a list of structure fields from a buffer,
145 * controlled by the array of fields in @desc.
146 */
147void ib_unpack(const struct ib_field *desc,
148 int desc_len,
149 void *buf,
150 void *structure)
151{
152 int i;
153
154 for (i = 0; i < desc_len; ++i) {
155 if (!desc[i].struct_size_bytes)
156 continue;
157
158 if (desc[i].size_bits <= 32) {
159 int shift;
160 u32 val;
161 u32 mask;
162 __be32 *addr;
163
164 shift = 32 - desc[i].offset_bits - desc[i].size_bits;
165 mask = ((1ull << desc[i].size_bits) - 1) << shift;
166 addr = (__be32 *) buf + desc[i].offset_words;
167 val = (be32_to_cpup(addr) & mask) >> shift;
168 value_write(desc[i].struct_offset_bytes,
169 desc[i].struct_size_bytes,
170 val,
171 structure);
172 } else if (desc[i].size_bits <= 64) {
173 int shift;
174 u64 val;
175 u64 mask;
176 __be64 *addr;
177
178 shift = 64 - desc[i].offset_bits - desc[i].size_bits;
179 mask = ((1ull << desc[i].size_bits) - 1) << shift;
180 addr = (__be64 *) buf + desc[i].offset_words;
181 val = (be64_to_cpup(addr) & mask) >> shift;
182 value_write(desc[i].struct_offset_bytes,
183 desc[i].struct_size_bytes,
184 val,
185 structure);
186 } else {
187 if (desc[i].offset_bits % 8 ||
188 desc[i].size_bits % 8) {
189 printk(KERN_WARNING "Structure field %s of size %d "
190 "bits is not byte-aligned\n",
191 desc[i].field_name, desc[i].size_bits);
192 }
193
194 memcpy(structure + desc[i].struct_offset_bytes,
195 buf + desc[i].offset_words * 4 +
196 desc[i].offset_bits / 8,
197 desc[i].size_bits / 8);
198 }
199 }
200}
201EXPORT_SYMBOL(ib_unpack);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
new file mode 100644
index 000000000000..d4233ee61c35
--- /dev/null
+++ b/drivers/infiniband/core/sa_query.c
@@ -0,0 +1,866 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: sa_query.c 1389 2004-12-27 22:56:47Z roland $
33 */
34
35#include <linux/module.h>
36#include <linux/init.h>
37#include <linux/err.h>
38#include <linux/random.h>
39#include <linux/spinlock.h>
40#include <linux/slab.h>
41#include <linux/pci.h>
42#include <linux/dma-mapping.h>
43#include <linux/kref.h>
44#include <linux/idr.h>
45
46#include <ib_pack.h>
47#include <ib_sa.h>
48
49MODULE_AUTHOR("Roland Dreier");
50MODULE_DESCRIPTION("InfiniBand subnet administration query support");
51MODULE_LICENSE("Dual BSD/GPL");
52
53/*
54 * These two structures must be packed because they have 64-bit fields
55 * that are only 32-bit aligned. 64-bit architectures will lay them
56 * out wrong otherwise. (And unfortunately they are sent on the wire
57 * so we can't change the layout)
58 */
59struct ib_sa_hdr {
60 u64 sm_key;
61 u16 attr_offset;
62 u16 reserved;
63 ib_sa_comp_mask comp_mask;
64} __attribute__ ((packed));
65
66struct ib_sa_mad {
67 struct ib_mad_hdr mad_hdr;
68 struct ib_rmpp_hdr rmpp_hdr;
69 struct ib_sa_hdr sa_hdr;
70 u8 data[200];
71} __attribute__ ((packed));
72
73struct ib_sa_sm_ah {
74 struct ib_ah *ah;
75 struct kref ref;
76};
77
78struct ib_sa_port {
79 struct ib_mad_agent *agent;
80 struct ib_mr *mr;
81 struct ib_sa_sm_ah *sm_ah;
82 struct work_struct update_task;
83 spinlock_t ah_lock;
84 u8 port_num;
85};
86
87struct ib_sa_device {
88 int start_port, end_port;
89 struct ib_event_handler event_handler;
90 struct ib_sa_port port[0];
91};
92
93struct ib_sa_query {
94 void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
95 void (*release)(struct ib_sa_query *);
96 struct ib_sa_port *port;
97 struct ib_sa_mad *mad;
98 struct ib_sa_sm_ah *sm_ah;
99 DECLARE_PCI_UNMAP_ADDR(mapping)
100 int id;
101};
102
103struct ib_sa_path_query {
104 void (*callback)(int, struct ib_sa_path_rec *, void *);
105 void *context;
106 struct ib_sa_query sa_query;
107};
108
109struct ib_sa_mcmember_query {
110 void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
111 void *context;
112 struct ib_sa_query sa_query;
113};
114
115static void ib_sa_add_one(struct ib_device *device);
116static void ib_sa_remove_one(struct ib_device *device);
117
118static struct ib_client sa_client = {
119 .name = "sa",
120 .add = ib_sa_add_one,
121 .remove = ib_sa_remove_one
122};
123
124static spinlock_t idr_lock;
125static DEFINE_IDR(query_idr);
126
127static spinlock_t tid_lock;
128static u32 tid;
129
130enum {
131 IB_SA_ATTR_CLASS_PORTINFO = 0x01,
132 IB_SA_ATTR_NOTICE = 0x02,
133 IB_SA_ATTR_INFORM_INFO = 0x03,
134 IB_SA_ATTR_NODE_REC = 0x11,
135 IB_SA_ATTR_PORT_INFO_REC = 0x12,
136 IB_SA_ATTR_SL2VL_REC = 0x13,
137 IB_SA_ATTR_SWITCH_REC = 0x14,
138 IB_SA_ATTR_LINEAR_FDB_REC = 0x15,
139 IB_SA_ATTR_RANDOM_FDB_REC = 0x16,
140 IB_SA_ATTR_MCAST_FDB_REC = 0x17,
141 IB_SA_ATTR_SM_INFO_REC = 0x18,
142 IB_SA_ATTR_LINK_REC = 0x20,
143 IB_SA_ATTR_GUID_INFO_REC = 0x30,
144 IB_SA_ATTR_SERVICE_REC = 0x31,
145 IB_SA_ATTR_PARTITION_REC = 0x33,
146 IB_SA_ATTR_RANGE_REC = 0x34,
147 IB_SA_ATTR_PATH_REC = 0x35,
148 IB_SA_ATTR_VL_ARB_REC = 0x36,
149 IB_SA_ATTR_MC_GROUP_REC = 0x37,
150 IB_SA_ATTR_MC_MEMBER_REC = 0x38,
151 IB_SA_ATTR_TRACE_REC = 0x39,
152 IB_SA_ATTR_MULTI_PATH_REC = 0x3a,
153 IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b
154};
155
156#define PATH_REC_FIELD(field) \
157 .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \
158 .struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \
159 .field_name = "sa_path_rec:" #field
160
161static const struct ib_field path_rec_table[] = {
162 { RESERVED,
163 .offset_words = 0,
164 .offset_bits = 0,
165 .size_bits = 32 },
166 { RESERVED,
167 .offset_words = 1,
168 .offset_bits = 0,
169 .size_bits = 32 },
170 { PATH_REC_FIELD(dgid),
171 .offset_words = 2,
172 .offset_bits = 0,
173 .size_bits = 128 },
174 { PATH_REC_FIELD(sgid),
175 .offset_words = 6,
176 .offset_bits = 0,
177 .size_bits = 128 },
178 { PATH_REC_FIELD(dlid),
179 .offset_words = 10,
180 .offset_bits = 0,
181 .size_bits = 16 },
182 { PATH_REC_FIELD(slid),
183 .offset_words = 10,
184 .offset_bits = 16,
185 .size_bits = 16 },
186 { PATH_REC_FIELD(raw_traffic),
187 .offset_words = 11,
188 .offset_bits = 0,
189 .size_bits = 1 },
190 { RESERVED,
191 .offset_words = 11,
192 .offset_bits = 1,
193 .size_bits = 3 },
194 { PATH_REC_FIELD(flow_label),
195 .offset_words = 11,
196 .offset_bits = 4,
197 .size_bits = 20 },
198 { PATH_REC_FIELD(hop_limit),
199 .offset_words = 11,
200 .offset_bits = 24,
201 .size_bits = 8 },
202 { PATH_REC_FIELD(traffic_class),
203 .offset_words = 12,
204 .offset_bits = 0,
205 .size_bits = 8 },
206 { PATH_REC_FIELD(reversible),
207 .offset_words = 12,
208 .offset_bits = 8,
209 .size_bits = 1 },
210 { PATH_REC_FIELD(numb_path),
211 .offset_words = 12,
212 .offset_bits = 9,
213 .size_bits = 7 },
214 { PATH_REC_FIELD(pkey),
215 .offset_words = 12,
216 .offset_bits = 16,
217 .size_bits = 16 },
218 { RESERVED,
219 .offset_words = 13,
220 .offset_bits = 0,
221 .size_bits = 12 },
222 { PATH_REC_FIELD(sl),
223 .offset_words = 13,
224 .offset_bits = 12,
225 .size_bits = 4 },
226 { PATH_REC_FIELD(mtu_selector),
227 .offset_words = 13,
228 .offset_bits = 16,
229 .size_bits = 2 },
230 { PATH_REC_FIELD(mtu),
231 .offset_words = 13,
232 .offset_bits = 18,
233 .size_bits = 6 },
234 { PATH_REC_FIELD(rate_selector),
235 .offset_words = 13,
236 .offset_bits = 24,
237 .size_bits = 2 },
238 { PATH_REC_FIELD(rate),
239 .offset_words = 13,
240 .offset_bits = 26,
241 .size_bits = 6 },
242 { PATH_REC_FIELD(packet_life_time_selector),
243 .offset_words = 14,
244 .offset_bits = 0,
245 .size_bits = 2 },
246 { PATH_REC_FIELD(packet_life_time),
247 .offset_words = 14,
248 .offset_bits = 2,
249 .size_bits = 6 },
250 { PATH_REC_FIELD(preference),
251 .offset_words = 14,
252 .offset_bits = 8,
253 .size_bits = 8 },
254 { RESERVED,
255 .offset_words = 14,
256 .offset_bits = 16,
257 .size_bits = 48 },
258};
259
260#define MCMEMBER_REC_FIELD(field) \
261 .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field), \
262 .struct_size_bytes = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \
263 .field_name = "sa_mcmember_rec:" #field
264
265static const struct ib_field mcmember_rec_table[] = {
266 { MCMEMBER_REC_FIELD(mgid),
267 .offset_words = 0,
268 .offset_bits = 0,
269 .size_bits = 128 },
270 { MCMEMBER_REC_FIELD(port_gid),
271 .offset_words = 4,
272 .offset_bits = 0,
273 .size_bits = 128 },
274 { MCMEMBER_REC_FIELD(qkey),
275 .offset_words = 8,
276 .offset_bits = 0,
277 .size_bits = 32 },
278 { MCMEMBER_REC_FIELD(mlid),
279 .offset_words = 9,
280 .offset_bits = 0,
281 .size_bits = 16 },
282 { MCMEMBER_REC_FIELD(mtu_selector),
283 .offset_words = 9,
284 .offset_bits = 16,
285 .size_bits = 2 },
286 { MCMEMBER_REC_FIELD(mtu),
287 .offset_words = 9,
288 .offset_bits = 18,
289 .size_bits = 6 },
290 { MCMEMBER_REC_FIELD(traffic_class),
291 .offset_words = 9,
292 .offset_bits = 24,
293 .size_bits = 8 },
294 { MCMEMBER_REC_FIELD(pkey),
295 .offset_words = 10,
296 .offset_bits = 0,
297 .size_bits = 16 },
298 { MCMEMBER_REC_FIELD(rate_selector),
299 .offset_words = 10,
300 .offset_bits = 16,
301 .size_bits = 2 },
302 { MCMEMBER_REC_FIELD(rate),
303 .offset_words = 10,
304 .offset_bits = 18,
305 .size_bits = 6 },
306 { MCMEMBER_REC_FIELD(packet_life_time_selector),
307 .offset_words = 10,
308 .offset_bits = 24,
309 .size_bits = 2 },
310 { MCMEMBER_REC_FIELD(packet_life_time),
311 .offset_words = 10,
312 .offset_bits = 26,
313 .size_bits = 6 },
314 { MCMEMBER_REC_FIELD(sl),
315 .offset_words = 11,
316 .offset_bits = 0,
317 .size_bits = 4 },
318 { MCMEMBER_REC_FIELD(flow_label),
319 .offset_words = 11,
320 .offset_bits = 4,
321 .size_bits = 20 },
322 { MCMEMBER_REC_FIELD(hop_limit),
323 .offset_words = 11,
324 .offset_bits = 24,
325 .size_bits = 8 },
326 { MCMEMBER_REC_FIELD(scope),
327 .offset_words = 12,
328 .offset_bits = 0,
329 .size_bits = 4 },
330 { MCMEMBER_REC_FIELD(join_state),
331 .offset_words = 12,
332 .offset_bits = 4,
333 .size_bits = 4 },
334 { MCMEMBER_REC_FIELD(proxy_join),
335 .offset_words = 12,
336 .offset_bits = 8,
337 .size_bits = 1 },
338 { RESERVED,
339 .offset_words = 12,
340 .offset_bits = 9,
341 .size_bits = 23 },
342};
343
344static void free_sm_ah(struct kref *kref)
345{
346 struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
347
348 ib_destroy_ah(sm_ah->ah);
349 kfree(sm_ah);
350}
351
352static void update_sm_ah(void *port_ptr)
353{
354 struct ib_sa_port *port = port_ptr;
355 struct ib_sa_sm_ah *new_ah, *old_ah;
356 struct ib_port_attr port_attr;
357 struct ib_ah_attr ah_attr;
358
359 if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
360 printk(KERN_WARNING "Couldn't query port\n");
361 return;
362 }
363
364 new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
365 if (!new_ah) {
366 printk(KERN_WARNING "Couldn't allocate new SM AH\n");
367 return;
368 }
369
370 kref_init(&new_ah->ref);
371
372 memset(&ah_attr, 0, sizeof ah_attr);
373 ah_attr.dlid = port_attr.sm_lid;
374 ah_attr.sl = port_attr.sm_sl;
375 ah_attr.port_num = port->port_num;
376
377 new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
378 if (IS_ERR(new_ah->ah)) {
379 printk(KERN_WARNING "Couldn't create new SM AH\n");
380 kfree(new_ah);
381 return;
382 }
383
384 spin_lock_irq(&port->ah_lock);
385 old_ah = port->sm_ah;
386 port->sm_ah = new_ah;
387 spin_unlock_irq(&port->ah_lock);
388
389 if (old_ah)
390 kref_put(&old_ah->ref, free_sm_ah);
391}
392
393static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
394{
395 if (event->event == IB_EVENT_PORT_ERR ||
396 event->event == IB_EVENT_PORT_ACTIVE ||
397 event->event == IB_EVENT_LID_CHANGE ||
398 event->event == IB_EVENT_PKEY_CHANGE ||
399 event->event == IB_EVENT_SM_CHANGE) {
400 struct ib_sa_device *sa_dev =
401 ib_get_client_data(event->device, &sa_client);
402
403 schedule_work(&sa_dev->port[event->element.port_num -
404 sa_dev->start_port].update_task);
405 }
406}
407
408/**
409 * ib_sa_cancel_query - try to cancel an SA query
410 * @id:ID of query to cancel
411 * @query:query pointer to cancel
412 *
413 * Try to cancel an SA query. If the id and query don't match up or
414 * the query has already completed, nothing is done. Otherwise the
415 * query is canceled and will complete with a status of -EINTR.
416 */
417void ib_sa_cancel_query(int id, struct ib_sa_query *query)
418{
419 unsigned long flags;
420 struct ib_mad_agent *agent;
421
422 spin_lock_irqsave(&idr_lock, flags);
423 if (idr_find(&query_idr, id) != query) {
424 spin_unlock_irqrestore(&idr_lock, flags);
425 return;
426 }
427 agent = query->port->agent;
428 spin_unlock_irqrestore(&idr_lock, flags);
429
430 ib_cancel_mad(agent, id);
431}
432EXPORT_SYMBOL(ib_sa_cancel_query);
433
434static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
435{
436 unsigned long flags;
437
438 memset(mad, 0, sizeof *mad);
439
440 mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
441 mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
442 mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
443
444 spin_lock_irqsave(&tid_lock, flags);
445 mad->mad_hdr.tid =
446 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
447 spin_unlock_irqrestore(&tid_lock, flags);
448}
449
450static int send_mad(struct ib_sa_query *query, int timeout_ms)
451{
452 struct ib_sa_port *port = query->port;
453 unsigned long flags;
454 int ret;
455 struct ib_sge gather_list;
456 struct ib_send_wr *bad_wr, wr = {
457 .opcode = IB_WR_SEND,
458 .sg_list = &gather_list,
459 .num_sge = 1,
460 .send_flags = IB_SEND_SIGNALED,
461 .wr = {
462 .ud = {
463 .mad_hdr = &query->mad->mad_hdr,
464 .remote_qpn = 1,
465 .remote_qkey = IB_QP1_QKEY,
466 .timeout_ms = timeout_ms
467 }
468 }
469 };
470
471retry:
472 if (!idr_pre_get(&query_idr, GFP_ATOMIC))
473 return -ENOMEM;
474 spin_lock_irqsave(&idr_lock, flags);
475 ret = idr_get_new(&query_idr, query, &query->id);
476 spin_unlock_irqrestore(&idr_lock, flags);
477 if (ret == -EAGAIN)
478 goto retry;
479 if (ret)
480 return ret;
481
482 wr.wr_id = query->id;
483
484 spin_lock_irqsave(&port->ah_lock, flags);
485 kref_get(&port->sm_ah->ref);
486 query->sm_ah = port->sm_ah;
487 wr.wr.ud.ah = port->sm_ah->ah;
488 spin_unlock_irqrestore(&port->ah_lock, flags);
489
490 gather_list.addr = dma_map_single(port->agent->device->dma_device,
491 query->mad,
492 sizeof (struct ib_sa_mad),
493 DMA_TO_DEVICE);
494 gather_list.length = sizeof (struct ib_sa_mad);
495 gather_list.lkey = port->mr->lkey;
496 pci_unmap_addr_set(query, mapping, gather_list.addr);
497
498 ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
499 if (ret) {
500 dma_unmap_single(port->agent->device->dma_device,
501 pci_unmap_addr(query, mapping),
502 sizeof (struct ib_sa_mad),
503 DMA_TO_DEVICE);
504 kref_put(&query->sm_ah->ref, free_sm_ah);
505 spin_lock_irqsave(&idr_lock, flags);
506 idr_remove(&query_idr, query->id);
507 spin_unlock_irqrestore(&idr_lock, flags);
508 }
509
510 return ret;
511}
512
513static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
514 int status,
515 struct ib_sa_mad *mad)
516{
517 struct ib_sa_path_query *query =
518 container_of(sa_query, struct ib_sa_path_query, sa_query);
519
520 if (mad) {
521 struct ib_sa_path_rec rec;
522
523 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
524 mad->data, &rec);
525 query->callback(status, &rec, query->context);
526 } else
527 query->callback(status, NULL, query->context);
528}
529
530static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
531{
532 kfree(sa_query->mad);
533 kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
534}
535
536/**
537 * ib_sa_path_rec_get - Start a Path get query
538 * @device:device to send query on
539 * @port_num: port number to send query on
540 * @rec:Path Record to send in query
541 * @comp_mask:component mask to send in query
542 * @timeout_ms:time to wait for response
543 * @gfp_mask:GFP mask to use for internal allocations
544 * @callback:function called when query completes, times out or is
545 * canceled
546 * @context:opaque user context passed to callback
547 * @sa_query:query context, used to cancel query
548 *
549 * Send a Path Record Get query to the SA to look up a path. The
550 * callback function will be called when the query completes (or
551 * fails); status is 0 for a successful response, -EINTR if the query
552 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
553 * occurred sending the query. The resp parameter of the callback is
554 * only valid if status is 0.
555 *
556 * If the return value of ib_sa_path_rec_get() is negative, it is an
557 * error code. Otherwise it is a query ID that can be used to cancel
558 * the query.
559 */
560int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
561 struct ib_sa_path_rec *rec,
562 ib_sa_comp_mask comp_mask,
563 int timeout_ms, int gfp_mask,
564 void (*callback)(int status,
565 struct ib_sa_path_rec *resp,
566 void *context),
567 void *context,
568 struct ib_sa_query **sa_query)
569{
570 struct ib_sa_path_query *query;
571 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
572 struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
573 struct ib_mad_agent *agent = port->agent;
574 int ret;
575
576 query = kmalloc(sizeof *query, gfp_mask);
577 if (!query)
578 return -ENOMEM;
579 query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
580 if (!query->sa_query.mad) {
581 kfree(query);
582 return -ENOMEM;
583 }
584
585 query->callback = callback;
586 query->context = context;
587
588 init_mad(query->sa_query.mad, agent);
589
590 query->sa_query.callback = ib_sa_path_rec_callback;
591 query->sa_query.release = ib_sa_path_rec_release;
592 query->sa_query.port = port;
593 query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET;
594 query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC);
595 query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
596
597 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table),
598 rec, query->sa_query.mad->data);
599
600 *sa_query = &query->sa_query;
601 ret = send_mad(&query->sa_query, timeout_ms);
602 if (ret) {
603 *sa_query = NULL;
604 kfree(query->sa_query.mad);
605 kfree(query);
606 }
607
608 return ret ? ret : query->sa_query.id;
609}
610EXPORT_SYMBOL(ib_sa_path_rec_get);
611
612static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
613 int status,
614 struct ib_sa_mad *mad)
615{
616 struct ib_sa_mcmember_query *query =
617 container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
618
619 if (mad) {
620 struct ib_sa_mcmember_rec rec;
621
622 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
623 mad->data, &rec);
624 query->callback(status, &rec, query->context);
625 } else
626 query->callback(status, NULL, query->context);
627}
628
629static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
630{
631 kfree(sa_query->mad);
632 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
633}
634
635int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
636 u8 method,
637 struct ib_sa_mcmember_rec *rec,
638 ib_sa_comp_mask comp_mask,
639 int timeout_ms, int gfp_mask,
640 void (*callback)(int status,
641 struct ib_sa_mcmember_rec *resp,
642 void *context),
643 void *context,
644 struct ib_sa_query **sa_query)
645{
646 struct ib_sa_mcmember_query *query;
647 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
648 struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
649 struct ib_mad_agent *agent = port->agent;
650 int ret;
651
652 query = kmalloc(sizeof *query, gfp_mask);
653 if (!query)
654 return -ENOMEM;
655 query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
656 if (!query->sa_query.mad) {
657 kfree(query);
658 return -ENOMEM;
659 }
660
661 query->callback = callback;
662 query->context = context;
663
664 init_mad(query->sa_query.mad, agent);
665
666 query->sa_query.callback = ib_sa_mcmember_rec_callback;
667 query->sa_query.release = ib_sa_mcmember_rec_release;
668 query->sa_query.port = port;
669 query->sa_query.mad->mad_hdr.method = method;
670 query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
671 query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
672
673 ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
674 rec, query->sa_query.mad->data);
675
676 *sa_query = &query->sa_query;
677 ret = send_mad(&query->sa_query, timeout_ms);
678 if (ret) {
679 *sa_query = NULL;
680 kfree(query->sa_query.mad);
681 kfree(query);
682 }
683
684 return ret ? ret : query->sa_query.id;
685}
686EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
687
688static void send_handler(struct ib_mad_agent *agent,
689 struct ib_mad_send_wc *mad_send_wc)
690{
691 struct ib_sa_query *query;
692 unsigned long flags;
693
694 spin_lock_irqsave(&idr_lock, flags);
695 query = idr_find(&query_idr, mad_send_wc->wr_id);
696 spin_unlock_irqrestore(&idr_lock, flags);
697
698 if (!query)
699 return;
700
701 switch (mad_send_wc->status) {
702 case IB_WC_SUCCESS:
703 /* No callback -- already got recv */
704 break;
705 case IB_WC_RESP_TIMEOUT_ERR:
706 query->callback(query, -ETIMEDOUT, NULL);
707 break;
708 case IB_WC_WR_FLUSH_ERR:
709 query->callback(query, -EINTR, NULL);
710 break;
711 default:
712 query->callback(query, -EIO, NULL);
713 break;
714 }
715
716 dma_unmap_single(agent->device->dma_device,
717 pci_unmap_addr(query, mapping),
718 sizeof (struct ib_sa_mad),
719 DMA_TO_DEVICE);
720 kref_put(&query->sm_ah->ref, free_sm_ah);
721
722 query->release(query);
723
724 spin_lock_irqsave(&idr_lock, flags);
725 idr_remove(&query_idr, mad_send_wc->wr_id);
726 spin_unlock_irqrestore(&idr_lock, flags);
727}
728
729static void recv_handler(struct ib_mad_agent *mad_agent,
730 struct ib_mad_recv_wc *mad_recv_wc)
731{
732 struct ib_sa_query *query;
733 unsigned long flags;
734
735 spin_lock_irqsave(&idr_lock, flags);
736 query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
737 spin_unlock_irqrestore(&idr_lock, flags);
738
739 if (query) {
740 if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
741 query->callback(query,
742 mad_recv_wc->recv_buf.mad->mad_hdr.status ?
743 -EINVAL : 0,
744 (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
745 else
746 query->callback(query, -EIO, NULL);
747 }
748
749 ib_free_recv_mad(mad_recv_wc);
750}
751
752static void ib_sa_add_one(struct ib_device *device)
753{
754 struct ib_sa_device *sa_dev;
755 int s, e, i;
756
757 if (device->node_type == IB_NODE_SWITCH)
758 s = e = 0;
759 else {
760 s = 1;
761 e = device->phys_port_cnt;
762 }
763
764 sa_dev = kmalloc(sizeof *sa_dev +
765 (e - s + 1) * sizeof (struct ib_sa_port),
766 GFP_KERNEL);
767 if (!sa_dev)
768 return;
769
770 sa_dev->start_port = s;
771 sa_dev->end_port = e;
772
773 for (i = 0; i <= e - s; ++i) {
774 sa_dev->port[i].mr = NULL;
775 sa_dev->port[i].sm_ah = NULL;
776 sa_dev->port[i].port_num = i + s;
777 spin_lock_init(&sa_dev->port[i].ah_lock);
778
779 sa_dev->port[i].agent =
780 ib_register_mad_agent(device, i + s, IB_QPT_GSI,
781 NULL, 0, send_handler,
782 recv_handler, sa_dev);
783 if (IS_ERR(sa_dev->port[i].agent))
784 goto err;
785
786 sa_dev->port[i].mr = ib_get_dma_mr(sa_dev->port[i].agent->qp->pd,
787 IB_ACCESS_LOCAL_WRITE);
788 if (IS_ERR(sa_dev->port[i].mr)) {
789 ib_unregister_mad_agent(sa_dev->port[i].agent);
790 goto err;
791 }
792
793 INIT_WORK(&sa_dev->port[i].update_task,
794 update_sm_ah, &sa_dev->port[i]);
795 }
796
797 ib_set_client_data(device, &sa_client, sa_dev);
798
799 /*
800 * We register our event handler after everything is set up,
801 * and then update our cached info after the event handler is
802 * registered to avoid any problems if a port changes state
803 * during our initialization.
804 */
805
806 INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
807 if (ib_register_event_handler(&sa_dev->event_handler))
808 goto err;
809
810 for (i = 0; i <= e - s; ++i)
811 update_sm_ah(&sa_dev->port[i]);
812
813 return;
814
815err:
816 while (--i >= 0) {
817 ib_dereg_mr(sa_dev->port[i].mr);
818 ib_unregister_mad_agent(sa_dev->port[i].agent);
819 }
820
821 kfree(sa_dev);
822
823 return;
824}
825
826static void ib_sa_remove_one(struct ib_device *device)
827{
828 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
829 int i;
830
831 if (!sa_dev)
832 return;
833
834 ib_unregister_event_handler(&sa_dev->event_handler);
835
836 for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
837 ib_unregister_mad_agent(sa_dev->port[i].agent);
838 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
839 }
840
841 kfree(sa_dev);
842}
843
844static int __init ib_sa_init(void)
845{
846 int ret;
847
848 spin_lock_init(&idr_lock);
849 spin_lock_init(&tid_lock);
850
851 get_random_bytes(&tid, sizeof tid);
852
853 ret = ib_register_client(&sa_client);
854 if (ret)
855 printk(KERN_ERR "Couldn't register ib_sa client\n");
856
857 return ret;
858}
859
860static void __exit ib_sa_cleanup(void)
861{
862 ib_unregister_client(&sa_client);
863}
864
865module_init(ib_sa_init);
866module_exit(ib_sa_cleanup);
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
new file mode 100644
index 000000000000..b4b284324a33
--- /dev/null
+++ b/drivers/infiniband/core/smi.c
@@ -0,0 +1,234 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $
37 */
38
39#include <ib_smi.h>
40#include "smi.h"
41
42/*
43 * Fixup a directed route SMP for sending
44 * Return 0 if the SMP should be discarded
45 */
46int smi_handle_dr_smp_send(struct ib_smp *smp,
47 u8 node_type,
48 int port_num)
49{
50 u8 hop_ptr, hop_cnt;
51
52 hop_ptr = smp->hop_ptr;
53 hop_cnt = smp->hop_cnt;
54
55 /* See section 14.2.2.2, Vol 1 IB spec */
56 if (!ib_get_smp_direction(smp)) {
57 /* C14-9:1 */
58 if (hop_cnt && hop_ptr == 0) {
59 smp->hop_ptr++;
60 return (smp->initial_path[smp->hop_ptr] ==
61 port_num);
62 }
63
64 /* C14-9:2 */
65 if (hop_ptr && hop_ptr < hop_cnt) {
66 if (node_type != IB_NODE_SWITCH)
67 return 0;
68
69 /* smp->return_path set when received */
70 smp->hop_ptr++;
71 return (smp->initial_path[smp->hop_ptr] ==
72 port_num);
73 }
74
75 /* C14-9:3 -- We're at the end of the DR segment of path */
76 if (hop_ptr == hop_cnt) {
77 /* smp->return_path set when received */
78 smp->hop_ptr++;
79 return (node_type == IB_NODE_SWITCH ||
80 smp->dr_dlid == IB_LID_PERMISSIVE);
81 }
82
83 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
84 /* C14-9:5 -- Fail unreasonable hop pointer */
85 return (hop_ptr == hop_cnt + 1);
86
87 } else {
88 /* C14-13:1 */
89 if (hop_cnt && hop_ptr == hop_cnt + 1) {
90 smp->hop_ptr--;
91 return (smp->return_path[smp->hop_ptr] ==
92 port_num);
93 }
94
95 /* C14-13:2 */
96 if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
97 if (node_type != IB_NODE_SWITCH)
98 return 0;
99
100 smp->hop_ptr--;
101 return (smp->return_path[smp->hop_ptr] ==
102 port_num);
103 }
104
105 /* C14-13:3 -- at the end of the DR segment of path */
106 if (hop_ptr == 1) {
107 smp->hop_ptr--;
108 /* C14-13:3 -- SMPs destined for SM shouldn't be here */
109 return (node_type == IB_NODE_SWITCH ||
110 smp->dr_slid == IB_LID_PERMISSIVE);
111 }
112
113 /* C14-13:4 -- hop_ptr = 0 -> should have gone to SM */
114 if (hop_ptr == 0)
115 return 1;
116
117 /* C14-13:5 -- Check for unreasonable hop pointer */
118 return 0;
119 }
120}
121
122/*
123 * Adjust information for a received SMP
124 * Return 0 if the SMP should be dropped
125 */
126int smi_handle_dr_smp_recv(struct ib_smp *smp,
127 u8 node_type,
128 int port_num,
129 int phys_port_cnt)
130{
131 u8 hop_ptr, hop_cnt;
132
133 hop_ptr = smp->hop_ptr;
134 hop_cnt = smp->hop_cnt;
135
136 /* See section 14.2.2.2, Vol 1 IB spec */
137 if (!ib_get_smp_direction(smp)) {
138 /* C14-9:1 -- sender should have incremented hop_ptr */
139 if (hop_cnt && hop_ptr == 0)
140 return 0;
141
142 /* C14-9:2 -- intermediate hop */
143 if (hop_ptr && hop_ptr < hop_cnt) {
144 if (node_type != IB_NODE_SWITCH)
145 return 0;
146
147 smp->return_path[hop_ptr] = port_num;
148 /* smp->hop_ptr updated when sending */
149 return (smp->initial_path[hop_ptr+1] <= phys_port_cnt);
150 }
151
152 /* C14-9:3 -- We're at the end of the DR segment of path */
153 if (hop_ptr == hop_cnt) {
154 if (hop_cnt)
155 smp->return_path[hop_ptr] = port_num;
156 /* smp->hop_ptr updated when sending */
157
158 return (node_type == IB_NODE_SWITCH ||
159 smp->dr_dlid == IB_LID_PERMISSIVE);
160 }
161
162 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
163 /* C14-9:5 -- fail unreasonable hop pointer */
164 return (hop_ptr == hop_cnt + 1);
165
166 } else {
167
168 /* C14-13:1 */
169 if (hop_cnt && hop_ptr == hop_cnt + 1) {
170 smp->hop_ptr--;
171 return (smp->return_path[smp->hop_ptr] ==
172 port_num);
173 }
174
175 /* C14-13:2 */
176 if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
177 if (node_type != IB_NODE_SWITCH)
178 return 0;
179
180 /* smp->hop_ptr updated when sending */
181 return (smp->return_path[hop_ptr-1] <= phys_port_cnt);
182 }
183
184 /* C14-13:3 -- We're at the end of the DR segment of path */
185 if (hop_ptr == 1) {
186 if (smp->dr_slid == IB_LID_PERMISSIVE) {
187 /* giving SMP to SM - update hop_ptr */
188 smp->hop_ptr--;
189 return 1;
190 }
191 /* smp->hop_ptr updated when sending */
192 return (node_type == IB_NODE_SWITCH);
193 }
194
195 /* C14-13:4 -- hop_ptr = 0 -> give to SM */
196 /* C14-13:5 -- Check for unreasonable hop pointer */
197 return (hop_ptr == 0);
198 }
199}
200
201/*
202 * Return 1 if the received DR SMP should be forwarded to the send queue
203 * Return 0 if the SMP should be completed up the stack
204 */
205int smi_check_forward_dr_smp(struct ib_smp *smp)
206{
207 u8 hop_ptr, hop_cnt;
208
209 hop_ptr = smp->hop_ptr;
210 hop_cnt = smp->hop_cnt;
211
212 if (!ib_get_smp_direction(smp)) {
213 /* C14-9:2 -- intermediate hop */
214 if (hop_ptr && hop_ptr < hop_cnt)
215 return 1;
216
217 /* C14-9:3 -- at the end of the DR segment of path */
218 if (hop_ptr == hop_cnt)
219 return (smp->dr_dlid == IB_LID_PERMISSIVE);
220
221 /* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
222 if (hop_ptr == hop_cnt + 1)
223 return 1;
224 } else {
225 /* C14-13:2 */
226 if (2 <= hop_ptr && hop_ptr <= hop_cnt)
227 return 1;
228
229 /* C14-13:3 -- at the end of the DR segment of path */
230 if (hop_ptr == 1)
231 return (smp->dr_slid != IB_LID_PERMISSIVE);
232 }
233 return 0;
234}
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
new file mode 100644
index 000000000000..db25503a0736
--- /dev/null
+++ b/drivers/infiniband/core/smi.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: smi.h 1389 2004-12-27 22:56:47Z roland $
37 */
38
39#ifndef __SMI_H_
40#define __SMI_H_
41
42int smi_handle_dr_smp_recv(struct ib_smp *smp,
43 u8 node_type,
44 int port_num,
45 int phys_port_cnt);
46extern int smi_check_forward_dr_smp(struct ib_smp *smp);
47extern int smi_handle_dr_smp_send(struct ib_smp *smp,
48 u8 node_type,
49 int port_num);
50extern int smi_check_local_dr_smp(struct ib_smp *smp,
51 struct ib_device *device,
52 int port_num);
53
54/*
55 * Return 1 if the SMP should be handled by the local SMA/SM via process_mad
56 */
57static inline int smi_check_local_smp(struct ib_mad_agent *mad_agent,
58 struct ib_smp *smp)
59{
60 /* C14-9:3 -- We're at the end of the DR segment of path */
61 /* C14-9:4 -- Hop Pointer = Hop Count + 1 -> give to SMA/SM */
62 return ((mad_agent->device->process_mad &&
63 !ib_get_smp_direction(smp) &&
64 (smp->hop_ptr == smp->hop_cnt + 1)));
65}
66
67#endif /* __SMI_H_ */
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
new file mode 100644
index 000000000000..3a413f72ff6d
--- /dev/null
+++ b/drivers/infiniband/core/sysfs.c
@@ -0,0 +1,762 @@
1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: sysfs.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include "core_priv.h"
36
37#include <ib_mad.h>
38
39struct ib_port {
40 struct kobject kobj;
41 struct ib_device *ibdev;
42 struct attribute_group gid_group;
43 struct attribute **gid_attr;
44 struct attribute_group pkey_group;
45 struct attribute **pkey_attr;
46 u8 port_num;
47};
48
49struct port_attribute {
50 struct attribute attr;
51 ssize_t (*show)(struct ib_port *, struct port_attribute *, char *buf);
52 ssize_t (*store)(struct ib_port *, struct port_attribute *,
53 const char *buf, size_t count);
54};
55
56#define PORT_ATTR(_name, _mode, _show, _store) \
57struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store)
58
59#define PORT_ATTR_RO(_name) \
60struct port_attribute port_attr_##_name = __ATTR_RO(_name)
61
62struct port_table_attribute {
63 struct port_attribute attr;
64 int index;
65};
66
67static ssize_t port_attr_show(struct kobject *kobj,
68 struct attribute *attr, char *buf)
69{
70 struct port_attribute *port_attr =
71 container_of(attr, struct port_attribute, attr);
72 struct ib_port *p = container_of(kobj, struct ib_port, kobj);
73
74 if (!port_attr->show)
75 return 0;
76
77 return port_attr->show(p, port_attr, buf);
78}
79
80static struct sysfs_ops port_sysfs_ops = {
81 .show = port_attr_show
82};
83
84static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
85 char *buf)
86{
87 struct ib_port_attr attr;
88 ssize_t ret;
89
90 static const char *state_name[] = {
91 [IB_PORT_NOP] = "NOP",
92 [IB_PORT_DOWN] = "DOWN",
93 [IB_PORT_INIT] = "INIT",
94 [IB_PORT_ARMED] = "ARMED",
95 [IB_PORT_ACTIVE] = "ACTIVE",
96 [IB_PORT_ACTIVE_DEFER] = "ACTIVE_DEFER"
97 };
98
99 ret = ib_query_port(p->ibdev, p->port_num, &attr);
100 if (ret)
101 return ret;
102
103 return sprintf(buf, "%d: %s\n", attr.state,
104 attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ?
105 state_name[attr.state] : "UNKNOWN");
106}
107
108static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused,
109 char *buf)
110{
111 struct ib_port_attr attr;
112 ssize_t ret;
113
114 ret = ib_query_port(p->ibdev, p->port_num, &attr);
115 if (ret)
116 return ret;
117
118 return sprintf(buf, "0x%x\n", attr.lid);
119}
120
121static ssize_t lid_mask_count_show(struct ib_port *p,
122 struct port_attribute *unused,
123 char *buf)
124{
125 struct ib_port_attr attr;
126 ssize_t ret;
127
128 ret = ib_query_port(p->ibdev, p->port_num, &attr);
129 if (ret)
130 return ret;
131
132 return sprintf(buf, "%d\n", attr.lmc);
133}
134
135static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused,
136 char *buf)
137{
138 struct ib_port_attr attr;
139 ssize_t ret;
140
141 ret = ib_query_port(p->ibdev, p->port_num, &attr);
142 if (ret)
143 return ret;
144
145 return sprintf(buf, "0x%x\n", attr.sm_lid);
146}
147
148static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused,
149 char *buf)
150{
151 struct ib_port_attr attr;
152 ssize_t ret;
153
154 ret = ib_query_port(p->ibdev, p->port_num, &attr);
155 if (ret)
156 return ret;
157
158 return sprintf(buf, "%d\n", attr.sm_sl);
159}
160
161static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused,
162 char *buf)
163{
164 struct ib_port_attr attr;
165 ssize_t ret;
166
167 ret = ib_query_port(p->ibdev, p->port_num, &attr);
168 if (ret)
169 return ret;
170
171 return sprintf(buf, "0x%08x\n", attr.port_cap_flags);
172}
173
174static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
175 char *buf)
176{
177 struct ib_port_attr attr;
178 char *speed = "";
179 int rate;
180 ssize_t ret;
181
182 ret = ib_query_port(p->ibdev, p->port_num, &attr);
183 if (ret)
184 return ret;
185
186 switch (attr.active_speed) {
187 case 2: speed = " DDR"; break;
188 case 4: speed = " QDR"; break;
189 }
190
191 rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed;
192 if (rate < 0)
193 return -EINVAL;
194
195 return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
196 rate / 10, rate % 10 ? ".5" : "",
197 ib_width_enum_to_int(attr.active_width), speed);
198}
199
200static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
201 char *buf)
202{
203 struct ib_port_attr attr;
204
205 ssize_t ret;
206
207 ret = ib_query_port(p->ibdev, p->port_num, &attr);
208 if (ret)
209 return ret;
210
211 switch (attr.phys_state) {
212 case 1: return sprintf(buf, "1: Sleep\n");
213 case 2: return sprintf(buf, "2: Polling\n");
214 case 3: return sprintf(buf, "3: Disabled\n");
215 case 4: return sprintf(buf, "4: PortConfigurationTraining\n");
216 case 5: return sprintf(buf, "5: LinkUp\n");
217 case 6: return sprintf(buf, "6: LinkErrorRecovery\n");
218 case 7: return sprintf(buf, "7: Phy Test\n");
219 default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
220 }
221}
222
223static PORT_ATTR_RO(state);
224static PORT_ATTR_RO(lid);
225static PORT_ATTR_RO(lid_mask_count);
226static PORT_ATTR_RO(sm_lid);
227static PORT_ATTR_RO(sm_sl);
228static PORT_ATTR_RO(cap_mask);
229static PORT_ATTR_RO(rate);
230static PORT_ATTR_RO(phys_state);
231
232static struct attribute *port_default_attrs[] = {
233 &port_attr_state.attr,
234 &port_attr_lid.attr,
235 &port_attr_lid_mask_count.attr,
236 &port_attr_sm_lid.attr,
237 &port_attr_sm_sl.attr,
238 &port_attr_cap_mask.attr,
239 &port_attr_rate.attr,
240 &port_attr_phys_state.attr,
241 NULL
242};
243
244static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
245 char *buf)
246{
247 struct port_table_attribute *tab_attr =
248 container_of(attr, struct port_table_attribute, attr);
249 union ib_gid gid;
250 ssize_t ret;
251
252 ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
253 if (ret)
254 return ret;
255
256 return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
257 be16_to_cpu(((u16 *) gid.raw)[0]),
258 be16_to_cpu(((u16 *) gid.raw)[1]),
259 be16_to_cpu(((u16 *) gid.raw)[2]),
260 be16_to_cpu(((u16 *) gid.raw)[3]),
261 be16_to_cpu(((u16 *) gid.raw)[4]),
262 be16_to_cpu(((u16 *) gid.raw)[5]),
263 be16_to_cpu(((u16 *) gid.raw)[6]),
264 be16_to_cpu(((u16 *) gid.raw)[7]));
265}
266
267static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
268 char *buf)
269{
270 struct port_table_attribute *tab_attr =
271 container_of(attr, struct port_table_attribute, attr);
272 u16 pkey;
273 ssize_t ret;
274
275 ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
276 if (ret)
277 return ret;
278
279 return sprintf(buf, "0x%04x\n", pkey);
280}
281
282#define PORT_PMA_ATTR(_name, _counter, _width, _offset) \
283struct port_table_attribute port_pma_attr_##_name = { \
284 .attr = __ATTR(_name, S_IRUGO, show_pma_counter, NULL), \
285 .index = (_offset) | ((_width) << 16) | ((_counter) << 24) \
286}
287
288static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
289 char *buf)
290{
291 struct port_table_attribute *tab_attr =
292 container_of(attr, struct port_table_attribute, attr);
293 int offset = tab_attr->index & 0xffff;
294 int width = (tab_attr->index >> 16) & 0xff;
295 struct ib_mad *in_mad = NULL;
296 struct ib_mad *out_mad = NULL;
297 ssize_t ret;
298
299 if (!p->ibdev->process_mad)
300 return sprintf(buf, "N/A (no PMA)\n");
301
302 in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
303 out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
304 if (!in_mad || !out_mad) {
305 ret = -ENOMEM;
306 goto out;
307 }
308
309 memset(in_mad, 0, sizeof *in_mad);
310 in_mad->mad_hdr.base_version = 1;
311 in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT;
312 in_mad->mad_hdr.class_version = 1;
313 in_mad->mad_hdr.method = IB_MGMT_METHOD_GET;
314 in_mad->mad_hdr.attr_id = cpu_to_be16(0x12); /* PortCounters */
315
316 in_mad->data[41] = p->port_num; /* PortSelect field */
317
318 if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
319 p->port_num, NULL, NULL, in_mad, out_mad) &
320 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
321 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
322 ret = -EINVAL;
323 goto out;
324 }
325
326 switch (width) {
327 case 4:
328 ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
329 (offset % 4)) & 0xf);
330 break;
331 case 8:
332 ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
333 break;
334 case 16:
335 ret = sprintf(buf, "%u\n",
336 be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8)));
337 break;
338 case 32:
339 ret = sprintf(buf, "%u\n",
340 be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8)));
341 break;
342 default:
343 ret = 0;
344 }
345
346out:
347 kfree(in_mad);
348 kfree(out_mad);
349
350 return ret;
351}
352
353static PORT_PMA_ATTR(symbol_error , 0, 16, 32);
354static PORT_PMA_ATTR(link_error_recovery , 1, 8, 48);
355static PORT_PMA_ATTR(link_downed , 2, 8, 56);
356static PORT_PMA_ATTR(port_rcv_errors , 3, 16, 64);
357static PORT_PMA_ATTR(port_rcv_remote_physical_errors, 4, 16, 80);
358static PORT_PMA_ATTR(port_rcv_switch_relay_errors , 5, 16, 96);
359static PORT_PMA_ATTR(port_xmit_discards , 6, 16, 112);
360static PORT_PMA_ATTR(port_xmit_constraint_errors , 7, 8, 128);
361static PORT_PMA_ATTR(port_rcv_constraint_errors , 8, 8, 136);
362static PORT_PMA_ATTR(local_link_integrity_errors , 9, 4, 152);
363static PORT_PMA_ATTR(excessive_buffer_overrun_errors, 10, 4, 156);
364static PORT_PMA_ATTR(VL15_dropped , 11, 16, 176);
365static PORT_PMA_ATTR(port_xmit_data , 12, 32, 192);
366static PORT_PMA_ATTR(port_rcv_data , 13, 32, 224);
367static PORT_PMA_ATTR(port_xmit_packets , 14, 32, 256);
368static PORT_PMA_ATTR(port_rcv_packets , 15, 32, 288);
369
370static struct attribute *pma_attrs[] = {
371 &port_pma_attr_symbol_error.attr.attr,
372 &port_pma_attr_link_error_recovery.attr.attr,
373 &port_pma_attr_link_downed.attr.attr,
374 &port_pma_attr_port_rcv_errors.attr.attr,
375 &port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
376 &port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
377 &port_pma_attr_port_xmit_discards.attr.attr,
378 &port_pma_attr_port_xmit_constraint_errors.attr.attr,
379 &port_pma_attr_port_rcv_constraint_errors.attr.attr,
380 &port_pma_attr_local_link_integrity_errors.attr.attr,
381 &port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
382 &port_pma_attr_VL15_dropped.attr.attr,
383 &port_pma_attr_port_xmit_data.attr.attr,
384 &port_pma_attr_port_rcv_data.attr.attr,
385 &port_pma_attr_port_xmit_packets.attr.attr,
386 &port_pma_attr_port_rcv_packets.attr.attr,
387 NULL
388};
389
390static struct attribute_group pma_group = {
391 .name = "counters",
392 .attrs = pma_attrs
393};
394
395static void ib_port_release(struct kobject *kobj)
396{
397 struct ib_port *p = container_of(kobj, struct ib_port, kobj);
398 struct attribute *a;
399 int i;
400
401 for (i = 0; (a = p->gid_attr[i]); ++i) {
402 kfree(a->name);
403 kfree(a);
404 }
405
406 for (i = 0; (a = p->pkey_attr[i]); ++i) {
407 kfree(a->name);
408 kfree(a);
409 }
410
411 kfree(p->gid_attr);
412 kfree(p);
413}
414
415static struct kobj_type port_type = {
416 .release = ib_port_release,
417 .sysfs_ops = &port_sysfs_ops,
418 .default_attrs = port_default_attrs
419};
420
421static void ib_device_release(struct class_device *cdev)
422{
423 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
424
425 kfree(dev);
426}
427
428static int ib_device_hotplug(struct class_device *cdev, char **envp,
429 int num_envp, char *buf, int size)
430{
431 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
432 int i = 0, len = 0;
433
434 if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,
435 "NAME=%s", dev->name))
436 return -ENOMEM;
437
438 /*
439 * It might be nice to pass the node GUID to hotplug, but
440 * right now the only way to get it is to query the device
441 * provider, and this can crash during device removal because
442 * we are will be running after driver removal has started.
443 * We could add a node_guid field to struct ib_device, or we
444 * could just let the hotplug script read the node GUID from
445 * sysfs when devices are added.
446 */
447
448 envp[i] = NULL;
449 return 0;
450}
451
452static int alloc_group(struct attribute ***attr,
453 ssize_t (*show)(struct ib_port *,
454 struct port_attribute *, char *buf),
455 int len)
456{
457 struct port_table_attribute ***tab_attr =
458 (struct port_table_attribute ***) attr;
459 int i;
460 int ret;
461
462 *tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL);
463 if (!*tab_attr)
464 return -ENOMEM;
465
466 memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr);
467
468 for (i = 0; i < len; ++i) {
469 (*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL);
470 if (!(*tab_attr)[i]) {
471 ret = -ENOMEM;
472 goto err;
473 }
474 memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]);
475 (*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL);
476 if (!(*tab_attr)[i]->attr.attr.name) {
477 ret = -ENOMEM;
478 goto err;
479 }
480
481 if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) {
482 ret = -ENOMEM;
483 goto err;
484 }
485
486 (*tab_attr)[i]->attr.attr.mode = S_IRUGO;
487 (*tab_attr)[i]->attr.attr.owner = THIS_MODULE;
488 (*tab_attr)[i]->attr.show = show;
489 (*tab_attr)[i]->index = i;
490 }
491
492 return 0;
493
494err:
495 for (i = 0; i < len; ++i) {
496 if ((*tab_attr)[i])
497 kfree((*tab_attr)[i]->attr.attr.name);
498 kfree((*tab_attr)[i]);
499 }
500
501 kfree(*tab_attr);
502
503 return ret;
504}
505
506static int add_port(struct ib_device *device, int port_num)
507{
508 struct ib_port *p;
509 struct ib_port_attr attr;
510 int i;
511 int ret;
512
513 ret = ib_query_port(device, port_num, &attr);
514 if (ret)
515 return ret;
516
517 p = kmalloc(sizeof *p, GFP_KERNEL);
518 if (!p)
519 return -ENOMEM;
520 memset(p, 0, sizeof *p);
521
522 p->ibdev = device;
523 p->port_num = port_num;
524 p->kobj.ktype = &port_type;
525
526 p->kobj.parent = kobject_get(&device->ports_parent);
527 if (!p->kobj.parent) {
528 ret = -EBUSY;
529 goto err;
530 }
531
532 ret = kobject_set_name(&p->kobj, "%d", port_num);
533 if (ret)
534 goto err_put;
535
536 ret = kobject_register(&p->kobj);
537 if (ret)
538 goto err_put;
539
540 ret = sysfs_create_group(&p->kobj, &pma_group);
541 if (ret)
542 goto err_put;
543
544 ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len);
545 if (ret)
546 goto err_remove_pma;
547
548 p->gid_group.name = "gids";
549 p->gid_group.attrs = p->gid_attr;
550
551 ret = sysfs_create_group(&p->kobj, &p->gid_group);
552 if (ret)
553 goto err_free_gid;
554
555 ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len);
556 if (ret)
557 goto err_remove_gid;
558
559 p->pkey_group.name = "pkeys";
560 p->pkey_group.attrs = p->pkey_attr;
561
562 ret = sysfs_create_group(&p->kobj, &p->pkey_group);
563 if (ret)
564 goto err_free_pkey;
565
566 list_add_tail(&p->kobj.entry, &device->port_list);
567
568 return 0;
569
570err_free_pkey:
571 for (i = 0; i < attr.pkey_tbl_len; ++i) {
572 kfree(p->pkey_attr[i]->name);
573 kfree(p->pkey_attr[i]);
574 }
575
576 kfree(p->pkey_attr);
577
578err_remove_gid:
579 sysfs_remove_group(&p->kobj, &p->gid_group);
580
581err_free_gid:
582 for (i = 0; i < attr.gid_tbl_len; ++i) {
583 kfree(p->gid_attr[i]->name);
584 kfree(p->gid_attr[i]);
585 }
586
587 kfree(p->gid_attr);
588
589err_remove_pma:
590 sysfs_remove_group(&p->kobj, &pma_group);
591
592err_put:
593 kobject_put(&device->ports_parent);
594
595err:
596 kfree(p);
597 return ret;
598}
599
600static ssize_t show_node_type(struct class_device *cdev, char *buf)
601{
602 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
603
604 switch (dev->node_type) {
605 case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
606 case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
607 case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
608 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type);
609 }
610}
611
612static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
613{
614 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
615 struct ib_device_attr attr;
616 ssize_t ret;
617
618 ret = ib_query_device(dev, &attr);
619 if (ret)
620 return ret;
621
622 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
623 be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]),
624 be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]),
625 be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]),
626 be16_to_cpu(((u16 *) &attr.sys_image_guid)[3]));
627}
628
629static ssize_t show_node_guid(struct class_device *cdev, char *buf)
630{
631 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
632 struct ib_device_attr attr;
633 ssize_t ret;
634
635 ret = ib_query_device(dev, &attr);
636 if (ret)
637 return ret;
638
639 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
640 be16_to_cpu(((u16 *) &attr.node_guid)[0]),
641 be16_to_cpu(((u16 *) &attr.node_guid)[1]),
642 be16_to_cpu(((u16 *) &attr.node_guid)[2]),
643 be16_to_cpu(((u16 *) &attr.node_guid)[3]));
644}
645
646static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
647static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
648static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
649
650static struct class_device_attribute *ib_class_attributes[] = {
651 &class_device_attr_node_type,
652 &class_device_attr_sys_image_guid,
653 &class_device_attr_node_guid
654};
655
656static struct class ib_class = {
657 .name = "infiniband",
658 .release = ib_device_release,
659 .hotplug = ib_device_hotplug,
660};
661
662int ib_device_register_sysfs(struct ib_device *device)
663{
664 struct class_device *class_dev = &device->class_dev;
665 int ret;
666 int i;
667
668 class_dev->class = &ib_class;
669 class_dev->class_data = device;
670 strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE);
671
672 INIT_LIST_HEAD(&device->port_list);
673
674 ret = class_device_register(class_dev);
675 if (ret)
676 goto err;
677
678 for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {
679 ret = class_device_create_file(class_dev, ib_class_attributes[i]);
680 if (ret)
681 goto err_unregister;
682 }
683
684 device->ports_parent.parent = kobject_get(&class_dev->kobj);
685 if (!device->ports_parent.parent) {
686 ret = -EBUSY;
687 goto err_unregister;
688 }
689 ret = kobject_set_name(&device->ports_parent, "ports");
690 if (ret)
691 goto err_put;
692 ret = kobject_register(&device->ports_parent);
693 if (ret)
694 goto err_put;
695
696 if (device->node_type == IB_NODE_SWITCH) {
697 ret = add_port(device, 0);
698 if (ret)
699 goto err_put;
700 } else {
701 int i;
702
703 for (i = 1; i <= device->phys_port_cnt; ++i) {
704 ret = add_port(device, i);
705 if (ret)
706 goto err_put;
707 }
708 }
709
710 return 0;
711
712err_put:
713 {
714 struct kobject *p, *t;
715 struct ib_port *port;
716
717 list_for_each_entry_safe(p, t, &device->port_list, entry) {
718 list_del(&p->entry);
719 port = container_of(p, struct ib_port, kobj);
720 sysfs_remove_group(p, &pma_group);
721 sysfs_remove_group(p, &port->pkey_group);
722 sysfs_remove_group(p, &port->gid_group);
723 kobject_unregister(p);
724 }
725 }
726
727 kobject_put(&class_dev->kobj);
728
729err_unregister:
730 class_device_unregister(class_dev);
731
732err:
733 return ret;
734}
735
736void ib_device_unregister_sysfs(struct ib_device *device)
737{
738 struct kobject *p, *t;
739 struct ib_port *port;
740
741 list_for_each_entry_safe(p, t, &device->port_list, entry) {
742 list_del(&p->entry);
743 port = container_of(p, struct ib_port, kobj);
744 sysfs_remove_group(p, &pma_group);
745 sysfs_remove_group(p, &port->pkey_group);
746 sysfs_remove_group(p, &port->gid_group);
747 kobject_unregister(p);
748 }
749
750 kobject_unregister(&device->ports_parent);
751 class_device_unregister(&device->class_dev);
752}
753
754int ib_sysfs_setup(void)
755{
756 return class_register(&ib_class);
757}
758
759void ib_sysfs_cleanup(void)
760{
761 class_unregister(&ib_class);
762}
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
new file mode 100644
index 000000000000..dc4eb1db5e96
--- /dev/null
+++ b/drivers/infiniband/core/ud_header.c
@@ -0,0 +1,365 @@
1/*
2 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: ud_header.c 1349 2004-12-16 21:09:43Z roland $
33 */
34
35#include <linux/errno.h>
36
37#include <ib_pack.h>
38
39#define STRUCT_FIELD(header, field) \
40 .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \
41 .struct_size_bytes = sizeof ((struct ib_unpacked_ ## header *) 0)->field, \
42 .field_name = #header ":" #field
43
44static const struct ib_field lrh_table[] = {
45 { STRUCT_FIELD(lrh, virtual_lane),
46 .offset_words = 0,
47 .offset_bits = 0,
48 .size_bits = 4 },
49 { STRUCT_FIELD(lrh, link_version),
50 .offset_words = 0,
51 .offset_bits = 4,
52 .size_bits = 4 },
53 { STRUCT_FIELD(lrh, service_level),
54 .offset_words = 0,
55 .offset_bits = 8,
56 .size_bits = 4 },
57 { RESERVED,
58 .offset_words = 0,
59 .offset_bits = 12,
60 .size_bits = 2 },
61 { STRUCT_FIELD(lrh, link_next_header),
62 .offset_words = 0,
63 .offset_bits = 14,
64 .size_bits = 2 },
65 { STRUCT_FIELD(lrh, destination_lid),
66 .offset_words = 0,
67 .offset_bits = 16,
68 .size_bits = 16 },
69 { RESERVED,
70 .offset_words = 1,
71 .offset_bits = 0,
72 .size_bits = 5 },
73 { STRUCT_FIELD(lrh, packet_length),
74 .offset_words = 1,
75 .offset_bits = 5,
76 .size_bits = 11 },
77 { STRUCT_FIELD(lrh, source_lid),
78 .offset_words = 1,
79 .offset_bits = 16,
80 .size_bits = 16 }
81};
82
83static const struct ib_field grh_table[] = {
84 { STRUCT_FIELD(grh, ip_version),
85 .offset_words = 0,
86 .offset_bits = 0,
87 .size_bits = 4 },
88 { STRUCT_FIELD(grh, traffic_class),
89 .offset_words = 0,
90 .offset_bits = 4,
91 .size_bits = 8 },
92 { STRUCT_FIELD(grh, flow_label),
93 .offset_words = 0,
94 .offset_bits = 12,
95 .size_bits = 20 },
96 { STRUCT_FIELD(grh, payload_length),
97 .offset_words = 1,
98 .offset_bits = 0,
99 .size_bits = 16 },
100 { STRUCT_FIELD(grh, next_header),
101 .offset_words = 1,
102 .offset_bits = 16,
103 .size_bits = 8 },
104 { STRUCT_FIELD(grh, hop_limit),
105 .offset_words = 1,
106 .offset_bits = 24,
107 .size_bits = 8 },
108 { STRUCT_FIELD(grh, source_gid),
109 .offset_words = 2,
110 .offset_bits = 0,
111 .size_bits = 128 },
112 { STRUCT_FIELD(grh, destination_gid),
113 .offset_words = 6,
114 .offset_bits = 0,
115 .size_bits = 128 }
116};
117
118static const struct ib_field bth_table[] = {
119 { STRUCT_FIELD(bth, opcode),
120 .offset_words = 0,
121 .offset_bits = 0,
122 .size_bits = 8 },
123 { STRUCT_FIELD(bth, solicited_event),
124 .offset_words = 0,
125 .offset_bits = 8,
126 .size_bits = 1 },
127 { STRUCT_FIELD(bth, mig_req),
128 .offset_words = 0,
129 .offset_bits = 9,
130 .size_bits = 1 },
131 { STRUCT_FIELD(bth, pad_count),
132 .offset_words = 0,
133 .offset_bits = 10,
134 .size_bits = 2 },
135 { STRUCT_FIELD(bth, transport_header_version),
136 .offset_words = 0,
137 .offset_bits = 12,
138 .size_bits = 4 },
139 { STRUCT_FIELD(bth, pkey),
140 .offset_words = 0,
141 .offset_bits = 16,
142 .size_bits = 16 },
143 { RESERVED,
144 .offset_words = 1,
145 .offset_bits = 0,
146 .size_bits = 8 },
147 { STRUCT_FIELD(bth, destination_qpn),
148 .offset_words = 1,
149 .offset_bits = 8,
150 .size_bits = 24 },
151 { STRUCT_FIELD(bth, ack_req),
152 .offset_words = 2,
153 .offset_bits = 0,
154 .size_bits = 1 },
155 { RESERVED,
156 .offset_words = 2,
157 .offset_bits = 1,
158 .size_bits = 7 },
159 { STRUCT_FIELD(bth, psn),
160 .offset_words = 2,
161 .offset_bits = 8,
162 .size_bits = 24 }
163};
164
165static const struct ib_field deth_table[] = {
166 { STRUCT_FIELD(deth, qkey),
167 .offset_words = 0,
168 .offset_bits = 0,
169 .size_bits = 32 },
170 { RESERVED,
171 .offset_words = 1,
172 .offset_bits = 0,
173 .size_bits = 8 },
174 { STRUCT_FIELD(deth, source_qpn),
175 .offset_words = 1,
176 .offset_bits = 8,
177 .size_bits = 24 }
178};
179
180/**
181 * ib_ud_header_init - Initialize UD header structure
182 * @payload_bytes:Length of packet payload
183 * @grh_present:GRH flag (if non-zero, GRH will be included)
184 * @header:Structure to initialize
185 *
186 * ib_ud_header_init() initializes the lrh.link_version, lrh.link_next_header,
187 * lrh.packet_length, grh.ip_version, grh.payload_length,
188 * grh.next_header, bth.opcode, bth.pad_count and
189 * bth.transport_header_version fields of a &struct ib_ud_header given
190 * the payload length and whether a GRH will be included.
191 */
192void ib_ud_header_init(int payload_bytes,
193 int grh_present,
194 struct ib_ud_header *header)
195{
196 int header_len;
197
198 memset(header, 0, sizeof *header);
199
200 header_len =
201 IB_LRH_BYTES +
202 IB_BTH_BYTES +
203 IB_DETH_BYTES;
204 if (grh_present) {
205 header_len += IB_GRH_BYTES;
206 }
207
208 header->lrh.link_version = 0;
209 header->lrh.link_next_header =
210 grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
211 header->lrh.packet_length = (IB_LRH_BYTES +
212 IB_BTH_BYTES +
213 IB_DETH_BYTES +
214 payload_bytes +
215 4 + /* ICRC */
216 3) / 4; /* round up */
217
218 header->grh_present = grh_present;
219 if (grh_present) {
220 header->lrh.packet_length += IB_GRH_BYTES / 4;
221
222 header->grh.ip_version = 6;
223 header->grh.payload_length =
224 cpu_to_be16((IB_BTH_BYTES +
225 IB_DETH_BYTES +
226 payload_bytes +
227 4 + /* ICRC */
228 3) & ~3); /* round up */
229 header->grh.next_header = 0x1b;
230 }
231
232 cpu_to_be16s(&header->lrh.packet_length);
233
234 if (header->immediate_present)
235 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
236 else
237 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY;
238 header->bth.pad_count = (4 - payload_bytes) & 3;
239 header->bth.transport_header_version = 0;
240}
241EXPORT_SYMBOL(ib_ud_header_init);
242
243/**
244 * ib_ud_header_pack - Pack UD header struct into wire format
245 * @header:UD header struct
246 * @buf:Buffer to pack into
247 *
248 * ib_ud_header_pack() packs the UD header structure @header into wire
249 * format in the buffer @buf.
250 */
251int ib_ud_header_pack(struct ib_ud_header *header,
252 void *buf)
253{
254 int len = 0;
255
256 ib_pack(lrh_table, ARRAY_SIZE(lrh_table),
257 &header->lrh, buf);
258 len += IB_LRH_BYTES;
259
260 if (header->grh_present) {
261 ib_pack(grh_table, ARRAY_SIZE(grh_table),
262 &header->grh, buf + len);
263 len += IB_GRH_BYTES;
264 }
265
266 ib_pack(bth_table, ARRAY_SIZE(bth_table),
267 &header->bth, buf + len);
268 len += IB_BTH_BYTES;
269
270 ib_pack(deth_table, ARRAY_SIZE(deth_table),
271 &header->deth, buf + len);
272 len += IB_DETH_BYTES;
273
274 if (header->immediate_present) {
275 memcpy(buf + len, &header->immediate_data, sizeof header->immediate_data);
276 len += sizeof header->immediate_data;
277 }
278
279 return len;
280}
281EXPORT_SYMBOL(ib_ud_header_pack);
282
283/**
284 * ib_ud_header_unpack - Unpack UD header struct from wire format
285 * @header:UD header struct
286 * @buf:Buffer to pack into
287 *
288 * ib_ud_header_pack() unpacks the UD header structure @header from wire
289 * format in the buffer @buf.
290 */
291int ib_ud_header_unpack(void *buf,
292 struct ib_ud_header *header)
293{
294 ib_unpack(lrh_table, ARRAY_SIZE(lrh_table),
295 buf, &header->lrh);
296 buf += IB_LRH_BYTES;
297
298 if (header->lrh.link_version != 0) {
299 printk(KERN_WARNING "Invalid LRH.link_version %d\n",
300 header->lrh.link_version);
301 return -EINVAL;
302 }
303
304 switch (header->lrh.link_next_header) {
305 case IB_LNH_IBA_LOCAL:
306 header->grh_present = 0;
307 break;
308
309 case IB_LNH_IBA_GLOBAL:
310 header->grh_present = 1;
311 ib_unpack(grh_table, ARRAY_SIZE(grh_table),
312 buf, &header->grh);
313 buf += IB_GRH_BYTES;
314
315 if (header->grh.ip_version != 6) {
316 printk(KERN_WARNING "Invalid GRH.ip_version %d\n",
317 header->grh.ip_version);
318 return -EINVAL;
319 }
320 if (header->grh.next_header != 0x1b) {
321 printk(KERN_WARNING "Invalid GRH.next_header 0x%02x\n",
322 header->grh.next_header);
323 return -EINVAL;
324 }
325 break;
326
327 default:
328 printk(KERN_WARNING "Invalid LRH.link_next_header %d\n",
329 header->lrh.link_next_header);
330 return -EINVAL;
331 }
332
333 ib_unpack(bth_table, ARRAY_SIZE(bth_table),
334 buf, &header->bth);
335 buf += IB_BTH_BYTES;
336
337 switch (header->bth.opcode) {
338 case IB_OPCODE_UD_SEND_ONLY:
339 header->immediate_present = 0;
340 break;
341 case IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE:
342 header->immediate_present = 1;
343 break;
344 default:
345 printk(KERN_WARNING "Invalid BTH.opcode 0x%02x\n",
346 header->bth.opcode);
347 return -EINVAL;
348 }
349
350 if (header->bth.transport_header_version != 0) {
351 printk(KERN_WARNING "Invalid BTH.transport_header_version %d\n",
352 header->bth.transport_header_version);
353 return -EINVAL;
354 }
355
356 ib_unpack(deth_table, ARRAY_SIZE(deth_table),
357 buf, &header->deth);
358 buf += IB_DETH_BYTES;
359
360 if (header->immediate_present)
361 memcpy(&header->immediate_data, buf, sizeof header->immediate_data);
362
363 return 0;
364}
365EXPORT_SYMBOL(ib_ud_header_unpack);
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
new file mode 100644
index 000000000000..54b4f33b0bf9
--- /dev/null
+++ b/drivers/infiniband/core/user_mad.c
@@ -0,0 +1,840 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: user_mad.c 1389 2004-12-27 22:56:47Z roland $
33 */
34
35#include <linux/module.h>
36#include <linux/init.h>
37#include <linux/device.h>
38#include <linux/err.h>
39#include <linux/fs.h>
40#include <linux/cdev.h>
41#include <linux/pci.h>
42#include <linux/dma-mapping.h>
43#include <linux/poll.h>
44#include <linux/rwsem.h>
45#include <linux/kref.h>
46
47#include <asm/uaccess.h>
48#include <asm/semaphore.h>
49
50#include <ib_mad.h>
51#include <ib_user_mad.h>
52
53MODULE_AUTHOR("Roland Dreier");
54MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
55MODULE_LICENSE("Dual BSD/GPL");
56
57enum {
58 IB_UMAD_MAX_PORTS = 64,
59 IB_UMAD_MAX_AGENTS = 32,
60
61 IB_UMAD_MAJOR = 231,
62 IB_UMAD_MINOR_BASE = 0
63};
64
65struct ib_umad_port {
66 int devnum;
67 struct cdev dev;
68 struct class_device class_dev;
69
70 int sm_devnum;
71 struct cdev sm_dev;
72 struct class_device sm_class_dev;
73 struct semaphore sm_sem;
74
75 struct ib_device *ib_dev;
76 struct ib_umad_device *umad_dev;
77 u8 port_num;
78};
79
80struct ib_umad_device {
81 int start_port, end_port;
82 struct kref ref;
83 struct ib_umad_port port[0];
84};
85
86struct ib_umad_file {
87 struct ib_umad_port *port;
88 spinlock_t recv_lock;
89 struct list_head recv_list;
90 wait_queue_head_t recv_wait;
91 struct rw_semaphore agent_mutex;
92 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
93 struct ib_mr *mr[IB_UMAD_MAX_AGENTS];
94};
95
96struct ib_umad_packet {
97 struct ib_user_mad mad;
98 struct ib_ah *ah;
99 struct list_head list;
100 DECLARE_PCI_UNMAP_ADDR(mapping)
101};
102
103static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
104static spinlock_t map_lock;
105static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2);
106
107static void ib_umad_add_one(struct ib_device *device);
108static void ib_umad_remove_one(struct ib_device *device);
109
110static int queue_packet(struct ib_umad_file *file,
111 struct ib_mad_agent *agent,
112 struct ib_umad_packet *packet)
113{
114 int ret = 1;
115
116 down_read(&file->agent_mutex);
117 for (packet->mad.id = 0;
118 packet->mad.id < IB_UMAD_MAX_AGENTS;
119 packet->mad.id++)
120 if (agent == file->agent[packet->mad.id]) {
121 spin_lock_irq(&file->recv_lock);
122 list_add_tail(&packet->list, &file->recv_list);
123 spin_unlock_irq(&file->recv_lock);
124 wake_up_interruptible(&file->recv_wait);
125 ret = 0;
126 break;
127 }
128
129 up_read(&file->agent_mutex);
130
131 return ret;
132}
133
134static void send_handler(struct ib_mad_agent *agent,
135 struct ib_mad_send_wc *send_wc)
136{
137 struct ib_umad_file *file = agent->context;
138 struct ib_umad_packet *packet =
139 (void *) (unsigned long) send_wc->wr_id;
140
141 dma_unmap_single(agent->device->dma_device,
142 pci_unmap_addr(packet, mapping),
143 sizeof packet->mad.data,
144 DMA_TO_DEVICE);
145 ib_destroy_ah(packet->ah);
146
147 if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
148 packet->mad.status = ETIMEDOUT;
149
150 if (!queue_packet(file, agent, packet))
151 return;
152 }
153
154 kfree(packet);
155}
156
157static void recv_handler(struct ib_mad_agent *agent,
158 struct ib_mad_recv_wc *mad_recv_wc)
159{
160 struct ib_umad_file *file = agent->context;
161 struct ib_umad_packet *packet;
162
163 if (mad_recv_wc->wc->status != IB_WC_SUCCESS)
164 goto out;
165
166 packet = kmalloc(sizeof *packet, GFP_KERNEL);
167 if (!packet)
168 goto out;
169
170 memset(packet, 0, sizeof *packet);
171
172 memcpy(packet->mad.data, mad_recv_wc->recv_buf.mad, sizeof packet->mad.data);
173 packet->mad.status = 0;
174 packet->mad.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp);
175 packet->mad.lid = cpu_to_be16(mad_recv_wc->wc->slid);
176 packet->mad.sl = mad_recv_wc->wc->sl;
177 packet->mad.path_bits = mad_recv_wc->wc->dlid_path_bits;
178 packet->mad.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH);
179 if (packet->mad.grh_present) {
180 /* XXX parse GRH */
181 packet->mad.gid_index = 0;
182 packet->mad.hop_limit = 0;
183 packet->mad.traffic_class = 0;
184 memset(packet->mad.gid, 0, 16);
185 packet->mad.flow_label = 0;
186 }
187
188 if (queue_packet(file, agent, packet))
189 kfree(packet);
190
191out:
192 ib_free_recv_mad(mad_recv_wc);
193}
194
195static ssize_t ib_umad_read(struct file *filp, char __user *buf,
196 size_t count, loff_t *pos)
197{
198 struct ib_umad_file *file = filp->private_data;
199 struct ib_umad_packet *packet;
200 ssize_t ret;
201
202 if (count < sizeof (struct ib_user_mad))
203 return -EINVAL;
204
205 spin_lock_irq(&file->recv_lock);
206
207 while (list_empty(&file->recv_list)) {
208 spin_unlock_irq(&file->recv_lock);
209
210 if (filp->f_flags & O_NONBLOCK)
211 return -EAGAIN;
212
213 if (wait_event_interruptible(file->recv_wait,
214 !list_empty(&file->recv_list)))
215 return -ERESTARTSYS;
216
217 spin_lock_irq(&file->recv_lock);
218 }
219
220 packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
221 list_del(&packet->list);
222
223 spin_unlock_irq(&file->recv_lock);
224
225 if (copy_to_user(buf, &packet->mad, sizeof packet->mad))
226 ret = -EFAULT;
227 else
228 ret = sizeof packet->mad;
229
230 kfree(packet);
231 return ret;
232}
233
234static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
235 size_t count, loff_t *pos)
236{
237 struct ib_umad_file *file = filp->private_data;
238 struct ib_umad_packet *packet;
239 struct ib_mad_agent *agent;
240 struct ib_ah_attr ah_attr;
241 struct ib_sge gather_list;
242 struct ib_send_wr *bad_wr, wr = {
243 .opcode = IB_WR_SEND,
244 .sg_list = &gather_list,
245 .num_sge = 1,
246 .send_flags = IB_SEND_SIGNALED,
247 };
248 u8 method;
249 u64 *tid;
250 int ret;
251
252 if (count < sizeof (struct ib_user_mad))
253 return -EINVAL;
254
255 packet = kmalloc(sizeof *packet, GFP_KERNEL);
256 if (!packet)
257 return -ENOMEM;
258
259 if (copy_from_user(&packet->mad, buf, sizeof packet->mad)) {
260 kfree(packet);
261 return -EFAULT;
262 }
263
264 if (packet->mad.id < 0 || packet->mad.id >= IB_UMAD_MAX_AGENTS) {
265 ret = -EINVAL;
266 goto err;
267 }
268
269 down_read(&file->agent_mutex);
270
271 agent = file->agent[packet->mad.id];
272 if (!agent) {
273 ret = -EINVAL;
274 goto err_up;
275 }
276
277 /*
278 * If userspace is generating a request that will generate a
279 * response, we need to make sure the high-order part of the
280 * transaction ID matches the agent being used to send the
281 * MAD.
282 */
283 method = ((struct ib_mad_hdr *) packet->mad.data)->method;
284
285 if (!(method & IB_MGMT_METHOD_RESP) &&
286 method != IB_MGMT_METHOD_TRAP_REPRESS &&
287 method != IB_MGMT_METHOD_SEND) {
288 tid = &((struct ib_mad_hdr *) packet->mad.data)->tid;
289 *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
290 (be64_to_cpup(tid) & 0xffffffff));
291 }
292
293 memset(&ah_attr, 0, sizeof ah_attr);
294 ah_attr.dlid = be16_to_cpu(packet->mad.lid);
295 ah_attr.sl = packet->mad.sl;
296 ah_attr.src_path_bits = packet->mad.path_bits;
297 ah_attr.port_num = file->port->port_num;
298 if (packet->mad.grh_present) {
299 ah_attr.ah_flags = IB_AH_GRH;
300 memcpy(ah_attr.grh.dgid.raw, packet->mad.gid, 16);
301 ah_attr.grh.flow_label = packet->mad.flow_label;
302 ah_attr.grh.hop_limit = packet->mad.hop_limit;
303 ah_attr.grh.traffic_class = packet->mad.traffic_class;
304 }
305
306 packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
307 if (IS_ERR(packet->ah)) {
308 ret = PTR_ERR(packet->ah);
309 goto err_up;
310 }
311
312 gather_list.addr = dma_map_single(agent->device->dma_device,
313 packet->mad.data,
314 sizeof packet->mad.data,
315 DMA_TO_DEVICE);
316 gather_list.length = sizeof packet->mad.data;
317 gather_list.lkey = file->mr[packet->mad.id]->lkey;
318 pci_unmap_addr_set(packet, mapping, gather_list.addr);
319
320 wr.wr.ud.mad_hdr = (struct ib_mad_hdr *) packet->mad.data;
321 wr.wr.ud.ah = packet->ah;
322 wr.wr.ud.remote_qpn = be32_to_cpu(packet->mad.qpn);
323 wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey);
324 wr.wr.ud.timeout_ms = packet->mad.timeout_ms;
325
326 wr.wr_id = (unsigned long) packet;
327
328 ret = ib_post_send_mad(agent, &wr, &bad_wr);
329 if (ret) {
330 dma_unmap_single(agent->device->dma_device,
331 pci_unmap_addr(packet, mapping),
332 sizeof packet->mad.data,
333 DMA_TO_DEVICE);
334 goto err_up;
335 }
336
337 up_read(&file->agent_mutex);
338
339 return sizeof packet->mad;
340
341err_up:
342 up_read(&file->agent_mutex);
343
344err:
345 kfree(packet);
346 return ret;
347}
348
349static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wait)
350{
351 struct ib_umad_file *file = filp->private_data;
352
353 /* we will always be able to post a MAD send */
354 unsigned int mask = POLLOUT | POLLWRNORM;
355
356 poll_wait(filp, &file->recv_wait, wait);
357
358 if (!list_empty(&file->recv_list))
359 mask |= POLLIN | POLLRDNORM;
360
361 return mask;
362}
363
364static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
365{
366 struct ib_user_mad_reg_req ureq;
367 struct ib_mad_reg_req req;
368 struct ib_mad_agent *agent;
369 int agent_id;
370 int ret;
371
372 down_write(&file->agent_mutex);
373
374 if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) {
375 ret = -EFAULT;
376 goto out;
377 }
378
379 if (ureq.qpn != 0 && ureq.qpn != 1) {
380 ret = -EINVAL;
381 goto out;
382 }
383
384 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
385 if (!file->agent[agent_id])
386 goto found;
387
388 ret = -ENOMEM;
389 goto out;
390
391found:
392 req.mgmt_class = ureq.mgmt_class;
393 req.mgmt_class_version = ureq.mgmt_class_version;
394 memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask);
395 memcpy(req.oui, ureq.oui, sizeof req.oui);
396
397 agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
398 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
399 &req, 0, send_handler, recv_handler,
400 file);
401 if (IS_ERR(agent)) {
402 ret = PTR_ERR(agent);
403 goto out;
404 }
405
406 file->agent[agent_id] = agent;
407
408 file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
409 if (IS_ERR(file->mr[agent_id])) {
410 ret = -ENOMEM;
411 goto err;
412 }
413
414 if (put_user(agent_id,
415 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
416 ret = -EFAULT;
417 goto err_mr;
418 }
419
420 ret = 0;
421 goto out;
422
423err_mr:
424 ib_dereg_mr(file->mr[agent_id]);
425
426err:
427 file->agent[agent_id] = NULL;
428 ib_unregister_mad_agent(agent);
429
430out:
431 up_write(&file->agent_mutex);
432 return ret;
433}
434
435static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
436{
437 u32 id;
438 int ret = 0;
439
440 down_write(&file->agent_mutex);
441
442 if (get_user(id, (u32 __user *) arg)) {
443 ret = -EFAULT;
444 goto out;
445 }
446
447 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) {
448 ret = -EINVAL;
449 goto out;
450 }
451
452 ib_dereg_mr(file->mr[id]);
453 ib_unregister_mad_agent(file->agent[id]);
454 file->agent[id] = NULL;
455
456out:
457 up_write(&file->agent_mutex);
458 return ret;
459}
460
461static long ib_umad_ioctl(struct file *filp,
462 unsigned int cmd, unsigned long arg)
463{
464 switch (cmd) {
465 case IB_USER_MAD_REGISTER_AGENT:
466 return ib_umad_reg_agent(filp->private_data, arg);
467 case IB_USER_MAD_UNREGISTER_AGENT:
468 return ib_umad_unreg_agent(filp->private_data, arg);
469 default:
470 return -ENOIOCTLCMD;
471 }
472}
473
474static int ib_umad_open(struct inode *inode, struct file *filp)
475{
476 struct ib_umad_port *port =
477 container_of(inode->i_cdev, struct ib_umad_port, dev);
478 struct ib_umad_file *file;
479
480 file = kmalloc(sizeof *file, GFP_KERNEL);
481 if (!file)
482 return -ENOMEM;
483
484 memset(file, 0, sizeof *file);
485
486 spin_lock_init(&file->recv_lock);
487 init_rwsem(&file->agent_mutex);
488 INIT_LIST_HEAD(&file->recv_list);
489 init_waitqueue_head(&file->recv_wait);
490
491 file->port = port;
492 filp->private_data = file;
493
494 return 0;
495}
496
497static int ib_umad_close(struct inode *inode, struct file *filp)
498{
499 struct ib_umad_file *file = filp->private_data;
500 int i;
501
502 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
503 if (file->agent[i]) {
504 ib_dereg_mr(file->mr[i]);
505 ib_unregister_mad_agent(file->agent[i]);
506 }
507
508 kfree(file);
509
510 return 0;
511}
512
513static struct file_operations umad_fops = {
514 .owner = THIS_MODULE,
515 .read = ib_umad_read,
516 .write = ib_umad_write,
517 .poll = ib_umad_poll,
518 .unlocked_ioctl = ib_umad_ioctl,
519 .compat_ioctl = ib_umad_ioctl,
520 .open = ib_umad_open,
521 .release = ib_umad_close
522};
523
524static int ib_umad_sm_open(struct inode *inode, struct file *filp)
525{
526 struct ib_umad_port *port =
527 container_of(inode->i_cdev, struct ib_umad_port, sm_dev);
528 struct ib_port_modify props = {
529 .set_port_cap_mask = IB_PORT_SM
530 };
531 int ret;
532
533 if (filp->f_flags & O_NONBLOCK) {
534 if (down_trylock(&port->sm_sem))
535 return -EAGAIN;
536 } else {
537 if (down_interruptible(&port->sm_sem))
538 return -ERESTARTSYS;
539 }
540
541 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
542 if (ret) {
543 up(&port->sm_sem);
544 return ret;
545 }
546
547 filp->private_data = port;
548
549 return 0;
550}
551
552static int ib_umad_sm_close(struct inode *inode, struct file *filp)
553{
554 struct ib_umad_port *port = filp->private_data;
555 struct ib_port_modify props = {
556 .clr_port_cap_mask = IB_PORT_SM
557 };
558 int ret;
559
560 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
561 up(&port->sm_sem);
562
563 return ret;
564}
565
566static struct file_operations umad_sm_fops = {
567 .owner = THIS_MODULE,
568 .open = ib_umad_sm_open,
569 .release = ib_umad_sm_close
570};
571
572static struct ib_client umad_client = {
573 .name = "umad",
574 .add = ib_umad_add_one,
575 .remove = ib_umad_remove_one
576};
577
578static ssize_t show_dev(struct class_device *class_dev, char *buf)
579{
580 struct ib_umad_port *port = class_get_devdata(class_dev);
581
582 if (class_dev == &port->class_dev)
583 return print_dev_t(buf, port->dev.dev);
584 else
585 return print_dev_t(buf, port->sm_dev.dev);
586}
587static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
588
589static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
590{
591 struct ib_umad_port *port = class_get_devdata(class_dev);
592
593 return sprintf(buf, "%s\n", port->ib_dev->name);
594}
595static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
596
597static ssize_t show_port(struct class_device *class_dev, char *buf)
598{
599 struct ib_umad_port *port = class_get_devdata(class_dev);
600
601 return sprintf(buf, "%d\n", port->port_num);
602}
603static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
604
605static void ib_umad_release_dev(struct kref *ref)
606{
607 struct ib_umad_device *dev =
608 container_of(ref, struct ib_umad_device, ref);
609
610 kfree(dev);
611}
612
613static void ib_umad_release_port(struct class_device *class_dev)
614{
615 struct ib_umad_port *port = class_get_devdata(class_dev);
616
617 if (class_dev == &port->class_dev) {
618 cdev_del(&port->dev);
619 clear_bit(port->devnum, dev_map);
620 } else {
621 cdev_del(&port->sm_dev);
622 clear_bit(port->sm_devnum, dev_map);
623 }
624
625 kref_put(&port->umad_dev->ref, ib_umad_release_dev);
626}
627
628static struct class umad_class = {
629 .name = "infiniband_mad",
630 .release = ib_umad_release_port
631};
632
633static ssize_t show_abi_version(struct class *class, char *buf)
634{
635 return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
636}
637static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
638
639static int ib_umad_init_port(struct ib_device *device, int port_num,
640 struct ib_umad_port *port)
641{
642 spin_lock(&map_lock);
643 port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
644 if (port->devnum >= IB_UMAD_MAX_PORTS) {
645 spin_unlock(&map_lock);
646 return -1;
647 }
648 port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS);
649 if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) {
650 spin_unlock(&map_lock);
651 return -1;
652 }
653 set_bit(port->devnum, dev_map);
654 set_bit(port->sm_devnum, dev_map);
655 spin_unlock(&map_lock);
656
657 port->ib_dev = device;
658 port->port_num = port_num;
659 init_MUTEX(&port->sm_sem);
660
661 cdev_init(&port->dev, &umad_fops);
662 port->dev.owner = THIS_MODULE;
663 kobject_set_name(&port->dev.kobj, "umad%d", port->devnum);
664 if (cdev_add(&port->dev, base_dev + port->devnum, 1))
665 return -1;
666
667 port->class_dev.class = &umad_class;
668 port->class_dev.dev = device->dma_device;
669
670 snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum);
671
672 if (class_device_register(&port->class_dev))
673 goto err_cdev;
674
675 class_set_devdata(&port->class_dev, port);
676 kref_get(&port->umad_dev->ref);
677
678 if (class_device_create_file(&port->class_dev, &class_device_attr_dev))
679 goto err_class;
680 if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev))
681 goto err_class;
682 if (class_device_create_file(&port->class_dev, &class_device_attr_port))
683 goto err_class;
684
685 cdev_init(&port->sm_dev, &umad_sm_fops);
686 port->sm_dev.owner = THIS_MODULE;
687 kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
688 if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1))
689 return -1;
690
691 port->sm_class_dev.class = &umad_class;
692 port->sm_class_dev.dev = device->dma_device;
693
694 snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
695
696 if (class_device_register(&port->sm_class_dev))
697 goto err_sm_cdev;
698
699 class_set_devdata(&port->sm_class_dev, port);
700 kref_get(&port->umad_dev->ref);
701
702 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev))
703 goto err_sm_class;
704 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev))
705 goto err_sm_class;
706 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port))
707 goto err_sm_class;
708
709 return 0;
710
711err_sm_class:
712 class_device_unregister(&port->sm_class_dev);
713
714err_sm_cdev:
715 cdev_del(&port->sm_dev);
716
717err_class:
718 class_device_unregister(&port->class_dev);
719
720err_cdev:
721 cdev_del(&port->dev);
722 clear_bit(port->devnum, dev_map);
723
724 return -1;
725}
726
727static void ib_umad_add_one(struct ib_device *device)
728{
729 struct ib_umad_device *umad_dev;
730 int s, e, i;
731
732 if (device->node_type == IB_NODE_SWITCH)
733 s = e = 0;
734 else {
735 s = 1;
736 e = device->phys_port_cnt;
737 }
738
739 umad_dev = kmalloc(sizeof *umad_dev +
740 (e - s + 1) * sizeof (struct ib_umad_port),
741 GFP_KERNEL);
742 if (!umad_dev)
743 return;
744
745 memset(umad_dev, 0, sizeof *umad_dev +
746 (e - s + 1) * sizeof (struct ib_umad_port));
747
748 kref_init(&umad_dev->ref);
749
750 umad_dev->start_port = s;
751 umad_dev->end_port = e;
752
753 for (i = s; i <= e; ++i) {
754 umad_dev->port[i - s].umad_dev = umad_dev;
755
756 if (ib_umad_init_port(device, i, &umad_dev->port[i - s]))
757 goto err;
758 }
759
760 ib_set_client_data(device, &umad_client, umad_dev);
761
762 return;
763
764err:
765 while (--i >= s) {
766 class_device_unregister(&umad_dev->port[i - s].class_dev);
767 class_device_unregister(&umad_dev->port[i - s].sm_class_dev);
768 }
769
770 kref_put(&umad_dev->ref, ib_umad_release_dev);
771}
772
773static void ib_umad_remove_one(struct ib_device *device)
774{
775 struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client);
776 int i;
777
778 if (!umad_dev)
779 return;
780
781 for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) {
782 class_device_unregister(&umad_dev->port[i].class_dev);
783 class_device_unregister(&umad_dev->port[i].sm_class_dev);
784 }
785
786 kref_put(&umad_dev->ref, ib_umad_release_dev);
787}
788
789static int __init ib_umad_init(void)
790{
791 int ret;
792
793 spin_lock_init(&map_lock);
794
795 ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
796 "infiniband_mad");
797 if (ret) {
798 printk(KERN_ERR "user_mad: couldn't register device number\n");
799 goto out;
800 }
801
802 ret = class_register(&umad_class);
803 if (ret) {
804 printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n");
805 goto out_chrdev;
806 }
807
808 ret = class_create_file(&umad_class, &class_attr_abi_version);
809 if (ret) {
810 printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
811 goto out_class;
812 }
813
814 ret = ib_register_client(&umad_client);
815 if (ret) {
816 printk(KERN_ERR "user_mad: couldn't register ib_umad client\n");
817 goto out_class;
818 }
819
820 return 0;
821
822out_class:
823 class_unregister(&umad_class);
824
825out_chrdev:
826 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
827
828out:
829 return ret;
830}
831
832static void __exit ib_umad_cleanup(void)
833{
834 ib_unregister_client(&umad_client);
835 class_unregister(&umad_class);
836 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
837}
838
839module_init(ib_umad_init);
840module_exit(ib_umad_cleanup);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
new file mode 100644
index 000000000000..7c08ed0cd7dd
--- /dev/null
+++ b/drivers/infiniband/core/verbs.c
@@ -0,0 +1,434 @@
1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 * $Id: verbs.c 1349 2004-12-16 21:09:43Z roland $
37 */
38
39#include <linux/errno.h>
40#include <linux/err.h>
41
42#include <ib_verbs.h>
43
44/* Protection domains */
45
46struct ib_pd *ib_alloc_pd(struct ib_device *device)
47{
48 struct ib_pd *pd;
49
50 pd = device->alloc_pd(device);
51
52 if (!IS_ERR(pd)) {
53 pd->device = device;
54 atomic_set(&pd->usecnt, 0);
55 }
56
57 return pd;
58}
59EXPORT_SYMBOL(ib_alloc_pd);
60
61int ib_dealloc_pd(struct ib_pd *pd)
62{
63 if (atomic_read(&pd->usecnt))
64 return -EBUSY;
65
66 return pd->device->dealloc_pd(pd);
67}
68EXPORT_SYMBOL(ib_dealloc_pd);
69
70/* Address handles */
71
72struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
73{
74 struct ib_ah *ah;
75
76 ah = pd->device->create_ah(pd, ah_attr);
77
78 if (!IS_ERR(ah)) {
79 ah->device = pd->device;
80 ah->pd = pd;
81 atomic_inc(&pd->usecnt);
82 }
83
84 return ah;
85}
86EXPORT_SYMBOL(ib_create_ah);
87
88int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
89{
90 return ah->device->modify_ah ?
91 ah->device->modify_ah(ah, ah_attr) :
92 -ENOSYS;
93}
94EXPORT_SYMBOL(ib_modify_ah);
95
96int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
97{
98 return ah->device->query_ah ?
99 ah->device->query_ah(ah, ah_attr) :
100 -ENOSYS;
101}
102EXPORT_SYMBOL(ib_query_ah);
103
104int ib_destroy_ah(struct ib_ah *ah)
105{
106 struct ib_pd *pd;
107 int ret;
108
109 pd = ah->pd;
110 ret = ah->device->destroy_ah(ah);
111 if (!ret)
112 atomic_dec(&pd->usecnt);
113
114 return ret;
115}
116EXPORT_SYMBOL(ib_destroy_ah);
117
118/* Queue pairs */
119
120struct ib_qp *ib_create_qp(struct ib_pd *pd,
121 struct ib_qp_init_attr *qp_init_attr)
122{
123 struct ib_qp *qp;
124
125 qp = pd->device->create_qp(pd, qp_init_attr);
126
127 if (!IS_ERR(qp)) {
128 qp->device = pd->device;
129 qp->pd = pd;
130 qp->send_cq = qp_init_attr->send_cq;
131 qp->recv_cq = qp_init_attr->recv_cq;
132 qp->srq = qp_init_attr->srq;
133 qp->event_handler = qp_init_attr->event_handler;
134 qp->qp_context = qp_init_attr->qp_context;
135 qp->qp_type = qp_init_attr->qp_type;
136 atomic_inc(&pd->usecnt);
137 atomic_inc(&qp_init_attr->send_cq->usecnt);
138 atomic_inc(&qp_init_attr->recv_cq->usecnt);
139 if (qp_init_attr->srq)
140 atomic_inc(&qp_init_attr->srq->usecnt);
141 }
142
143 return qp;
144}
145EXPORT_SYMBOL(ib_create_qp);
146
147int ib_modify_qp(struct ib_qp *qp,
148 struct ib_qp_attr *qp_attr,
149 int qp_attr_mask)
150{
151 return qp->device->modify_qp(qp, qp_attr, qp_attr_mask);
152}
153EXPORT_SYMBOL(ib_modify_qp);
154
155int ib_query_qp(struct ib_qp *qp,
156 struct ib_qp_attr *qp_attr,
157 int qp_attr_mask,
158 struct ib_qp_init_attr *qp_init_attr)
159{
160 return qp->device->query_qp ?
161 qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
162 -ENOSYS;
163}
164EXPORT_SYMBOL(ib_query_qp);
165
166int ib_destroy_qp(struct ib_qp *qp)
167{
168 struct ib_pd *pd;
169 struct ib_cq *scq, *rcq;
170 struct ib_srq *srq;
171 int ret;
172
173 pd = qp->pd;
174 scq = qp->send_cq;
175 rcq = qp->recv_cq;
176 srq = qp->srq;
177
178 ret = qp->device->destroy_qp(qp);
179 if (!ret) {
180 atomic_dec(&pd->usecnt);
181 atomic_dec(&scq->usecnt);
182 atomic_dec(&rcq->usecnt);
183 if (srq)
184 atomic_dec(&srq->usecnt);
185 }
186
187 return ret;
188}
189EXPORT_SYMBOL(ib_destroy_qp);
190
191/* Completion queues */
192
193struct ib_cq *ib_create_cq(struct ib_device *device,
194 ib_comp_handler comp_handler,
195 void (*event_handler)(struct ib_event *, void *),
196 void *cq_context, int cqe)
197{
198 struct ib_cq *cq;
199
200 cq = device->create_cq(device, cqe);
201
202 if (!IS_ERR(cq)) {
203 cq->device = device;
204 cq->comp_handler = comp_handler;
205 cq->event_handler = event_handler;
206 cq->cq_context = cq_context;
207 atomic_set(&cq->usecnt, 0);
208 }
209
210 return cq;
211}
212EXPORT_SYMBOL(ib_create_cq);
213
214int ib_destroy_cq(struct ib_cq *cq)
215{
216 if (atomic_read(&cq->usecnt))
217 return -EBUSY;
218
219 return cq->device->destroy_cq(cq);
220}
221EXPORT_SYMBOL(ib_destroy_cq);
222
223int ib_resize_cq(struct ib_cq *cq,
224 int cqe)
225{
226 int ret;
227
228 if (!cq->device->resize_cq)
229 return -ENOSYS;
230
231 ret = cq->device->resize_cq(cq, &cqe);
232 if (!ret)
233 cq->cqe = cqe;
234
235 return ret;
236}
237EXPORT_SYMBOL(ib_resize_cq);
238
239/* Memory regions */
240
241struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
242{
243 struct ib_mr *mr;
244
245 mr = pd->device->get_dma_mr(pd, mr_access_flags);
246
247 if (!IS_ERR(mr)) {
248 mr->device = pd->device;
249 mr->pd = pd;
250 atomic_inc(&pd->usecnt);
251 atomic_set(&mr->usecnt, 0);
252 }
253
254 return mr;
255}
256EXPORT_SYMBOL(ib_get_dma_mr);
257
258struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
259 struct ib_phys_buf *phys_buf_array,
260 int num_phys_buf,
261 int mr_access_flags,
262 u64 *iova_start)
263{
264 struct ib_mr *mr;
265
266 mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
267 mr_access_flags, iova_start);
268
269 if (!IS_ERR(mr)) {
270 mr->device = pd->device;
271 mr->pd = pd;
272 atomic_inc(&pd->usecnt);
273 atomic_set(&mr->usecnt, 0);
274 }
275
276 return mr;
277}
278EXPORT_SYMBOL(ib_reg_phys_mr);
279
280int ib_rereg_phys_mr(struct ib_mr *mr,
281 int mr_rereg_mask,
282 struct ib_pd *pd,
283 struct ib_phys_buf *phys_buf_array,
284 int num_phys_buf,
285 int mr_access_flags,
286 u64 *iova_start)
287{
288 struct ib_pd *old_pd;
289 int ret;
290
291 if (!mr->device->rereg_phys_mr)
292 return -ENOSYS;
293
294 if (atomic_read(&mr->usecnt))
295 return -EBUSY;
296
297 old_pd = mr->pd;
298
299 ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
300 phys_buf_array, num_phys_buf,
301 mr_access_flags, iova_start);
302
303 if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
304 atomic_dec(&old_pd->usecnt);
305 atomic_inc(&pd->usecnt);
306 }
307
308 return ret;
309}
310EXPORT_SYMBOL(ib_rereg_phys_mr);
311
312int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
313{
314 return mr->device->query_mr ?
315 mr->device->query_mr(mr, mr_attr) : -ENOSYS;
316}
317EXPORT_SYMBOL(ib_query_mr);
318
319int ib_dereg_mr(struct ib_mr *mr)
320{
321 struct ib_pd *pd;
322 int ret;
323
324 if (atomic_read(&mr->usecnt))
325 return -EBUSY;
326
327 pd = mr->pd;
328 ret = mr->device->dereg_mr(mr);
329 if (!ret)
330 atomic_dec(&pd->usecnt);
331
332 return ret;
333}
334EXPORT_SYMBOL(ib_dereg_mr);
335
336/* Memory windows */
337
338struct ib_mw *ib_alloc_mw(struct ib_pd *pd)
339{
340 struct ib_mw *mw;
341
342 if (!pd->device->alloc_mw)
343 return ERR_PTR(-ENOSYS);
344
345 mw = pd->device->alloc_mw(pd);
346 if (!IS_ERR(mw)) {
347 mw->device = pd->device;
348 mw->pd = pd;
349 atomic_inc(&pd->usecnt);
350 }
351
352 return mw;
353}
354EXPORT_SYMBOL(ib_alloc_mw);
355
356int ib_dealloc_mw(struct ib_mw *mw)
357{
358 struct ib_pd *pd;
359 int ret;
360
361 pd = mw->pd;
362 ret = mw->device->dealloc_mw(mw);
363 if (!ret)
364 atomic_dec(&pd->usecnt);
365
366 return ret;
367}
368EXPORT_SYMBOL(ib_dealloc_mw);
369
370/* "Fast" memory regions */
371
372struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
373 int mr_access_flags,
374 struct ib_fmr_attr *fmr_attr)
375{
376 struct ib_fmr *fmr;
377
378 if (!pd->device->alloc_fmr)
379 return ERR_PTR(-ENOSYS);
380
381 fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
382 if (!IS_ERR(fmr)) {
383 fmr->device = pd->device;
384 fmr->pd = pd;
385 atomic_inc(&pd->usecnt);
386 }
387
388 return fmr;
389}
390EXPORT_SYMBOL(ib_alloc_fmr);
391
392int ib_unmap_fmr(struct list_head *fmr_list)
393{
394 struct ib_fmr *fmr;
395
396 if (list_empty(fmr_list))
397 return 0;
398
399 fmr = list_entry(fmr_list->next, struct ib_fmr, list);
400 return fmr->device->unmap_fmr(fmr_list);
401}
402EXPORT_SYMBOL(ib_unmap_fmr);
403
404int ib_dealloc_fmr(struct ib_fmr *fmr)
405{
406 struct ib_pd *pd;
407 int ret;
408
409 pd = fmr->pd;
410 ret = fmr->device->dealloc_fmr(fmr);
411 if (!ret)
412 atomic_dec(&pd->usecnt);
413
414 return ret;
415}
416EXPORT_SYMBOL(ib_dealloc_fmr);
417
418/* Multicast groups */
419
420int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
421{
422 return qp->device->attach_mcast ?
423 qp->device->attach_mcast(qp, gid, lid) :
424 -ENOSYS;
425}
426EXPORT_SYMBOL(ib_attach_mcast);
427
428int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
429{
430 return qp->device->detach_mcast ?
431 qp->device->detach_mcast(qp, gid, lid) :
432 -ENOSYS;
433}
434EXPORT_SYMBOL(ib_detach_mcast);