Merge head 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6
[linux-2.6] / 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  *
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 <ib_pack.h>
48 #include <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);