xref: /linux/drivers/infiniband/core/sa_query.c (revision 13abf8130139c2ccd4962a7e5a8902be5e6cb5a7)
1 /*
2  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  *
33  * $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $
34  */
35 
36 #include <linux/module.h>
37 #include <linux/init.h>
38 #include <linux/err.h>
39 #include <linux/random.h>
40 #include <linux/spinlock.h>
41 #include <linux/slab.h>
42 #include <linux/pci.h>
43 #include <linux/dma-mapping.h>
44 #include <linux/kref.h>
45 #include <linux/idr.h>
46 
47 #include <rdma/ib_pack.h>
48 #include <rdma/ib_sa.h>
49 
50 MODULE_AUTHOR("Roland Dreier");
51 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
52 MODULE_LICENSE("Dual BSD/GPL");
53 
54 struct ib_sa_sm_ah {
55 	struct ib_ah        *ah;
56 	struct kref          ref;
57 };
58 
59 struct ib_sa_port {
60 	struct ib_mad_agent *agent;
61 	struct ib_sa_sm_ah  *sm_ah;
62 	struct work_struct   update_task;
63 	spinlock_t           ah_lock;
64 	u8                   port_num;
65 };
66 
67 struct ib_sa_device {
68 	int                     start_port, end_port;
69 	struct ib_event_handler event_handler;
70 	struct ib_sa_port port[0];
71 };
72 
73 struct ib_sa_query {
74 	void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
75 	void (*release)(struct ib_sa_query *);
76 	struct ib_sa_port  *port;
77 	struct ib_sa_mad   *mad;
78 	struct ib_sa_sm_ah *sm_ah;
79 	DECLARE_PCI_UNMAP_ADDR(mapping)
80 	int                 id;
81 };
82 
83 struct ib_sa_service_query {
84 	void (*callback)(int, struct ib_sa_service_rec *, void *);
85 	void *context;
86 	struct ib_sa_query sa_query;
87 };
88 
89 struct ib_sa_path_query {
90 	void (*callback)(int, struct ib_sa_path_rec *, void *);
91 	void *context;
92 	struct ib_sa_query sa_query;
93 };
94 
95 struct ib_sa_mcmember_query {
96 	void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
97 	void *context;
98 	struct ib_sa_query sa_query;
99 };
100 
101 static void ib_sa_add_one(struct ib_device *device);
102 static void ib_sa_remove_one(struct ib_device *device);
103 
104 static struct ib_client sa_client = {
105 	.name   = "sa",
106 	.add    = ib_sa_add_one,
107 	.remove = ib_sa_remove_one
108 };
109 
110 static spinlock_t idr_lock;
111 static DEFINE_IDR(query_idr);
112 
113 static spinlock_t tid_lock;
114 static u32 tid;
115 
116 enum {
117 	IB_SA_ATTR_CLASS_PORTINFO    = 0x01,
118 	IB_SA_ATTR_NOTICE	     = 0x02,
119 	IB_SA_ATTR_INFORM_INFO	     = 0x03,
120 	IB_SA_ATTR_NODE_REC	     = 0x11,
121 	IB_SA_ATTR_PORT_INFO_REC     = 0x12,
122 	IB_SA_ATTR_SL2VL_REC	     = 0x13,
123 	IB_SA_ATTR_SWITCH_REC	     = 0x14,
124 	IB_SA_ATTR_LINEAR_FDB_REC    = 0x15,
125 	IB_SA_ATTR_RANDOM_FDB_REC    = 0x16,
126 	IB_SA_ATTR_MCAST_FDB_REC     = 0x17,
127 	IB_SA_ATTR_SM_INFO_REC	     = 0x18,
128 	IB_SA_ATTR_LINK_REC	     = 0x20,
129 	IB_SA_ATTR_GUID_INFO_REC     = 0x30,
130 	IB_SA_ATTR_SERVICE_REC	     = 0x31,
131 	IB_SA_ATTR_PARTITION_REC     = 0x33,
132 	IB_SA_ATTR_RANGE_REC	     = 0x34,
133 	IB_SA_ATTR_PATH_REC	     = 0x35,
134 	IB_SA_ATTR_VL_ARB_REC	     = 0x36,
135 	IB_SA_ATTR_MC_GROUP_REC	     = 0x37,
136 	IB_SA_ATTR_MC_MEMBER_REC     = 0x38,
137 	IB_SA_ATTR_TRACE_REC	     = 0x39,
138 	IB_SA_ATTR_MULTI_PATH_REC    = 0x3a,
139 	IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b
140 };
141 
142 #define PATH_REC_FIELD(field) \
143 	.struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),		\
144 	.struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,	\
145 	.field_name          = "sa_path_rec:" #field
146 
147 static const struct ib_field path_rec_table[] = {
148 	{ RESERVED,
149 	  .offset_words = 0,
150 	  .offset_bits  = 0,
151 	  .size_bits    = 32 },
152 	{ RESERVED,
153 	  .offset_words = 1,
154 	  .offset_bits  = 0,
155 	  .size_bits    = 32 },
156 	{ PATH_REC_FIELD(dgid),
157 	  .offset_words = 2,
158 	  .offset_bits  = 0,
159 	  .size_bits    = 128 },
160 	{ PATH_REC_FIELD(sgid),
161 	  .offset_words = 6,
162 	  .offset_bits  = 0,
163 	  .size_bits    = 128 },
164 	{ PATH_REC_FIELD(dlid),
165 	  .offset_words = 10,
166 	  .offset_bits  = 0,
167 	  .size_bits    = 16 },
168 	{ PATH_REC_FIELD(slid),
169 	  .offset_words = 10,
170 	  .offset_bits  = 16,
171 	  .size_bits    = 16 },
172 	{ PATH_REC_FIELD(raw_traffic),
173 	  .offset_words = 11,
174 	  .offset_bits  = 0,
175 	  .size_bits    = 1 },
176 	{ RESERVED,
177 	  .offset_words = 11,
178 	  .offset_bits  = 1,
179 	  .size_bits    = 3 },
180 	{ PATH_REC_FIELD(flow_label),
181 	  .offset_words = 11,
182 	  .offset_bits  = 4,
183 	  .size_bits    = 20 },
184 	{ PATH_REC_FIELD(hop_limit),
185 	  .offset_words = 11,
186 	  .offset_bits  = 24,
187 	  .size_bits    = 8 },
188 	{ PATH_REC_FIELD(traffic_class),
189 	  .offset_words = 12,
190 	  .offset_bits  = 0,
191 	  .size_bits    = 8 },
192 	{ PATH_REC_FIELD(reversible),
193 	  .offset_words = 12,
194 	  .offset_bits  = 8,
195 	  .size_bits    = 1 },
196 	{ PATH_REC_FIELD(numb_path),
197 	  .offset_words = 12,
198 	  .offset_bits  = 9,
199 	  .size_bits    = 7 },
200 	{ PATH_REC_FIELD(pkey),
201 	  .offset_words = 12,
202 	  .offset_bits  = 16,
203 	  .size_bits    = 16 },
204 	{ RESERVED,
205 	  .offset_words = 13,
206 	  .offset_bits  = 0,
207 	  .size_bits    = 12 },
208 	{ PATH_REC_FIELD(sl),
209 	  .offset_words = 13,
210 	  .offset_bits  = 12,
211 	  .size_bits    = 4 },
212 	{ PATH_REC_FIELD(mtu_selector),
213 	  .offset_words = 13,
214 	  .offset_bits  = 16,
215 	  .size_bits    = 2 },
216 	{ PATH_REC_FIELD(mtu),
217 	  .offset_words = 13,
218 	  .offset_bits  = 18,
219 	  .size_bits    = 6 },
220 	{ PATH_REC_FIELD(rate_selector),
221 	  .offset_words = 13,
222 	  .offset_bits  = 24,
223 	  .size_bits    = 2 },
224 	{ PATH_REC_FIELD(rate),
225 	  .offset_words = 13,
226 	  .offset_bits  = 26,
227 	  .size_bits    = 6 },
228 	{ PATH_REC_FIELD(packet_life_time_selector),
229 	  .offset_words = 14,
230 	  .offset_bits  = 0,
231 	  .size_bits    = 2 },
232 	{ PATH_REC_FIELD(packet_life_time),
233 	  .offset_words = 14,
234 	  .offset_bits  = 2,
235 	  .size_bits    = 6 },
236 	{ PATH_REC_FIELD(preference),
237 	  .offset_words = 14,
238 	  .offset_bits  = 8,
239 	  .size_bits    = 8 },
240 	{ RESERVED,
241 	  .offset_words = 14,
242 	  .offset_bits  = 16,
243 	  .size_bits    = 48 },
244 };
245 
246 #define MCMEMBER_REC_FIELD(field) \
247 	.struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field),	\
248 	.struct_size_bytes   = sizeof ((struct ib_sa_mcmember_rec *) 0)->field,	\
249 	.field_name          = "sa_mcmember_rec:" #field
250 
251 static const struct ib_field mcmember_rec_table[] = {
252 	{ MCMEMBER_REC_FIELD(mgid),
253 	  .offset_words = 0,
254 	  .offset_bits  = 0,
255 	  .size_bits    = 128 },
256 	{ MCMEMBER_REC_FIELD(port_gid),
257 	  .offset_words = 4,
258 	  .offset_bits  = 0,
259 	  .size_bits    = 128 },
260 	{ MCMEMBER_REC_FIELD(qkey),
261 	  .offset_words = 8,
262 	  .offset_bits  = 0,
263 	  .size_bits    = 32 },
264 	{ MCMEMBER_REC_FIELD(mlid),
265 	  .offset_words = 9,
266 	  .offset_bits  = 0,
267 	  .size_bits    = 16 },
268 	{ MCMEMBER_REC_FIELD(mtu_selector),
269 	  .offset_words = 9,
270 	  .offset_bits  = 16,
271 	  .size_bits    = 2 },
272 	{ MCMEMBER_REC_FIELD(mtu),
273 	  .offset_words = 9,
274 	  .offset_bits  = 18,
275 	  .size_bits    = 6 },
276 	{ MCMEMBER_REC_FIELD(traffic_class),
277 	  .offset_words = 9,
278 	  .offset_bits  = 24,
279 	  .size_bits    = 8 },
280 	{ MCMEMBER_REC_FIELD(pkey),
281 	  .offset_words = 10,
282 	  .offset_bits  = 0,
283 	  .size_bits    = 16 },
284 	{ MCMEMBER_REC_FIELD(rate_selector),
285 	  .offset_words = 10,
286 	  .offset_bits  = 16,
287 	  .size_bits    = 2 },
288 	{ MCMEMBER_REC_FIELD(rate),
289 	  .offset_words = 10,
290 	  .offset_bits  = 18,
291 	  .size_bits    = 6 },
292 	{ MCMEMBER_REC_FIELD(packet_life_time_selector),
293 	  .offset_words = 10,
294 	  .offset_bits  = 24,
295 	  .size_bits    = 2 },
296 	{ MCMEMBER_REC_FIELD(packet_life_time),
297 	  .offset_words = 10,
298 	  .offset_bits  = 26,
299 	  .size_bits    = 6 },
300 	{ MCMEMBER_REC_FIELD(sl),
301 	  .offset_words = 11,
302 	  .offset_bits  = 0,
303 	  .size_bits    = 4 },
304 	{ MCMEMBER_REC_FIELD(flow_label),
305 	  .offset_words = 11,
306 	  .offset_bits  = 4,
307 	  .size_bits    = 20 },
308 	{ MCMEMBER_REC_FIELD(hop_limit),
309 	  .offset_words = 11,
310 	  .offset_bits  = 24,
311 	  .size_bits    = 8 },
312 	{ MCMEMBER_REC_FIELD(scope),
313 	  .offset_words = 12,
314 	  .offset_bits  = 0,
315 	  .size_bits    = 4 },
316 	{ MCMEMBER_REC_FIELD(join_state),
317 	  .offset_words = 12,
318 	  .offset_bits  = 4,
319 	  .size_bits    = 4 },
320 	{ MCMEMBER_REC_FIELD(proxy_join),
321 	  .offset_words = 12,
322 	  .offset_bits  = 8,
323 	  .size_bits    = 1 },
324 	{ RESERVED,
325 	  .offset_words = 12,
326 	  .offset_bits  = 9,
327 	  .size_bits    = 23 },
328 };
329 
330 #define SERVICE_REC_FIELD(field) \
331 	.struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),	\
332 	.struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,	\
333 	.field_name          = "sa_service_rec:" #field
334 
335 static const struct ib_field service_rec_table[] = {
336 	{ SERVICE_REC_FIELD(id),
337 	  .offset_words = 0,
338 	  .offset_bits  = 0,
339 	  .size_bits    = 64 },
340 	{ SERVICE_REC_FIELD(gid),
341 	  .offset_words = 2,
342 	  .offset_bits  = 0,
343 	  .size_bits    = 128 },
344 	{ SERVICE_REC_FIELD(pkey),
345 	  .offset_words = 6,
346 	  .offset_bits  = 0,
347 	  .size_bits    = 16 },
348 	{ SERVICE_REC_FIELD(lease),
349 	  .offset_words = 7,
350 	  .offset_bits  = 0,
351 	  .size_bits    = 32 },
352 	{ SERVICE_REC_FIELD(key),
353 	  .offset_words = 8,
354 	  .offset_bits  = 0,
355 	  .size_bits    = 128 },
356 	{ SERVICE_REC_FIELD(name),
357 	  .offset_words = 12,
358 	  .offset_bits  = 0,
359 	  .size_bits    = 64*8 },
360 	{ SERVICE_REC_FIELD(data8),
361 	  .offset_words = 28,
362 	  .offset_bits  = 0,
363 	  .size_bits    = 16*8 },
364 	{ SERVICE_REC_FIELD(data16),
365 	  .offset_words = 32,
366 	  .offset_bits  = 0,
367 	  .size_bits    = 8*16 },
368 	{ SERVICE_REC_FIELD(data32),
369 	  .offset_words = 36,
370 	  .offset_bits  = 0,
371 	  .size_bits    = 4*32 },
372 	{ SERVICE_REC_FIELD(data64),
373 	  .offset_words = 40,
374 	  .offset_bits  = 0,
375 	  .size_bits    = 2*64 },
376 };
377 
378 static void free_sm_ah(struct kref *kref)
379 {
380 	struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
381 
382 	ib_destroy_ah(sm_ah->ah);
383 	kfree(sm_ah);
384 }
385 
386 static void update_sm_ah(void *port_ptr)
387 {
388 	struct ib_sa_port *port = port_ptr;
389 	struct ib_sa_sm_ah *new_ah, *old_ah;
390 	struct ib_port_attr port_attr;
391 	struct ib_ah_attr   ah_attr;
392 
393 	if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
394 		printk(KERN_WARNING "Couldn't query port\n");
395 		return;
396 	}
397 
398 	new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
399 	if (!new_ah) {
400 		printk(KERN_WARNING "Couldn't allocate new SM AH\n");
401 		return;
402 	}
403 
404 	kref_init(&new_ah->ref);
405 
406 	memset(&ah_attr, 0, sizeof ah_attr);
407 	ah_attr.dlid     = port_attr.sm_lid;
408 	ah_attr.sl       = port_attr.sm_sl;
409 	ah_attr.port_num = port->port_num;
410 
411 	new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
412 	if (IS_ERR(new_ah->ah)) {
413 		printk(KERN_WARNING "Couldn't create new SM AH\n");
414 		kfree(new_ah);
415 		return;
416 	}
417 
418 	spin_lock_irq(&port->ah_lock);
419 	old_ah = port->sm_ah;
420 	port->sm_ah = new_ah;
421 	spin_unlock_irq(&port->ah_lock);
422 
423 	if (old_ah)
424 		kref_put(&old_ah->ref, free_sm_ah);
425 }
426 
427 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
428 {
429 	if (event->event == IB_EVENT_PORT_ERR    ||
430 	    event->event == IB_EVENT_PORT_ACTIVE ||
431 	    event->event == IB_EVENT_LID_CHANGE  ||
432 	    event->event == IB_EVENT_PKEY_CHANGE ||
433 	    event->event == IB_EVENT_SM_CHANGE) {
434 		struct ib_sa_device *sa_dev =
435 			ib_get_client_data(event->device, &sa_client);
436 
437 		schedule_work(&sa_dev->port[event->element.port_num -
438 					    sa_dev->start_port].update_task);
439 	}
440 }
441 
442 /**
443  * ib_sa_cancel_query - try to cancel an SA query
444  * @id:ID of query to cancel
445  * @query:query pointer to cancel
446  *
447  * Try to cancel an SA query.  If the id and query don't match up or
448  * the query has already completed, nothing is done.  Otherwise the
449  * query is canceled and will complete with a status of -EINTR.
450  */
451 void ib_sa_cancel_query(int id, struct ib_sa_query *query)
452 {
453 	unsigned long flags;
454 	struct ib_mad_agent *agent;
455 
456 	spin_lock_irqsave(&idr_lock, flags);
457 	if (idr_find(&query_idr, id) != query) {
458 		spin_unlock_irqrestore(&idr_lock, flags);
459 		return;
460 	}
461 	agent = query->port->agent;
462 	spin_unlock_irqrestore(&idr_lock, flags);
463 
464 	ib_cancel_mad(agent, id);
465 }
466 EXPORT_SYMBOL(ib_sa_cancel_query);
467 
468 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
469 {
470 	unsigned long flags;
471 
472 	memset(mad, 0, sizeof *mad);
473 
474 	mad->mad_hdr.base_version  = IB_MGMT_BASE_VERSION;
475 	mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_SUBN_ADM;
476 	mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
477 
478 	spin_lock_irqsave(&tid_lock, flags);
479 	mad->mad_hdr.tid           =
480 		cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
481 	spin_unlock_irqrestore(&tid_lock, flags);
482 }
483 
484 static int send_mad(struct ib_sa_query *query, int timeout_ms)
485 {
486 	struct ib_sa_port *port = query->port;
487 	unsigned long flags;
488 	int ret;
489 	struct ib_sge      gather_list;
490 	struct ib_send_wr *bad_wr, wr = {
491 		.opcode      = IB_WR_SEND,
492 		.sg_list     = &gather_list,
493 		.num_sge     = 1,
494 		.send_flags  = IB_SEND_SIGNALED,
495 		.wr	     = {
496 			 .ud = {
497 				 .mad_hdr     = &query->mad->mad_hdr,
498 				 .remote_qpn  = 1,
499 				 .remote_qkey = IB_QP1_QKEY,
500 				 .timeout_ms  = timeout_ms,
501 			 }
502 		 }
503 	};
504 
505 retry:
506 	if (!idr_pre_get(&query_idr, GFP_ATOMIC))
507 		return -ENOMEM;
508 	spin_lock_irqsave(&idr_lock, flags);
509 	ret = idr_get_new(&query_idr, query, &query->id);
510 	spin_unlock_irqrestore(&idr_lock, flags);
511 	if (ret == -EAGAIN)
512 		goto retry;
513 	if (ret)
514 		return ret;
515 
516 	wr.wr_id = query->id;
517 
518 	spin_lock_irqsave(&port->ah_lock, flags);
519 	kref_get(&port->sm_ah->ref);
520 	query->sm_ah = port->sm_ah;
521 	wr.wr.ud.ah  = port->sm_ah->ah;
522 	spin_unlock_irqrestore(&port->ah_lock, flags);
523 
524 	gather_list.addr   = dma_map_single(port->agent->device->dma_device,
525 					    query->mad,
526 					    sizeof (struct ib_sa_mad),
527 					    DMA_TO_DEVICE);
528 	gather_list.length = sizeof (struct ib_sa_mad);
529 	gather_list.lkey   = port->agent->mr->lkey;
530 	pci_unmap_addr_set(query, mapping, gather_list.addr);
531 
532 	ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
533 	if (ret) {
534 		dma_unmap_single(port->agent->device->dma_device,
535 				 pci_unmap_addr(query, mapping),
536 				 sizeof (struct ib_sa_mad),
537 				 DMA_TO_DEVICE);
538 		kref_put(&query->sm_ah->ref, free_sm_ah);
539 		spin_lock_irqsave(&idr_lock, flags);
540 		idr_remove(&query_idr, query->id);
541 		spin_unlock_irqrestore(&idr_lock, flags);
542 	}
543 
544 	/*
545 	 * It's not safe to dereference query any more, because the
546 	 * send may already have completed and freed the query in
547 	 * another context.  So use wr.wr_id, which has a copy of the
548 	 * query's id.
549 	 */
550 	return ret ? ret : wr.wr_id;
551 }
552 
553 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
554 				    int status,
555 				    struct ib_sa_mad *mad)
556 {
557 	struct ib_sa_path_query *query =
558 		container_of(sa_query, struct ib_sa_path_query, sa_query);
559 
560 	if (mad) {
561 		struct ib_sa_path_rec rec;
562 
563 		ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
564 			  mad->data, &rec);
565 		query->callback(status, &rec, query->context);
566 	} else
567 		query->callback(status, NULL, query->context);
568 }
569 
570 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
571 {
572 	kfree(sa_query->mad);
573 	kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
574 }
575 
576 /**
577  * ib_sa_path_rec_get - Start a Path get query
578  * @device:device to send query on
579  * @port_num: port number to send query on
580  * @rec:Path Record to send in query
581  * @comp_mask:component mask to send in query
582  * @timeout_ms:time to wait for response
583  * @gfp_mask:GFP mask to use for internal allocations
584  * @callback:function called when query completes, times out or is
585  * canceled
586  * @context:opaque user context passed to callback
587  * @sa_query:query context, used to cancel query
588  *
589  * Send a Path Record Get query to the SA to look up a path.  The
590  * callback function will be called when the query completes (or
591  * fails); status is 0 for a successful response, -EINTR if the query
592  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
593  * occurred sending the query.  The resp parameter of the callback is
594  * only valid if status is 0.
595  *
596  * If the return value of ib_sa_path_rec_get() is negative, it is an
597  * error code.  Otherwise it is a query ID that can be used to cancel
598  * the query.
599  */
600 int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
601 		       struct ib_sa_path_rec *rec,
602 		       ib_sa_comp_mask comp_mask,
603 		       int timeout_ms, unsigned int __nocast gfp_mask,
604 		       void (*callback)(int status,
605 					struct ib_sa_path_rec *resp,
606 					void *context),
607 		       void *context,
608 		       struct ib_sa_query **sa_query)
609 {
610 	struct ib_sa_path_query *query;
611 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
612 	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
613 	struct ib_mad_agent *agent  = port->agent;
614 	int ret;
615 
616 	query = kmalloc(sizeof *query, gfp_mask);
617 	if (!query)
618 		return -ENOMEM;
619 	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
620 	if (!query->sa_query.mad) {
621 		kfree(query);
622 		return -ENOMEM;
623 	}
624 
625 	query->callback = callback;
626 	query->context  = context;
627 
628 	init_mad(query->sa_query.mad, agent);
629 
630 	query->sa_query.callback              = callback ? ib_sa_path_rec_callback : NULL;
631 	query->sa_query.release               = ib_sa_path_rec_release;
632 	query->sa_query.port                  = port;
633 	query->sa_query.mad->mad_hdr.method   = IB_MGMT_METHOD_GET;
634 	query->sa_query.mad->mad_hdr.attr_id  = cpu_to_be16(IB_SA_ATTR_PATH_REC);
635 	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
636 
637 	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table),
638 		rec, query->sa_query.mad->data);
639 
640 	*sa_query = &query->sa_query;
641 
642 	ret = send_mad(&query->sa_query, timeout_ms);
643 	if (ret < 0) {
644 		*sa_query = NULL;
645 		kfree(query->sa_query.mad);
646 		kfree(query);
647 	}
648 
649 	return ret;
650 }
651 EXPORT_SYMBOL(ib_sa_path_rec_get);
652 
653 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
654 				    int status,
655 				    struct ib_sa_mad *mad)
656 {
657 	struct ib_sa_service_query *query =
658 		container_of(sa_query, struct ib_sa_service_query, sa_query);
659 
660 	if (mad) {
661 		struct ib_sa_service_rec rec;
662 
663 		ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
664 			  mad->data, &rec);
665 		query->callback(status, &rec, query->context);
666 	} else
667 		query->callback(status, NULL, query->context);
668 }
669 
670 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
671 {
672 	kfree(sa_query->mad);
673 	kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
674 }
675 
676 /**
677  * ib_sa_service_rec_query - Start Service Record operation
678  * @device:device to send request on
679  * @port_num: port number to send request on
680  * @method:SA method - should be get, set, or delete
681  * @rec:Service Record to send in request
682  * @comp_mask:component mask to send in request
683  * @timeout_ms:time to wait for response
684  * @gfp_mask:GFP mask to use for internal allocations
685  * @callback:function called when request completes, times out or is
686  * canceled
687  * @context:opaque user context passed to callback
688  * @sa_query:request context, used to cancel request
689  *
690  * Send a Service Record set/get/delete to the SA to register,
691  * unregister or query a service record.
692  * The callback function will be called when the request completes (or
693  * fails); status is 0 for a successful response, -EINTR if the query
694  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
695  * occurred sending the query.  The resp parameter of the callback is
696  * only valid if status is 0.
697  *
698  * If the return value of ib_sa_service_rec_query() is negative, it is an
699  * error code.  Otherwise it is a request ID that can be used to cancel
700  * the query.
701  */
702 int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
703 			    struct ib_sa_service_rec *rec,
704 			    ib_sa_comp_mask comp_mask,
705 			    int timeout_ms, unsigned int __nocast gfp_mask,
706 			    void (*callback)(int status,
707 					     struct ib_sa_service_rec *resp,
708 					     void *context),
709 			    void *context,
710 			    struct ib_sa_query **sa_query)
711 {
712 	struct ib_sa_service_query *query;
713 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
714 	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
715 	struct ib_mad_agent *agent  = port->agent;
716 	int ret;
717 
718 	if (method != IB_MGMT_METHOD_GET &&
719 	    method != IB_MGMT_METHOD_SET &&
720 	    method != IB_SA_METHOD_DELETE)
721 		return -EINVAL;
722 
723 	query = kmalloc(sizeof *query, gfp_mask);
724 	if (!query)
725 		return -ENOMEM;
726 	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
727 	if (!query->sa_query.mad) {
728 		kfree(query);
729 		return -ENOMEM;
730 	}
731 
732 	query->callback = callback;
733 	query->context  = context;
734 
735 	init_mad(query->sa_query.mad, agent);
736 
737 	query->sa_query.callback              = callback ? ib_sa_service_rec_callback : NULL;
738 	query->sa_query.release               = ib_sa_service_rec_release;
739 	query->sa_query.port                  = port;
740 	query->sa_query.mad->mad_hdr.method   = method;
741 	query->sa_query.mad->mad_hdr.attr_id  =
742 				cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
743 	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
744 
745 	ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
746 		rec, query->sa_query.mad->data);
747 
748 	*sa_query = &query->sa_query;
749 
750 	ret = send_mad(&query->sa_query, timeout_ms);
751 	if (ret < 0) {
752 		*sa_query = NULL;
753 		kfree(query->sa_query.mad);
754 		kfree(query);
755 	}
756 
757 	return ret;
758 }
759 EXPORT_SYMBOL(ib_sa_service_rec_query);
760 
761 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
762 					int status,
763 					struct ib_sa_mad *mad)
764 {
765 	struct ib_sa_mcmember_query *query =
766 		container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
767 
768 	if (mad) {
769 		struct ib_sa_mcmember_rec rec;
770 
771 		ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
772 			  mad->data, &rec);
773 		query->callback(status, &rec, query->context);
774 	} else
775 		query->callback(status, NULL, query->context);
776 }
777 
778 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
779 {
780 	kfree(sa_query->mad);
781 	kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
782 }
783 
784 int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
785 			     u8 method,
786 			     struct ib_sa_mcmember_rec *rec,
787 			     ib_sa_comp_mask comp_mask,
788 			     int timeout_ms, unsigned int __nocast gfp_mask,
789 			     void (*callback)(int status,
790 					      struct ib_sa_mcmember_rec *resp,
791 					      void *context),
792 			     void *context,
793 			     struct ib_sa_query **sa_query)
794 {
795 	struct ib_sa_mcmember_query *query;
796 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
797 	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
798 	struct ib_mad_agent *agent  = port->agent;
799 	int ret;
800 
801 	query = kmalloc(sizeof *query, gfp_mask);
802 	if (!query)
803 		return -ENOMEM;
804 	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
805 	if (!query->sa_query.mad) {
806 		kfree(query);
807 		return -ENOMEM;
808 	}
809 
810 	query->callback = callback;
811 	query->context  = context;
812 
813 	init_mad(query->sa_query.mad, agent);
814 
815 	query->sa_query.callback              = callback ? ib_sa_mcmember_rec_callback : NULL;
816 	query->sa_query.release               = ib_sa_mcmember_rec_release;
817 	query->sa_query.port                  = port;
818 	query->sa_query.mad->mad_hdr.method   = method;
819 	query->sa_query.mad->mad_hdr.attr_id  = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
820 	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
821 
822 	ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
823 		rec, query->sa_query.mad->data);
824 
825 	*sa_query = &query->sa_query;
826 
827 	ret = send_mad(&query->sa_query, timeout_ms);
828 	if (ret < 0) {
829 		*sa_query = NULL;
830 		kfree(query->sa_query.mad);
831 		kfree(query);
832 	}
833 
834 	return ret;
835 }
836 EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
837 
838 static void send_handler(struct ib_mad_agent *agent,
839 			 struct ib_mad_send_wc *mad_send_wc)
840 {
841 	struct ib_sa_query *query;
842 	unsigned long flags;
843 
844 	spin_lock_irqsave(&idr_lock, flags);
845 	query = idr_find(&query_idr, mad_send_wc->wr_id);
846 	spin_unlock_irqrestore(&idr_lock, flags);
847 
848 	if (!query)
849 		return;
850 
851 	if (query->callback)
852 		switch (mad_send_wc->status) {
853 		case IB_WC_SUCCESS:
854 			/* No callback -- already got recv */
855 			break;
856 		case IB_WC_RESP_TIMEOUT_ERR:
857 			query->callback(query, -ETIMEDOUT, NULL);
858 			break;
859 		case IB_WC_WR_FLUSH_ERR:
860 			query->callback(query, -EINTR, NULL);
861 			break;
862 		default:
863 			query->callback(query, -EIO, NULL);
864 			break;
865 		}
866 
867 	dma_unmap_single(agent->device->dma_device,
868 			 pci_unmap_addr(query, mapping),
869 			 sizeof (struct ib_sa_mad),
870 			 DMA_TO_DEVICE);
871 	kref_put(&query->sm_ah->ref, free_sm_ah);
872 
873 	query->release(query);
874 
875 	spin_lock_irqsave(&idr_lock, flags);
876 	idr_remove(&query_idr, mad_send_wc->wr_id);
877 	spin_unlock_irqrestore(&idr_lock, flags);
878 }
879 
880 static void recv_handler(struct ib_mad_agent *mad_agent,
881 			 struct ib_mad_recv_wc *mad_recv_wc)
882 {
883 	struct ib_sa_query *query;
884 	unsigned long flags;
885 
886 	spin_lock_irqsave(&idr_lock, flags);
887 	query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
888 	spin_unlock_irqrestore(&idr_lock, flags);
889 
890 	if (query && query->callback) {
891 		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
892 			query->callback(query,
893 					mad_recv_wc->recv_buf.mad->mad_hdr.status ?
894 					-EINVAL : 0,
895 					(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
896 		else
897 			query->callback(query, -EIO, NULL);
898 	}
899 
900 	ib_free_recv_mad(mad_recv_wc);
901 }
902 
903 static void ib_sa_add_one(struct ib_device *device)
904 {
905 	struct ib_sa_device *sa_dev;
906 	int s, e, i;
907 
908 	if (device->node_type == IB_NODE_SWITCH)
909 		s = e = 0;
910 	else {
911 		s = 1;
912 		e = device->phys_port_cnt;
913 	}
914 
915 	sa_dev = kmalloc(sizeof *sa_dev +
916 			 (e - s + 1) * sizeof (struct ib_sa_port),
917 			 GFP_KERNEL);
918 	if (!sa_dev)
919 		return;
920 
921 	sa_dev->start_port = s;
922 	sa_dev->end_port   = e;
923 
924 	for (i = 0; i <= e - s; ++i) {
925 		sa_dev->port[i].sm_ah    = NULL;
926 		sa_dev->port[i].port_num = i + s;
927 		spin_lock_init(&sa_dev->port[i].ah_lock);
928 
929 		sa_dev->port[i].agent =
930 			ib_register_mad_agent(device, i + s, IB_QPT_GSI,
931 					      NULL, 0, send_handler,
932 					      recv_handler, sa_dev);
933 		if (IS_ERR(sa_dev->port[i].agent))
934 			goto err;
935 
936 		INIT_WORK(&sa_dev->port[i].update_task,
937 			  update_sm_ah, &sa_dev->port[i]);
938 	}
939 
940 	ib_set_client_data(device, &sa_client, sa_dev);
941 
942 	/*
943 	 * We register our event handler after everything is set up,
944 	 * and then update our cached info after the event handler is
945 	 * registered to avoid any problems if a port changes state
946 	 * during our initialization.
947 	 */
948 
949 	INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
950 	if (ib_register_event_handler(&sa_dev->event_handler))
951 		goto err;
952 
953 	for (i = 0; i <= e - s; ++i)
954 		update_sm_ah(&sa_dev->port[i]);
955 
956 	return;
957 
958 err:
959 	while (--i >= 0)
960 		ib_unregister_mad_agent(sa_dev->port[i].agent);
961 
962 	kfree(sa_dev);
963 
964 	return;
965 }
966 
967 static void ib_sa_remove_one(struct ib_device *device)
968 {
969 	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
970 	int i;
971 
972 	if (!sa_dev)
973 		return;
974 
975 	ib_unregister_event_handler(&sa_dev->event_handler);
976 
977 	for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
978 		ib_unregister_mad_agent(sa_dev->port[i].agent);
979 		kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
980 	}
981 
982 	kfree(sa_dev);
983 }
984 
985 static int __init ib_sa_init(void)
986 {
987 	int ret;
988 
989 	spin_lock_init(&idr_lock);
990 	spin_lock_init(&tid_lock);
991 
992 	get_random_bytes(&tid, sizeof tid);
993 
994 	ret = ib_register_client(&sa_client);
995 	if (ret)
996 		printk(KERN_ERR "Couldn't register ib_sa client\n");
997 
998 	return ret;
999 }
1000 
1001 static void __exit ib_sa_cleanup(void)
1002 {
1003 	ib_unregister_client(&sa_client);
1004 }
1005 
1006 module_init(ib_sa_init);
1007 module_exit(ib_sa_cleanup);
1008