]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/ofed/drivers/infiniband/core/sa_query.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / ofed / drivers / infiniband / core / sa_query.c
1 /*
2  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4  * Copyright (c) 2006 Intel Corporation.  All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
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/dma-mapping.h>
42 #include <linux/kref.h>
43 #include <linux/idr.h>
44 #include <linux/workqueue.h>
45
46 #include <rdma/ib_pack.h>
47 #include <rdma/ib_cache.h>
48 #include "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         u16                  pkey_index;
58         u8                   src_path_mask;
59 };
60
61 struct ib_sa_port {
62         struct ib_mad_agent *agent;
63         struct ib_mad_agent *notice_agent;
64         struct ib_sa_sm_ah  *sm_ah;
65         struct work_struct   update_task;
66         spinlock_t           ah_lock;
67         u8                   port_num;
68         struct ib_device    *device;
69 };
70
71 struct ib_sa_device {
72         int                     start_port, end_port;
73         struct ib_event_handler event_handler;
74         struct ib_sa_port port[0];
75 };
76
77 struct ib_sa_query {
78         void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
79         void (*release)(struct ib_sa_query *);
80         struct ib_sa_client    *client;
81         struct ib_sa_port      *port;
82         struct ib_mad_send_buf *mad_buf;
83         struct ib_sa_sm_ah     *sm_ah;
84         int                     id;
85 };
86
87 struct ib_sa_service_query {
88         void (*callback)(int, struct ib_sa_service_rec *, void *);
89         void *context;
90         struct ib_sa_query sa_query;
91 };
92
93 struct ib_sa_path_query {
94         void (*callback)(int, struct ib_sa_path_rec *, void *);
95         void *context;
96         struct ib_sa_query sa_query;
97 };
98
99 struct ib_sa_mcmember_query {
100         void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
101         void *context;
102         struct ib_sa_query sa_query;
103 };
104
105 struct ib_sa_inform_query {
106         void (*callback)(int, struct ib_sa_inform *, void *);
107         void *context;
108         struct ib_sa_query sa_query;
109 };
110
111 static void ib_sa_add_one(struct ib_device *device);
112 static void ib_sa_remove_one(struct ib_device *device);
113
114 static struct ib_client sa_client = {
115         .name   = "sa",
116         .add    = ib_sa_add_one,
117         .remove = ib_sa_remove_one
118 };
119
120 static spinlock_t idr_lock;
121 static DEFINE_IDR(query_idr);
122
123 static spinlock_t tid_lock;
124 static u32 tid;
125
126 #define PATH_REC_FIELD(field) \
127         .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),          \
128         .struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,     \
129         .field_name          = "sa_path_rec:" #field
130
131 static const struct ib_field path_rec_table[] = {
132         { PATH_REC_FIELD(service_id),
133           .offset_words = 0,
134           .offset_bits  = 0,
135           .size_bits    = 64 },
136         { PATH_REC_FIELD(dgid),
137           .offset_words = 2,
138           .offset_bits  = 0,
139           .size_bits    = 128 },
140         { PATH_REC_FIELD(sgid),
141           .offset_words = 6,
142           .offset_bits  = 0,
143           .size_bits    = 128 },
144         { PATH_REC_FIELD(dlid),
145           .offset_words = 10,
146           .offset_bits  = 0,
147           .size_bits    = 16 },
148         { PATH_REC_FIELD(slid),
149           .offset_words = 10,
150           .offset_bits  = 16,
151           .size_bits    = 16 },
152         { PATH_REC_FIELD(raw_traffic),
153           .offset_words = 11,
154           .offset_bits  = 0,
155           .size_bits    = 1 },
156         { RESERVED,
157           .offset_words = 11,
158           .offset_bits  = 1,
159           .size_bits    = 3 },
160         { PATH_REC_FIELD(flow_label),
161           .offset_words = 11,
162           .offset_bits  = 4,
163           .size_bits    = 20 },
164         { PATH_REC_FIELD(hop_limit),
165           .offset_words = 11,
166           .offset_bits  = 24,
167           .size_bits    = 8 },
168         { PATH_REC_FIELD(traffic_class),
169           .offset_words = 12,
170           .offset_bits  = 0,
171           .size_bits    = 8 },
172         { PATH_REC_FIELD(reversible),
173           .offset_words = 12,
174           .offset_bits  = 8,
175           .size_bits    = 1 },
176         { PATH_REC_FIELD(numb_path),
177           .offset_words = 12,
178           .offset_bits  = 9,
179           .size_bits    = 7 },
180         { PATH_REC_FIELD(pkey),
181           .offset_words = 12,
182           .offset_bits  = 16,
183           .size_bits    = 16 },
184         { PATH_REC_FIELD(qos_class),
185           .offset_words = 13,
186           .offset_bits  = 0,
187           .size_bits    = 12 },
188         { PATH_REC_FIELD(sl),
189           .offset_words = 13,
190           .offset_bits  = 12,
191           .size_bits    = 4 },
192         { PATH_REC_FIELD(mtu_selector),
193           .offset_words = 13,
194           .offset_bits  = 16,
195           .size_bits    = 2 },
196         { PATH_REC_FIELD(mtu),
197           .offset_words = 13,
198           .offset_bits  = 18,
199           .size_bits    = 6 },
200         { PATH_REC_FIELD(rate_selector),
201           .offset_words = 13,
202           .offset_bits  = 24,
203           .size_bits    = 2 },
204         { PATH_REC_FIELD(rate),
205           .offset_words = 13,
206           .offset_bits  = 26,
207           .size_bits    = 6 },
208         { PATH_REC_FIELD(packet_life_time_selector),
209           .offset_words = 14,
210           .offset_bits  = 0,
211           .size_bits    = 2 },
212         { PATH_REC_FIELD(packet_life_time),
213           .offset_words = 14,
214           .offset_bits  = 2,
215           .size_bits    = 6 },
216         { PATH_REC_FIELD(preference),
217           .offset_words = 14,
218           .offset_bits  = 8,
219           .size_bits    = 8 },
220         { RESERVED,
221           .offset_words = 14,
222           .offset_bits  = 16,
223           .size_bits    = 48 },
224 };
225
226 #define MCMEMBER_REC_FIELD(field) \
227         .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field),      \
228         .struct_size_bytes   = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \
229         .field_name          = "sa_mcmember_rec:" #field
230
231 static const struct ib_field mcmember_rec_table[] = {
232         { MCMEMBER_REC_FIELD(mgid),
233           .offset_words = 0,
234           .offset_bits  = 0,
235           .size_bits    = 128 },
236         { MCMEMBER_REC_FIELD(port_gid),
237           .offset_words = 4,
238           .offset_bits  = 0,
239           .size_bits    = 128 },
240         { MCMEMBER_REC_FIELD(qkey),
241           .offset_words = 8,
242           .offset_bits  = 0,
243           .size_bits    = 32 },
244         { MCMEMBER_REC_FIELD(mlid),
245           .offset_words = 9,
246           .offset_bits  = 0,
247           .size_bits    = 16 },
248         { MCMEMBER_REC_FIELD(mtu_selector),
249           .offset_words = 9,
250           .offset_bits  = 16,
251           .size_bits    = 2 },
252         { MCMEMBER_REC_FIELD(mtu),
253           .offset_words = 9,
254           .offset_bits  = 18,
255           .size_bits    = 6 },
256         { MCMEMBER_REC_FIELD(traffic_class),
257           .offset_words = 9,
258           .offset_bits  = 24,
259           .size_bits    = 8 },
260         { MCMEMBER_REC_FIELD(pkey),
261           .offset_words = 10,
262           .offset_bits  = 0,
263           .size_bits    = 16 },
264         { MCMEMBER_REC_FIELD(rate_selector),
265           .offset_words = 10,
266           .offset_bits  = 16,
267           .size_bits    = 2 },
268         { MCMEMBER_REC_FIELD(rate),
269           .offset_words = 10,
270           .offset_bits  = 18,
271           .size_bits    = 6 },
272         { MCMEMBER_REC_FIELD(packet_life_time_selector),
273           .offset_words = 10,
274           .offset_bits  = 24,
275           .size_bits    = 2 },
276         { MCMEMBER_REC_FIELD(packet_life_time),
277           .offset_words = 10,
278           .offset_bits  = 26,
279           .size_bits    = 6 },
280         { MCMEMBER_REC_FIELD(sl),
281           .offset_words = 11,
282           .offset_bits  = 0,
283           .size_bits    = 4 },
284         { MCMEMBER_REC_FIELD(flow_label),
285           .offset_words = 11,
286           .offset_bits  = 4,
287           .size_bits    = 20 },
288         { MCMEMBER_REC_FIELD(hop_limit),
289           .offset_words = 11,
290           .offset_bits  = 24,
291           .size_bits    = 8 },
292         { MCMEMBER_REC_FIELD(scope),
293           .offset_words = 12,
294           .offset_bits  = 0,
295           .size_bits    = 4 },
296         { MCMEMBER_REC_FIELD(join_state),
297           .offset_words = 12,
298           .offset_bits  = 4,
299           .size_bits    = 4 },
300         { MCMEMBER_REC_FIELD(proxy_join),
301           .offset_words = 12,
302           .offset_bits  = 8,
303           .size_bits    = 1 },
304         { RESERVED,
305           .offset_words = 12,
306           .offset_bits  = 9,
307           .size_bits    = 23 },
308 };
309
310 #define SERVICE_REC_FIELD(field) \
311         .struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),       \
312         .struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,  \
313         .field_name          = "sa_service_rec:" #field
314
315 static const struct ib_field service_rec_table[] = {
316         { SERVICE_REC_FIELD(id),
317           .offset_words = 0,
318           .offset_bits  = 0,
319           .size_bits    = 64 },
320         { SERVICE_REC_FIELD(gid),
321           .offset_words = 2,
322           .offset_bits  = 0,
323           .size_bits    = 128 },
324         { SERVICE_REC_FIELD(pkey),
325           .offset_words = 6,
326           .offset_bits  = 0,
327           .size_bits    = 16 },
328         { SERVICE_REC_FIELD(lease),
329           .offset_words = 7,
330           .offset_bits  = 0,
331           .size_bits    = 32 },
332         { SERVICE_REC_FIELD(key),
333           .offset_words = 8,
334           .offset_bits  = 0,
335           .size_bits    = 128 },
336         { SERVICE_REC_FIELD(name),
337           .offset_words = 12,
338           .offset_bits  = 0,
339           .size_bits    = 64*8 },
340         { SERVICE_REC_FIELD(data8),
341           .offset_words = 28,
342           .offset_bits  = 0,
343           .size_bits    = 16*8 },
344         { SERVICE_REC_FIELD(data16),
345           .offset_words = 32,
346           .offset_bits  = 0,
347           .size_bits    = 8*16 },
348         { SERVICE_REC_FIELD(data32),
349           .offset_words = 36,
350           .offset_bits  = 0,
351           .size_bits    = 4*32 },
352         { SERVICE_REC_FIELD(data64),
353           .offset_words = 40,
354           .offset_bits  = 0,
355           .size_bits    = 2*64 },
356 };
357
358 #define INFORM_FIELD(field) \
359         .struct_offset_bytes = offsetof(struct ib_sa_inform, field), \
360         .struct_size_bytes   = sizeof ((struct ib_sa_inform *) 0)->field, \
361         .field_name          = "sa_inform:" #field
362
363 static const struct ib_field inform_table[] = {
364         { INFORM_FIELD(gid),
365           .offset_words = 0,
366           .offset_bits  = 0,
367           .size_bits    = 128 },
368         { INFORM_FIELD(lid_range_begin),
369           .offset_words = 4,
370           .offset_bits  = 0,
371           .size_bits    = 16 },
372         { INFORM_FIELD(lid_range_end),
373           .offset_words = 4,
374           .offset_bits  = 16,
375           .size_bits    = 16 },
376         { RESERVED,
377           .offset_words = 5,
378           .offset_bits  = 0,
379           .size_bits    = 16 },
380         { INFORM_FIELD(is_generic),
381           .offset_words = 5,
382           .offset_bits  = 16,
383           .size_bits    = 8 },
384         { INFORM_FIELD(subscribe),
385           .offset_words = 5,
386           .offset_bits  = 24,
387           .size_bits    = 8 },
388         { INFORM_FIELD(type),
389           .offset_words = 6,
390           .offset_bits  = 0,
391           .size_bits    = 16 },
392         { INFORM_FIELD(trap.generic.trap_num),
393           .offset_words = 6,
394           .offset_bits  = 16,
395           .size_bits    = 16 },
396         { INFORM_FIELD(trap.generic.qpn),
397           .offset_words = 7,
398           .offset_bits  = 0,
399           .size_bits    = 24 },
400         { RESERVED,
401           .offset_words = 7,
402           .offset_bits  = 24,
403           .size_bits    = 3 },
404         { INFORM_FIELD(trap.generic.resp_time),
405           .offset_words = 7,
406           .offset_bits  = 27,
407           .size_bits    = 5 },
408         { RESERVED,
409           .offset_words = 8,
410           .offset_bits  = 0,
411           .size_bits    = 8 },
412         { INFORM_FIELD(trap.generic.producer_type),
413           .offset_words = 8,
414           .offset_bits  = 8,
415           .size_bits    = 24 },
416 };
417
418 #define NOTICE_FIELD(field) \
419         .struct_offset_bytes = offsetof(struct ib_sa_notice, field), \
420         .struct_size_bytes   = sizeof ((struct ib_sa_notice *) 0)->field, \
421         .field_name          = "sa_notice:" #field
422
423 static const struct ib_field notice_table[] = {
424         { NOTICE_FIELD(is_generic),
425           .offset_words = 0,
426           .offset_bits  = 0,
427           .size_bits    = 1 },
428         { NOTICE_FIELD(type),
429           .offset_words = 0,
430           .offset_bits  = 1,
431           .size_bits    = 7 },
432         { NOTICE_FIELD(trap.generic.producer_type),
433           .offset_words = 0,
434           .offset_bits  = 8,
435           .size_bits    = 24 },
436         { NOTICE_FIELD(trap.generic.trap_num),
437           .offset_words = 1,
438           .offset_bits  = 0,
439           .size_bits    = 16 },
440         { NOTICE_FIELD(issuer_lid),
441           .offset_words = 1,
442           .offset_bits  = 16,
443           .size_bits    = 16 },
444         { NOTICE_FIELD(notice_toggle),
445           .offset_words = 2,
446           .offset_bits  = 0,
447           .size_bits    = 1 },
448         { NOTICE_FIELD(notice_count),
449           .offset_words = 2,
450           .offset_bits  = 1,
451           .size_bits    = 15 },
452         { NOTICE_FIELD(data_details),
453           .offset_words = 2,
454           .offset_bits  = 16,
455           .size_bits    = 432 },
456         { NOTICE_FIELD(issuer_gid),
457           .offset_words = 16,
458           .offset_bits  = 0,
459           .size_bits    = 128 },
460 };
461
462 int ib_sa_check_selector(ib_sa_comp_mask comp_mask,
463                          ib_sa_comp_mask selector_mask,
464                          ib_sa_comp_mask value_mask,
465                          u8 selector, u8 src_value, u8 dst_value)
466 {
467         int err;
468
469         if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
470                 return 0;
471
472         switch (selector) {
473         case IB_SA_GT:
474                 err = (src_value <= dst_value);
475                 break;
476         case IB_SA_LT:
477                 err = (src_value >= dst_value);
478                 break;
479         case IB_SA_EQ:
480                 err = (src_value != dst_value);
481                 break;
482         default:
483                 err = 0;
484                 break;
485         }
486
487         return err;
488 }
489
490 int ib_sa_pack_attr(void *dst, void *src, int attr_id)
491 {
492         switch (attr_id) {
493         case IB_SA_ATTR_PATH_REC:
494                 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
495                 break;
496         default:
497                 return -EINVAL;
498         }
499         return 0;
500 }
501
502 int ib_sa_unpack_attr(void *dst, void *src, int attr_id)
503 {
504         switch (attr_id) {
505         case IB_SA_ATTR_PATH_REC:
506                 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
507                 break;
508         default:
509                 return -EINVAL;
510         }
511         return 0;
512 }
513
514 static void free_sm_ah(struct kref *kref)
515 {
516         struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
517
518         ib_destroy_ah(sm_ah->ah);
519         kfree(sm_ah);
520 }
521
522 static void update_sm_ah(struct work_struct *work)
523 {
524         struct ib_sa_port *port =
525                 container_of(work, struct ib_sa_port, update_task);
526         struct ib_sa_sm_ah *new_ah;
527         struct ib_port_attr port_attr;
528         struct ib_ah_attr   ah_attr;
529
530         if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
531                 printk(KERN_WARNING "Couldn't query port\n");
532                 return;
533         }
534
535         new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
536         if (!new_ah) {
537                 printk(KERN_WARNING "Couldn't allocate new SM AH\n");
538                 return;
539         }
540
541         kref_init(&new_ah->ref);
542         new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
543
544         new_ah->pkey_index = 0;
545         if (ib_find_pkey(port->agent->device, port->port_num,
546                          IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index))
547                 printk(KERN_ERR "Couldn't find index for default PKey\n");
548
549         memset(&ah_attr, 0, sizeof ah_attr);
550         ah_attr.dlid     = port_attr.sm_lid;
551         ah_attr.sl       = port_attr.sm_sl;
552         ah_attr.port_num = port->port_num;
553
554         new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
555         if (IS_ERR(new_ah->ah)) {
556                 printk(KERN_WARNING "Couldn't create new SM AH\n");
557                 kfree(new_ah);
558                 return;
559         }
560
561         spin_lock_irq(&port->ah_lock);
562         if (port->sm_ah)
563                 kref_put(&port->sm_ah->ref, free_sm_ah);
564         port->sm_ah = new_ah;
565         spin_unlock_irq(&port->ah_lock);
566
567 }
568
569 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
570 {
571         if (event->event == IB_EVENT_PORT_ERR    ||
572             event->event == IB_EVENT_PORT_ACTIVE ||
573             event->event == IB_EVENT_LID_CHANGE  ||
574             event->event == IB_EVENT_PKEY_CHANGE ||
575             event->event == IB_EVENT_SM_CHANGE   ||
576             event->event == IB_EVENT_CLIENT_REREGISTER) {
577                 unsigned long flags;
578                 struct ib_sa_device *sa_dev =
579                         container_of(handler, typeof(*sa_dev), event_handler);
580                 struct ib_sa_port *port =
581                         &sa_dev->port[event->element.port_num - sa_dev->start_port];
582
583                 if (rdma_port_get_link_layer(handler->device, port->port_num) != IB_LINK_LAYER_INFINIBAND)
584                         return;
585
586                 spin_lock_irqsave(&port->ah_lock, flags);
587                 if (port->sm_ah)
588                         kref_put(&port->sm_ah->ref, free_sm_ah);
589                 port->sm_ah = NULL;
590                 spin_unlock_irqrestore(&port->ah_lock, flags);
591
592                 schedule_work(&sa_dev->port[event->element.port_num -
593                                             sa_dev->start_port].update_task);
594         }
595 }
596
597 void ib_sa_register_client(struct ib_sa_client *client)
598 {
599         atomic_set(&client->users, 1);
600         init_completion(&client->comp);
601 }
602 EXPORT_SYMBOL(ib_sa_register_client);
603
604 void ib_sa_unregister_client(struct ib_sa_client *client)
605 {
606         ib_sa_client_put(client);
607         wait_for_completion(&client->comp);
608 }
609 EXPORT_SYMBOL(ib_sa_unregister_client);
610
611 /**
612  * ib_sa_cancel_query - try to cancel an SA query
613  * @id:ID of query to cancel
614  * @query:query pointer to cancel
615  *
616  * Try to cancel an SA query.  If the id and query don't match up or
617  * the query has already completed, nothing is done.  Otherwise the
618  * query is canceled and will complete with a status of -EINTR.
619  */
620 void ib_sa_cancel_query(int id, struct ib_sa_query *query)
621 {
622         unsigned long flags;
623         struct ib_mad_agent *agent;
624         struct ib_mad_send_buf *mad_buf;
625
626         spin_lock_irqsave(&idr_lock, flags);
627         if (idr_find(&query_idr, id) != query) {
628                 spin_unlock_irqrestore(&idr_lock, flags);
629                 return;
630         }
631         agent = query->port->agent;
632         mad_buf = query->mad_buf;
633         spin_unlock_irqrestore(&idr_lock, flags);
634
635         ib_cancel_mad(agent, mad_buf);
636 }
637 EXPORT_SYMBOL(ib_sa_cancel_query);
638
639 static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
640 {
641         struct ib_sa_device *sa_dev;
642         struct ib_sa_port   *port;
643         unsigned long flags;
644         u8 src_path_mask;
645
646         sa_dev = ib_get_client_data(device, &sa_client);
647         if (!sa_dev)
648                 return 0x7f;
649
650         port  = &sa_dev->port[port_num - sa_dev->start_port];
651         spin_lock_irqsave(&port->ah_lock, flags);
652         src_path_mask = port->sm_ah ? port->sm_ah->src_path_mask : 0x7f;
653         spin_unlock_irqrestore(&port->ah_lock, flags);
654
655         return src_path_mask;
656 }
657
658 int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
659                          struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr)
660 {
661         int ret;
662         u16 gid_index;
663         int force_grh;
664
665         memset(ah_attr, 0, sizeof *ah_attr);
666         ah_attr->dlid = be16_to_cpu(rec->dlid);
667         ah_attr->sl = rec->sl;
668         ah_attr->src_path_bits = be16_to_cpu(rec->slid) &
669                                  get_src_path_mask(device, port_num);
670         ah_attr->port_num = port_num;
671         ah_attr->static_rate = rec->rate;
672
673         force_grh = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_ETHERNET;
674
675         if (rec->hop_limit > 1 || force_grh) {
676                 ah_attr->ah_flags = IB_AH_GRH;
677                 ah_attr->grh.dgid = rec->dgid;
678
679                 ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
680                                          &gid_index);
681                 if (ret)
682                         return ret;
683
684                 ah_attr->grh.sgid_index    = gid_index;
685                 ah_attr->grh.flow_label    = be32_to_cpu(rec->flow_label);
686                 ah_attr->grh.hop_limit     = rec->hop_limit;
687                 ah_attr->grh.traffic_class = rec->traffic_class;
688         }
689         return 0;
690 }
691 EXPORT_SYMBOL(ib_init_ah_from_path);
692
693 static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
694 {
695         unsigned long flags;
696
697         spin_lock_irqsave(&query->port->ah_lock, flags);
698         if (!query->port->sm_ah) {
699                 spin_unlock_irqrestore(&query->port->ah_lock, flags);
700                 return -EAGAIN;
701         }
702         kref_get(&query->port->sm_ah->ref);
703         query->sm_ah = query->port->sm_ah;
704         spin_unlock_irqrestore(&query->port->ah_lock, flags);
705
706         query->mad_buf = ib_create_send_mad(query->port->agent, 1,
707                                             query->sm_ah->pkey_index,
708                                             0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
709                                             gfp_mask);
710         if (IS_ERR(query->mad_buf)) {
711                 kref_put(&query->sm_ah->ref, free_sm_ah);
712                 return -ENOMEM;
713         }
714
715         query->mad_buf->ah = query->sm_ah->ah;
716
717         return 0;
718 }
719
720 static void free_mad(struct ib_sa_query *query)
721 {
722         ib_free_send_mad(query->mad_buf);
723         kref_put(&query->sm_ah->ref, free_sm_ah);
724 }
725
726 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
727 {
728         unsigned long flags;
729
730         memset(mad, 0, sizeof *mad);
731
732         mad->mad_hdr.base_version  = IB_MGMT_BASE_VERSION;
733         mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_SUBN_ADM;
734         mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
735
736         spin_lock_irqsave(&tid_lock, flags);
737         mad->mad_hdr.tid           =
738                 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
739         spin_unlock_irqrestore(&tid_lock, flags);
740 }
741
742 static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
743 {
744         unsigned long flags;
745         int ret, id;
746
747 retry:
748         if (!idr_pre_get(&query_idr, gfp_mask))
749                 return -ENOMEM;
750         spin_lock_irqsave(&idr_lock, flags);
751         ret = idr_get_new(&query_idr, query, &id);
752         spin_unlock_irqrestore(&idr_lock, flags);
753         if (ret == -EAGAIN)
754                 goto retry;
755         if (ret)
756                 return ret;
757
758         query->mad_buf->timeout_ms  = timeout_ms;
759         query->mad_buf->context[0] = query;
760         query->id = id;
761
762         ret = ib_post_send_mad(query->mad_buf, NULL);
763         if (ret) {
764                 spin_lock_irqsave(&idr_lock, flags);
765                 idr_remove(&query_idr, id);
766                 spin_unlock_irqrestore(&idr_lock, flags);
767         }
768
769         /*
770          * It's not safe to dereference query any more, because the
771          * send may already have completed and freed the query in
772          * another context.
773          */
774         return ret ? ret : id;
775 }
776
777 void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
778 {
779         ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
780 }
781 EXPORT_SYMBOL(ib_sa_unpack_path);
782
783 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
784                                     int status,
785                                     struct ib_sa_mad *mad)
786 {
787         struct ib_sa_path_query *query =
788                 container_of(sa_query, struct ib_sa_path_query, sa_query);
789
790         if (mad) {
791                 struct ib_sa_path_rec rec;
792
793                 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
794                           mad->data, &rec);
795                 query->callback(status, &rec, query->context);
796         } else
797                 query->callback(status, NULL, query->context);
798 }
799
800 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
801 {
802         kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
803 }
804
805 int ib_sa_path_rec_query(struct ib_sa_client *client,
806                          struct ib_device *device, u8 port_num,
807                          struct ib_sa_path_rec *rec,
808                          ib_sa_comp_mask comp_mask,
809                          int timeout_ms, gfp_t gfp_mask,
810                          void (*callback)(int status,
811                                           struct ib_sa_path_rec *resp,
812                                           void *context),
813                          void *context,
814                          struct ib_sa_query **sa_query)
815 {
816         struct ib_sa_path_query *query;
817         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
818         struct ib_sa_port   *port;
819         struct ib_mad_agent *agent;
820         struct ib_sa_mad *mad;
821         int ret;
822
823         if (!sa_dev)
824                 return -ENODEV;
825
826         port  = &sa_dev->port[port_num - sa_dev->start_port];
827         agent = port->agent;
828
829         query = kmalloc(sizeof *query, gfp_mask);
830         if (!query)
831                 return -ENOMEM;
832
833         query->sa_query.port     = port;
834         ret = alloc_mad(&query->sa_query, gfp_mask);
835         if (ret)
836                 goto err1;
837
838         ib_sa_client_get(client);
839         query->sa_query.client = client;
840         query->callback        = callback;
841         query->context         = context;
842
843         mad = query->sa_query.mad_buf->mad;
844         init_mad(mad, agent);
845
846         query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
847         query->sa_query.release  = ib_sa_path_rec_release;
848         mad->mad_hdr.method      = IB_MGMT_METHOD_GET;
849         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_PATH_REC);
850         mad->sa_hdr.comp_mask    = comp_mask;
851
852         ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
853
854         *sa_query = &query->sa_query;
855
856         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
857         if (ret < 0)
858                 goto err2;
859
860         return ret;
861
862 err2:
863         *sa_query = NULL;
864         ib_sa_client_put(query->sa_query.client);
865         free_mad(&query->sa_query);
866
867 err1:
868         kfree(query);
869         return ret;
870 }
871
872 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
873                                     int status,
874                                     struct ib_sa_mad *mad)
875 {
876         struct ib_sa_service_query *query =
877                 container_of(sa_query, struct ib_sa_service_query, sa_query);
878
879         if (mad) {
880                 struct ib_sa_service_rec rec;
881
882                 ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
883                           mad->data, &rec);
884                 query->callback(status, &rec, query->context);
885         } else
886                 query->callback(status, NULL, query->context);
887 }
888
889 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
890 {
891         kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
892 }
893
894 /**
895  * ib_sa_service_rec_query - Start Service Record operation
896  * @client:SA client
897  * @device:device to send request on
898  * @port_num: port number to send request on
899  * @method:SA method - should be get, set, or delete
900  * @rec:Service Record to send in request
901  * @comp_mask:component mask to send in request
902  * @timeout_ms:time to wait for response
903  * @gfp_mask:GFP mask to use for internal allocations
904  * @callback:function called when request completes, times out or is
905  * canceled
906  * @context:opaque user context passed to callback
907  * @sa_query:request context, used to cancel request
908  *
909  * Send a Service Record set/get/delete to the SA to register,
910  * unregister or query a service record.
911  * The callback function will be called when the request completes (or
912  * fails); status is 0 for a successful response, -EINTR if the query
913  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
914  * occurred sending the query.  The resp parameter of the callback is
915  * only valid if status is 0.
916  *
917  * If the return value of ib_sa_service_rec_query() is negative, it is an
918  * error code.  Otherwise it is a request ID that can be used to cancel
919  * the query.
920  */
921 int ib_sa_service_rec_query(struct ib_sa_client *client,
922                             struct ib_device *device, u8 port_num, u8 method,
923                             struct ib_sa_service_rec *rec,
924                             ib_sa_comp_mask comp_mask,
925                             int timeout_ms, gfp_t gfp_mask,
926                             void (*callback)(int status,
927                                              struct ib_sa_service_rec *resp,
928                                              void *context),
929                             void *context,
930                             struct ib_sa_query **sa_query)
931 {
932         struct ib_sa_service_query *query;
933         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
934         struct ib_sa_port   *port;
935         struct ib_mad_agent *agent;
936         struct ib_sa_mad *mad;
937         int ret;
938
939         if (!sa_dev)
940                 return -ENODEV;
941
942         port  = &sa_dev->port[port_num - sa_dev->start_port];
943         agent = port->agent;
944
945         if (method != IB_MGMT_METHOD_GET &&
946             method != IB_MGMT_METHOD_SET &&
947             method != IB_SA_METHOD_DELETE)
948                 return -EINVAL;
949
950         query = kmalloc(sizeof *query, gfp_mask);
951         if (!query)
952                 return -ENOMEM;
953
954         query->sa_query.port     = port;
955         ret = alloc_mad(&query->sa_query, gfp_mask);
956         if (ret)
957                 goto err1;
958
959         ib_sa_client_get(client);
960         query->sa_query.client = client;
961         query->callback        = callback;
962         query->context         = context;
963
964         mad = query->sa_query.mad_buf->mad;
965         init_mad(mad, agent);
966
967         query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
968         query->sa_query.release  = ib_sa_service_rec_release;
969         mad->mad_hdr.method      = method;
970         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
971         mad->sa_hdr.comp_mask    = comp_mask;
972
973         ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
974                 rec, mad->data);
975
976         *sa_query = &query->sa_query;
977
978         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
979         if (ret < 0)
980                 goto err2;
981
982         return ret;
983
984 err2:
985         *sa_query = NULL;
986         ib_sa_client_put(query->sa_query.client);
987         free_mad(&query->sa_query);
988
989 err1:
990         kfree(query);
991         return ret;
992 }
993 EXPORT_SYMBOL(ib_sa_service_rec_query);
994
995 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
996                                         int status,
997                                         struct ib_sa_mad *mad)
998 {
999         struct ib_sa_mcmember_query *query =
1000                 container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
1001
1002         if (mad) {
1003                 struct ib_sa_mcmember_rec rec;
1004
1005                 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1006                           mad->data, &rec);
1007                 query->callback(status, &rec, query->context);
1008         } else
1009                 query->callback(status, NULL, query->context);
1010 }
1011
1012 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
1013 {
1014         kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
1015 }
1016
1017 int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
1018                              struct ib_device *device, u8 port_num,
1019                              u8 method,
1020                              struct ib_sa_mcmember_rec *rec,
1021                              ib_sa_comp_mask comp_mask,
1022                              int timeout_ms, gfp_t gfp_mask,
1023                              void (*callback)(int status,
1024                                               struct ib_sa_mcmember_rec *resp,
1025                                               void *context),
1026                              void *context,
1027                              struct ib_sa_query **sa_query)
1028 {
1029         struct ib_sa_mcmember_query *query;
1030         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1031         struct ib_sa_port   *port;
1032         struct ib_mad_agent *agent;
1033         struct ib_sa_mad *mad;
1034         int ret;
1035
1036         if (!sa_dev)
1037                 return -ENODEV;
1038
1039         port  = &sa_dev->port[port_num - sa_dev->start_port];
1040         agent = port->agent;
1041
1042         query = kmalloc(sizeof *query, gfp_mask);
1043         if (!query)
1044                 return -ENOMEM;
1045
1046         query->sa_query.port     = port;
1047         ret = alloc_mad(&query->sa_query, gfp_mask);
1048         if (ret)
1049                 goto err1;
1050
1051         ib_sa_client_get(client);
1052         query->sa_query.client = client;
1053         query->callback        = callback;
1054         query->context         = context;
1055
1056         mad = query->sa_query.mad_buf->mad;
1057         init_mad(mad, agent);
1058
1059         query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
1060         query->sa_query.release  = ib_sa_mcmember_rec_release;
1061         mad->mad_hdr.method      = method;
1062         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
1063         mad->sa_hdr.comp_mask    = comp_mask;
1064
1065         ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1066                 rec, mad->data);
1067
1068         *sa_query = &query->sa_query;
1069
1070         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1071         if (ret < 0)
1072                 goto err2;
1073
1074         return ret;
1075
1076 err2:
1077         *sa_query = NULL;
1078         ib_sa_client_put(query->sa_query.client);
1079         free_mad(&query->sa_query);
1080
1081 err1:
1082         kfree(query);
1083         return ret;
1084 }
1085
1086 static void ib_sa_inform_callback(struct ib_sa_query *sa_query,
1087                                   int status,
1088                                   struct ib_sa_mad *mad)
1089 {
1090         struct ib_sa_inform_query *query =
1091                 container_of(sa_query, struct ib_sa_inform_query, sa_query);
1092
1093         if (mad) {
1094                 struct ib_sa_inform rec;
1095
1096                 ib_unpack(inform_table, ARRAY_SIZE(inform_table),
1097                           mad->data, &rec);
1098                 query->callback(status, &rec, query->context);
1099         } else
1100                 query->callback(status, NULL, query->context);
1101 }
1102
1103 static void ib_sa_inform_release(struct ib_sa_query *sa_query)
1104 {
1105         kfree(container_of(sa_query, struct ib_sa_inform_query, sa_query));
1106 }
1107
1108 /**
1109  * ib_sa_informinfo_query - Start an InformInfo registration.
1110  * @client:SA client
1111  * @device:device to send query on
1112  * @port_num: port number to send query on
1113  * @rec:Inform record to send in query
1114  * @timeout_ms:time to wait for response
1115  * @gfp_mask:GFP mask to use for internal allocations
1116  * @callback:function called when notice handler registration completes,
1117  * times out or is canceled
1118  * @context:opaque user context passed to callback
1119  * @sa_query:query context, used to cancel query
1120  *
1121  * This function sends inform info to register with SA to receive
1122  * in-service notice.
1123  * The callback function will be called when the query completes (or
1124  * fails); status is 0 for a successful response, -EINTR if the query
1125  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
1126  * occurred sending the query.  The resp parameter of the callback is
1127  * only valid if status is 0.
1128  *
1129  * If the return value of ib_sa_inform_query() is negative, it is an
1130  * error code.  Otherwise it is a query ID that can be used to cancel
1131  * the query.
1132  */
1133 int ib_sa_informinfo_query(struct ib_sa_client *client,
1134                            struct ib_device *device, u8 port_num,
1135                            struct ib_sa_inform *rec,
1136                            int timeout_ms, gfp_t gfp_mask,
1137                            void (*callback)(int status,
1138                                            struct ib_sa_inform *resp,
1139                                            void *context),
1140                            void *context,
1141                            struct ib_sa_query **sa_query)
1142 {
1143         struct ib_sa_inform_query *query;
1144         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1145         struct ib_sa_port   *port;
1146         struct ib_mad_agent *agent;
1147         struct ib_sa_mad *mad;
1148         int ret;
1149
1150         if (!sa_dev)
1151                 return -ENODEV;
1152
1153         port  = &sa_dev->port[port_num - sa_dev->start_port];
1154         agent = port->agent;
1155
1156         query = kmalloc(sizeof *query, gfp_mask);
1157         if (!query)
1158                 return -ENOMEM;
1159
1160         query->sa_query.port     = port;
1161         ret = alloc_mad(&query->sa_query, gfp_mask);
1162         if (ret)
1163                 goto err1;
1164
1165         ib_sa_client_get(client);
1166         query->sa_query.client = client;
1167         query->callback = callback;
1168         query->context  = context;
1169
1170         mad = query->sa_query.mad_buf->mad;
1171         init_mad(mad, agent);
1172
1173         query->sa_query.callback = callback ? ib_sa_inform_callback : NULL;
1174         query->sa_query.release  = ib_sa_inform_release;
1175         query->sa_query.port     = port;
1176         mad->mad_hdr.method      = IB_MGMT_METHOD_SET;
1177         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_INFORM_INFO);
1178
1179         ib_pack(inform_table, ARRAY_SIZE(inform_table), rec, mad->data);
1180
1181         *sa_query = &query->sa_query;
1182         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1183         if (ret < 0)
1184                 goto err2;
1185
1186         return ret;
1187
1188 err2:
1189         *sa_query = NULL;
1190         ib_sa_client_put(query->sa_query.client);
1191         free_mad(&query->sa_query);
1192 err1:
1193         kfree(query);
1194         return ret;
1195 }
1196
1197 static void ib_sa_notice_resp(struct ib_sa_port *port,
1198                               struct ib_mad_recv_wc *mad_recv_wc)
1199 {
1200         struct ib_mad_send_buf *mad_buf;
1201         struct ib_sa_mad *mad;
1202         int ret;
1203         unsigned long flags;
1204
1205         mad_buf = ib_create_send_mad(port->notice_agent, 1, 0, 0,
1206                                      IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
1207                                      GFP_KERNEL);
1208         if (IS_ERR(mad_buf))
1209                 return;
1210
1211         mad = mad_buf->mad;
1212         memcpy(mad, mad_recv_wc->recv_buf.mad, sizeof *mad);
1213         mad->mad_hdr.method = IB_MGMT_METHOD_REPORT_RESP;
1214
1215         spin_lock_irqsave(&port->ah_lock, flags);
1216         if (!port->sm_ah) {
1217                 spin_unlock_irqrestore(&port->ah_lock, flags);
1218                 ib_free_send_mad(mad_buf);
1219                 return;
1220         }
1221         kref_get(&port->sm_ah->ref);
1222         mad_buf->context[0] = &port->sm_ah->ref;
1223         mad_buf->ah = port->sm_ah->ah;
1224         spin_unlock_irqrestore(&port->ah_lock, flags);
1225
1226         ret = ib_post_send_mad(mad_buf, NULL);
1227         if (ret)
1228                 goto err;
1229
1230         return;
1231 err:
1232         kref_put(mad_buf->context[0], free_sm_ah);
1233         ib_free_send_mad(mad_buf);
1234 }
1235
1236 static void send_handler(struct ib_mad_agent *agent,
1237                          struct ib_mad_send_wc *mad_send_wc)
1238 {
1239         struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
1240         unsigned long flags;
1241
1242         if (query->callback)
1243                 switch (mad_send_wc->status) {
1244                 case IB_WC_SUCCESS:
1245                         /* No callback -- already got recv */
1246                         break;
1247                 case IB_WC_RESP_TIMEOUT_ERR:
1248                         query->callback(query, -ETIMEDOUT, NULL);
1249                         break;
1250                 case IB_WC_WR_FLUSH_ERR:
1251                         query->callback(query, -EINTR, NULL);
1252                         break;
1253                 default:
1254                         query->callback(query, -EIO, NULL);
1255                         break;
1256                 }
1257
1258         spin_lock_irqsave(&idr_lock, flags);
1259         idr_remove(&query_idr, query->id);
1260         spin_unlock_irqrestore(&idr_lock, flags);
1261
1262         free_mad(query);
1263         ib_sa_client_put(query->client);
1264         query->release(query);
1265 }
1266
1267 static void recv_handler(struct ib_mad_agent *mad_agent,
1268                          struct ib_mad_recv_wc *mad_recv_wc)
1269 {
1270         struct ib_sa_query *query;
1271         struct ib_mad_send_buf *mad_buf;
1272
1273         mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
1274         query = mad_buf->context[0];
1275
1276         if (query->callback) {
1277                 if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
1278                         query->callback(query,
1279                                         mad_recv_wc->recv_buf.mad->mad_hdr.status ?
1280                                         -EINVAL : 0,
1281                                         (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
1282                 else
1283                         query->callback(query, -EIO, NULL);
1284         }
1285
1286         ib_free_recv_mad(mad_recv_wc);
1287 }
1288
1289 static void notice_resp_handler(struct ib_mad_agent *agent,
1290                                 struct ib_mad_send_wc *mad_send_wc)
1291 {
1292         kref_put(mad_send_wc->send_buf->context[0], free_sm_ah);
1293         ib_free_send_mad(mad_send_wc->send_buf);
1294 }
1295
1296 static void notice_handler(struct ib_mad_agent *mad_agent,
1297                            struct ib_mad_recv_wc *mad_recv_wc)
1298 {
1299         struct ib_sa_port *port;
1300         struct ib_sa_mad *mad;
1301         struct ib_sa_notice notice;
1302
1303         port = mad_agent->context;
1304         mad = (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad;
1305         ib_unpack(notice_table, ARRAY_SIZE(notice_table), mad->data, &notice);
1306
1307         if (!notice_dispatch(port->device, port->port_num, &notice))
1308                 ib_sa_notice_resp(port, mad_recv_wc);
1309         ib_free_recv_mad(mad_recv_wc);
1310 }
1311
1312 static void ib_sa_add_one(struct ib_device *device)
1313 {
1314         struct ib_sa_device *sa_dev;
1315         struct ib_mad_reg_req reg_req = {
1316                 .mgmt_class = IB_MGMT_CLASS_SUBN_ADM,
1317                 .mgmt_class_version = 2
1318         };
1319         int s, e, i;
1320
1321         if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1322                 return;
1323
1324         if (device->node_type == RDMA_NODE_IB_SWITCH)
1325                 s = e = 0;
1326         else {
1327                 s = 1;
1328                 e = device->phys_port_cnt;
1329         }
1330
1331         sa_dev = kzalloc(sizeof *sa_dev +
1332                          (e - s + 1) * sizeof (struct ib_sa_port),
1333                          GFP_KERNEL);
1334         if (!sa_dev)
1335                 return;
1336
1337         sa_dev->start_port = s;
1338         sa_dev->end_port   = e;
1339
1340         for (i = 0; i <= e - s; ++i) {
1341                 spin_lock_init(&sa_dev->port[i].ah_lock);
1342                 if (rdma_port_get_link_layer(device, i + 1) != IB_LINK_LAYER_INFINIBAND)
1343                         continue;
1344
1345                 sa_dev->port[i].sm_ah    = NULL;
1346                 sa_dev->port[i].port_num = i + s;
1347
1348                 sa_dev->port[i].agent =
1349                         ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1350                                               NULL, 0, send_handler,
1351                                               recv_handler, sa_dev);
1352                 if (IS_ERR(sa_dev->port[i].agent))
1353                         goto err;
1354
1355                 sa_dev->port[i].device = device;
1356                 set_bit(IB_MGMT_METHOD_REPORT, reg_req.method_mask);
1357                 sa_dev->port[i].notice_agent =
1358                         ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1359                                               &reg_req, 0, notice_resp_handler,
1360                                               notice_handler, &sa_dev->port[i]);
1361
1362                 if (IS_ERR(sa_dev->port[i].notice_agent))
1363                         goto err;
1364
1365                 INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
1366         }
1367
1368         ib_set_client_data(device, &sa_client, sa_dev);
1369
1370         /*
1371          * We register our event handler after everything is set up,
1372          * and then update our cached info after the event handler is
1373          * registered to avoid any problems if a port changes state
1374          * during our initialization.
1375          */
1376
1377         INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
1378         if (ib_register_event_handler(&sa_dev->event_handler))
1379                 goto err;
1380
1381         for (i = 0; i <= e - s; ++i)
1382                 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND)
1383                         update_sm_ah(&sa_dev->port[i].update_task);
1384
1385         return;
1386
1387 err:
1388         while (--i >= 0)
1389                 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1390                         if (!IS_ERR(sa_dev->port[i].notice_agent))
1391                                 ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1392                         if (!IS_ERR(sa_dev->port[i].agent))
1393                                 ib_unregister_mad_agent(sa_dev->port[i].agent);
1394                 }
1395
1396         kfree(sa_dev);
1397
1398         return;
1399 }
1400
1401 static void ib_sa_remove_one(struct ib_device *device)
1402 {
1403         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1404         int i;
1405
1406         if (!sa_dev)
1407                 return;
1408
1409         ib_unregister_event_handler(&sa_dev->event_handler);
1410
1411         flush_scheduled_work();
1412
1413         for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
1414                 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1415                         ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1416                         ib_unregister_mad_agent(sa_dev->port[i].agent);
1417                         if (sa_dev->port[i].sm_ah)
1418                                 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
1419                 }
1420
1421         }
1422
1423         kfree(sa_dev);
1424 }
1425
1426 static int __init ib_sa_init(void)
1427 {
1428         int ret;
1429
1430         spin_lock_init(&idr_lock);
1431         spin_lock_init(&tid_lock);
1432
1433         get_random_bytes(&tid, sizeof tid);
1434
1435         ret = ib_register_client(&sa_client);
1436         if (ret) {
1437                 printk(KERN_ERR "Couldn't register ib_sa client\n");
1438                 goto err1;
1439         }
1440
1441         ret = mcast_init();
1442         if (ret) {
1443                 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1444                 goto err2;
1445         }
1446
1447         ret = notice_init();
1448         if (ret) {
1449                 printk(KERN_ERR "Couldn't initialize notice handling\n");
1450                 goto err3;
1451         }
1452
1453         ret = sa_db_init();
1454         if (ret) {
1455                 printk(KERN_ERR "Couldn't initialize local SA\n");
1456                 goto err4;
1457         }
1458
1459         return 0;
1460 err4:
1461         notice_cleanup();
1462 err3:
1463         mcast_cleanup();
1464 err2:
1465         ib_unregister_client(&sa_client);
1466 err1:
1467         return ret;
1468 }
1469
1470 static void __exit ib_sa_cleanup(void)
1471 {
1472         sa_db_cleanup();
1473         mcast_cleanup();
1474         notice_cleanup();
1475         ib_unregister_client(&sa_client);
1476         idr_destroy(&query_idr);
1477 }
1478
1479 module_init_order(ib_sa_init, SI_ORDER_SECOND);
1480 module_exit(ib_sa_cleanup);