]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/infiniband/core/sa_query.c
Merge /pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6.git] / 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  * $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $
35  */
36
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/err.h>
40 #include <linux/random.h>
41 #include <linux/spinlock.h>
42 #include <linux/slab.h>
43 #include <linux/pci.h>
44 #include <linux/dma-mapping.h>
45 #include <linux/kref.h>
46 #include <linux/idr.h>
47 #include <linux/workqueue.h>
48
49 #include <rdma/ib_pack.h>
50 #include <rdma/ib_cache.h>
51 #include "sa.h"
52
53 MODULE_AUTHOR("Roland Dreier");
54 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
55 MODULE_LICENSE("Dual BSD/GPL");
56
57 struct ib_sa_sm_ah {
58         struct ib_ah        *ah;
59         struct kref          ref;
60         u8                   src_path_mask;
61 };
62
63 struct ib_sa_port {
64         struct ib_mad_agent *agent;
65         struct ib_sa_sm_ah  *sm_ah;
66         struct work_struct   update_task;
67         spinlock_t           ah_lock;
68         u8                   port_num;
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 static void ib_sa_add_one(struct ib_device *device);
106 static void ib_sa_remove_one(struct ib_device *device);
107
108 static struct ib_client sa_client = {
109         .name   = "sa",
110         .add    = ib_sa_add_one,
111         .remove = ib_sa_remove_one
112 };
113
114 static spinlock_t idr_lock;
115 static DEFINE_IDR(query_idr);
116
117 static spinlock_t tid_lock;
118 static u32 tid;
119
120 #define PATH_REC_FIELD(field) \
121         .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),          \
122         .struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,     \
123         .field_name          = "sa_path_rec:" #field
124
125 static const struct ib_field path_rec_table[] = {
126         { RESERVED,
127           .offset_words = 0,
128           .offset_bits  = 0,
129           .size_bits    = 32 },
130         { RESERVED,
131           .offset_words = 1,
132           .offset_bits  = 0,
133           .size_bits    = 32 },
134         { PATH_REC_FIELD(dgid),
135           .offset_words = 2,
136           .offset_bits  = 0,
137           .size_bits    = 128 },
138         { PATH_REC_FIELD(sgid),
139           .offset_words = 6,
140           .offset_bits  = 0,
141           .size_bits    = 128 },
142         { PATH_REC_FIELD(dlid),
143           .offset_words = 10,
144           .offset_bits  = 0,
145           .size_bits    = 16 },
146         { PATH_REC_FIELD(slid),
147           .offset_words = 10,
148           .offset_bits  = 16,
149           .size_bits    = 16 },
150         { PATH_REC_FIELD(raw_traffic),
151           .offset_words = 11,
152           .offset_bits  = 0,
153           .size_bits    = 1 },
154         { RESERVED,
155           .offset_words = 11,
156           .offset_bits  = 1,
157           .size_bits    = 3 },
158         { PATH_REC_FIELD(flow_label),
159           .offset_words = 11,
160           .offset_bits  = 4,
161           .size_bits    = 20 },
162         { PATH_REC_FIELD(hop_limit),
163           .offset_words = 11,
164           .offset_bits  = 24,
165           .size_bits    = 8 },
166         { PATH_REC_FIELD(traffic_class),
167           .offset_words = 12,
168           .offset_bits  = 0,
169           .size_bits    = 8 },
170         { PATH_REC_FIELD(reversible),
171           .offset_words = 12,
172           .offset_bits  = 8,
173           .size_bits    = 1 },
174         { PATH_REC_FIELD(numb_path),
175           .offset_words = 12,
176           .offset_bits  = 9,
177           .size_bits    = 7 },
178         { PATH_REC_FIELD(pkey),
179           .offset_words = 12,
180           .offset_bits  = 16,
181           .size_bits    = 16 },
182         { RESERVED,
183           .offset_words = 13,
184           .offset_bits  = 0,
185           .size_bits    = 12 },
186         { PATH_REC_FIELD(sl),
187           .offset_words = 13,
188           .offset_bits  = 12,
189           .size_bits    = 4 },
190         { PATH_REC_FIELD(mtu_selector),
191           .offset_words = 13,
192           .offset_bits  = 16,
193           .size_bits    = 2 },
194         { PATH_REC_FIELD(mtu),
195           .offset_words = 13,
196           .offset_bits  = 18,
197           .size_bits    = 6 },
198         { PATH_REC_FIELD(rate_selector),
199           .offset_words = 13,
200           .offset_bits  = 24,
201           .size_bits    = 2 },
202         { PATH_REC_FIELD(rate),
203           .offset_words = 13,
204           .offset_bits  = 26,
205           .size_bits    = 6 },
206         { PATH_REC_FIELD(packet_life_time_selector),
207           .offset_words = 14,
208           .offset_bits  = 0,
209           .size_bits    = 2 },
210         { PATH_REC_FIELD(packet_life_time),
211           .offset_words = 14,
212           .offset_bits  = 2,
213           .size_bits    = 6 },
214         { PATH_REC_FIELD(preference),
215           .offset_words = 14,
216           .offset_bits  = 8,
217           .size_bits    = 8 },
218         { RESERVED,
219           .offset_words = 14,
220           .offset_bits  = 16,
221           .size_bits    = 48 },
222 };
223
224 #define MCMEMBER_REC_FIELD(field) \
225         .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field),      \
226         .struct_size_bytes   = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \
227         .field_name          = "sa_mcmember_rec:" #field
228
229 static const struct ib_field mcmember_rec_table[] = {
230         { MCMEMBER_REC_FIELD(mgid),
231           .offset_words = 0,
232           .offset_bits  = 0,
233           .size_bits    = 128 },
234         { MCMEMBER_REC_FIELD(port_gid),
235           .offset_words = 4,
236           .offset_bits  = 0,
237           .size_bits    = 128 },
238         { MCMEMBER_REC_FIELD(qkey),
239           .offset_words = 8,
240           .offset_bits  = 0,
241           .size_bits    = 32 },
242         { MCMEMBER_REC_FIELD(mlid),
243           .offset_words = 9,
244           .offset_bits  = 0,
245           .size_bits    = 16 },
246         { MCMEMBER_REC_FIELD(mtu_selector),
247           .offset_words = 9,
248           .offset_bits  = 16,
249           .size_bits    = 2 },
250         { MCMEMBER_REC_FIELD(mtu),
251           .offset_words = 9,
252           .offset_bits  = 18,
253           .size_bits    = 6 },
254         { MCMEMBER_REC_FIELD(traffic_class),
255           .offset_words = 9,
256           .offset_bits  = 24,
257           .size_bits    = 8 },
258         { MCMEMBER_REC_FIELD(pkey),
259           .offset_words = 10,
260           .offset_bits  = 0,
261           .size_bits    = 16 },
262         { MCMEMBER_REC_FIELD(rate_selector),
263           .offset_words = 10,
264           .offset_bits  = 16,
265           .size_bits    = 2 },
266         { MCMEMBER_REC_FIELD(rate),
267           .offset_words = 10,
268           .offset_bits  = 18,
269           .size_bits    = 6 },
270         { MCMEMBER_REC_FIELD(packet_life_time_selector),
271           .offset_words = 10,
272           .offset_bits  = 24,
273           .size_bits    = 2 },
274         { MCMEMBER_REC_FIELD(packet_life_time),
275           .offset_words = 10,
276           .offset_bits  = 26,
277           .size_bits    = 6 },
278         { MCMEMBER_REC_FIELD(sl),
279           .offset_words = 11,
280           .offset_bits  = 0,
281           .size_bits    = 4 },
282         { MCMEMBER_REC_FIELD(flow_label),
283           .offset_words = 11,
284           .offset_bits  = 4,
285           .size_bits    = 20 },
286         { MCMEMBER_REC_FIELD(hop_limit),
287           .offset_words = 11,
288           .offset_bits  = 24,
289           .size_bits    = 8 },
290         { MCMEMBER_REC_FIELD(scope),
291           .offset_words = 12,
292           .offset_bits  = 0,
293           .size_bits    = 4 },
294         { MCMEMBER_REC_FIELD(join_state),
295           .offset_words = 12,
296           .offset_bits  = 4,
297           .size_bits    = 4 },
298         { MCMEMBER_REC_FIELD(proxy_join),
299           .offset_words = 12,
300           .offset_bits  = 8,
301           .size_bits    = 1 },
302         { RESERVED,
303           .offset_words = 12,
304           .offset_bits  = 9,
305           .size_bits    = 23 },
306 };
307
308 #define SERVICE_REC_FIELD(field) \
309         .struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),       \
310         .struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,  \
311         .field_name          = "sa_service_rec:" #field
312
313 static const struct ib_field service_rec_table[] = {
314         { SERVICE_REC_FIELD(id),
315           .offset_words = 0,
316           .offset_bits  = 0,
317           .size_bits    = 64 },
318         { SERVICE_REC_FIELD(gid),
319           .offset_words = 2,
320           .offset_bits  = 0,
321           .size_bits    = 128 },
322         { SERVICE_REC_FIELD(pkey),
323           .offset_words = 6,
324           .offset_bits  = 0,
325           .size_bits    = 16 },
326         { SERVICE_REC_FIELD(lease),
327           .offset_words = 7,
328           .offset_bits  = 0,
329           .size_bits    = 32 },
330         { SERVICE_REC_FIELD(key),
331           .offset_words = 8,
332           .offset_bits  = 0,
333           .size_bits    = 128 },
334         { SERVICE_REC_FIELD(name),
335           .offset_words = 12,
336           .offset_bits  = 0,
337           .size_bits    = 64*8 },
338         { SERVICE_REC_FIELD(data8),
339           .offset_words = 28,
340           .offset_bits  = 0,
341           .size_bits    = 16*8 },
342         { SERVICE_REC_FIELD(data16),
343           .offset_words = 32,
344           .offset_bits  = 0,
345           .size_bits    = 8*16 },
346         { SERVICE_REC_FIELD(data32),
347           .offset_words = 36,
348           .offset_bits  = 0,
349           .size_bits    = 4*32 },
350         { SERVICE_REC_FIELD(data64),
351           .offset_words = 40,
352           .offset_bits  = 0,
353           .size_bits    = 2*64 },
354 };
355
356 static void free_sm_ah(struct kref *kref)
357 {
358         struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
359
360         ib_destroy_ah(sm_ah->ah);
361         kfree(sm_ah);
362 }
363
364 static void update_sm_ah(struct work_struct *work)
365 {
366         struct ib_sa_port *port =
367                 container_of(work, struct ib_sa_port, update_task);
368         struct ib_sa_sm_ah *new_ah, *old_ah;
369         struct ib_port_attr port_attr;
370         struct ib_ah_attr   ah_attr;
371
372         if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
373                 printk(KERN_WARNING "Couldn't query port\n");
374                 return;
375         }
376
377         new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
378         if (!new_ah) {
379                 printk(KERN_WARNING "Couldn't allocate new SM AH\n");
380                 return;
381         }
382
383         kref_init(&new_ah->ref);
384         new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
385
386         memset(&ah_attr, 0, sizeof ah_attr);
387         ah_attr.dlid     = port_attr.sm_lid;
388         ah_attr.sl       = port_attr.sm_sl;
389         ah_attr.port_num = port->port_num;
390
391         new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
392         if (IS_ERR(new_ah->ah)) {
393                 printk(KERN_WARNING "Couldn't create new SM AH\n");
394                 kfree(new_ah);
395                 return;
396         }
397
398         spin_lock_irq(&port->ah_lock);
399         old_ah = port->sm_ah;
400         port->sm_ah = new_ah;
401         spin_unlock_irq(&port->ah_lock);
402
403         if (old_ah)
404                 kref_put(&old_ah->ref, free_sm_ah);
405 }
406
407 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
408 {
409         if (event->event == IB_EVENT_PORT_ERR    ||
410             event->event == IB_EVENT_PORT_ACTIVE ||
411             event->event == IB_EVENT_LID_CHANGE  ||
412             event->event == IB_EVENT_PKEY_CHANGE ||
413             event->event == IB_EVENT_SM_CHANGE   ||
414             event->event == IB_EVENT_CLIENT_REREGISTER) {
415                 struct ib_sa_device *sa_dev;
416                 sa_dev = container_of(handler, typeof(*sa_dev), event_handler);
417
418                 schedule_work(&sa_dev->port[event->element.port_num -
419                                             sa_dev->start_port].update_task);
420         }
421 }
422
423 void ib_sa_register_client(struct ib_sa_client *client)
424 {
425         atomic_set(&client->users, 1);
426         init_completion(&client->comp);
427 }
428 EXPORT_SYMBOL(ib_sa_register_client);
429
430 void ib_sa_unregister_client(struct ib_sa_client *client)
431 {
432         ib_sa_client_put(client);
433         wait_for_completion(&client->comp);
434 }
435 EXPORT_SYMBOL(ib_sa_unregister_client);
436
437 /**
438  * ib_sa_cancel_query - try to cancel an SA query
439  * @id:ID of query to cancel
440  * @query:query pointer to cancel
441  *
442  * Try to cancel an SA query.  If the id and query don't match up or
443  * the query has already completed, nothing is done.  Otherwise the
444  * query is canceled and will complete with a status of -EINTR.
445  */
446 void ib_sa_cancel_query(int id, struct ib_sa_query *query)
447 {
448         unsigned long flags;
449         struct ib_mad_agent *agent;
450         struct ib_mad_send_buf *mad_buf;
451
452         spin_lock_irqsave(&idr_lock, flags);
453         if (idr_find(&query_idr, id) != query) {
454                 spin_unlock_irqrestore(&idr_lock, flags);
455                 return;
456         }
457         agent = query->port->agent;
458         mad_buf = query->mad_buf;
459         spin_unlock_irqrestore(&idr_lock, flags);
460
461         ib_cancel_mad(agent, mad_buf);
462 }
463 EXPORT_SYMBOL(ib_sa_cancel_query);
464
465 static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
466 {
467         struct ib_sa_device *sa_dev;
468         struct ib_sa_port   *port;
469         unsigned long flags;
470         u8 src_path_mask;
471
472         sa_dev = ib_get_client_data(device, &sa_client);
473         if (!sa_dev)
474                 return 0x7f;
475
476         port  = &sa_dev->port[port_num - sa_dev->start_port];
477         spin_lock_irqsave(&port->ah_lock, flags);
478         src_path_mask = port->sm_ah ? port->sm_ah->src_path_mask : 0x7f;
479         spin_unlock_irqrestore(&port->ah_lock, flags);
480
481         return src_path_mask;
482 }
483
484 int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
485                          struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr)
486 {
487         int ret;
488         u16 gid_index;
489
490         memset(ah_attr, 0, sizeof *ah_attr);
491         ah_attr->dlid = be16_to_cpu(rec->dlid);
492         ah_attr->sl = rec->sl;
493         ah_attr->src_path_bits = be16_to_cpu(rec->slid) &
494                                  get_src_path_mask(device, port_num);
495         ah_attr->port_num = port_num;
496         ah_attr->static_rate = rec->rate;
497
498         if (rec->hop_limit > 1) {
499                 ah_attr->ah_flags = IB_AH_GRH;
500                 ah_attr->grh.dgid = rec->dgid;
501
502                 ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
503                                          &gid_index);
504                 if (ret)
505                         return ret;
506
507                 ah_attr->grh.sgid_index    = gid_index;
508                 ah_attr->grh.flow_label    = be32_to_cpu(rec->flow_label);
509                 ah_attr->grh.hop_limit     = rec->hop_limit;
510                 ah_attr->grh.traffic_class = rec->traffic_class;
511         }
512         return 0;
513 }
514 EXPORT_SYMBOL(ib_init_ah_from_path);
515
516 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
517 {
518         unsigned long flags;
519
520         memset(mad, 0, sizeof *mad);
521
522         mad->mad_hdr.base_version  = IB_MGMT_BASE_VERSION;
523         mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_SUBN_ADM;
524         mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
525
526         spin_lock_irqsave(&tid_lock, flags);
527         mad->mad_hdr.tid           =
528                 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
529         spin_unlock_irqrestore(&tid_lock, flags);
530 }
531
532 static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
533 {
534         unsigned long flags;
535         int ret, id;
536
537 retry:
538         if (!idr_pre_get(&query_idr, gfp_mask))
539                 return -ENOMEM;
540         spin_lock_irqsave(&idr_lock, flags);
541         ret = idr_get_new(&query_idr, query, &id);
542         spin_unlock_irqrestore(&idr_lock, flags);
543         if (ret == -EAGAIN)
544                 goto retry;
545         if (ret)
546                 return ret;
547
548         query->mad_buf->timeout_ms  = timeout_ms;
549         query->mad_buf->context[0] = query;
550         query->id = id;
551
552         spin_lock_irqsave(&query->port->ah_lock, flags);
553         kref_get(&query->port->sm_ah->ref);
554         query->sm_ah = query->port->sm_ah;
555         spin_unlock_irqrestore(&query->port->ah_lock, flags);
556
557         query->mad_buf->ah = query->sm_ah->ah;
558
559         ret = ib_post_send_mad(query->mad_buf, NULL);
560         if (ret) {
561                 spin_lock_irqsave(&idr_lock, flags);
562                 idr_remove(&query_idr, id);
563                 spin_unlock_irqrestore(&idr_lock, flags);
564
565                 kref_put(&query->sm_ah->ref, free_sm_ah);
566         }
567
568         /*
569          * It's not safe to dereference query any more, because the
570          * send may already have completed and freed the query in
571          * another context.
572          */
573         return ret ? ret : id;
574 }
575
576 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
577                                     int status,
578                                     struct ib_sa_mad *mad)
579 {
580         struct ib_sa_path_query *query =
581                 container_of(sa_query, struct ib_sa_path_query, sa_query);
582
583         if (mad) {
584                 struct ib_sa_path_rec rec;
585
586                 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
587                           mad->data, &rec);
588                 query->callback(status, &rec, query->context);
589         } else
590                 query->callback(status, NULL, query->context);
591 }
592
593 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
594 {
595         kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
596 }
597
598 /**
599  * ib_sa_path_rec_get - Start a Path get query
600  * @client:SA client
601  * @device:device to send query on
602  * @port_num: port number to send query on
603  * @rec:Path Record to send in query
604  * @comp_mask:component mask to send in query
605  * @timeout_ms:time to wait for response
606  * @gfp_mask:GFP mask to use for internal allocations
607  * @callback:function called when query completes, times out or is
608  * canceled
609  * @context:opaque user context passed to callback
610  * @sa_query:query context, used to cancel query
611  *
612  * Send a Path Record Get query to the SA to look up a path.  The
613  * callback function will be called when the query completes (or
614  * fails); status is 0 for a successful response, -EINTR if the query
615  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
616  * occurred sending the query.  The resp parameter of the callback is
617  * only valid if status is 0.
618  *
619  * If the return value of ib_sa_path_rec_get() is negative, it is an
620  * error code.  Otherwise it is a query ID that can be used to cancel
621  * the query.
622  */
623 int ib_sa_path_rec_get(struct ib_sa_client *client,
624                        struct ib_device *device, u8 port_num,
625                        struct ib_sa_path_rec *rec,
626                        ib_sa_comp_mask comp_mask,
627                        int timeout_ms, gfp_t gfp_mask,
628                        void (*callback)(int status,
629                                         struct ib_sa_path_rec *resp,
630                                         void *context),
631                        void *context,
632                        struct ib_sa_query **sa_query)
633 {
634         struct ib_sa_path_query *query;
635         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
636         struct ib_sa_port   *port;
637         struct ib_mad_agent *agent;
638         struct ib_sa_mad *mad;
639         int ret;
640
641         if (!sa_dev)
642                 return -ENODEV;
643
644         port  = &sa_dev->port[port_num - sa_dev->start_port];
645         agent = port->agent;
646
647         query = kmalloc(sizeof *query, gfp_mask);
648         if (!query)
649                 return -ENOMEM;
650
651         query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
652                                                      0, IB_MGMT_SA_HDR,
653                                                      IB_MGMT_SA_DATA, gfp_mask);
654         if (!query->sa_query.mad_buf) {
655                 ret = -ENOMEM;
656                 goto err1;
657         }
658
659         ib_sa_client_get(client);
660         query->sa_query.client = client;
661         query->callback        = callback;
662         query->context         = context;
663
664         mad = query->sa_query.mad_buf->mad;
665         init_mad(mad, agent);
666
667         query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
668         query->sa_query.release  = ib_sa_path_rec_release;
669         query->sa_query.port     = port;
670         mad->mad_hdr.method      = IB_MGMT_METHOD_GET;
671         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_PATH_REC);
672         mad->sa_hdr.comp_mask    = comp_mask;
673
674         ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
675
676         *sa_query = &query->sa_query;
677
678         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
679         if (ret < 0)
680                 goto err2;
681
682         return ret;
683
684 err2:
685         *sa_query = NULL;
686         ib_sa_client_put(query->sa_query.client);
687         ib_free_send_mad(query->sa_query.mad_buf);
688
689 err1:
690         kfree(query);
691         return ret;
692 }
693 EXPORT_SYMBOL(ib_sa_path_rec_get);
694
695 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
696                                     int status,
697                                     struct ib_sa_mad *mad)
698 {
699         struct ib_sa_service_query *query =
700                 container_of(sa_query, struct ib_sa_service_query, sa_query);
701
702         if (mad) {
703                 struct ib_sa_service_rec rec;
704
705                 ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
706                           mad->data, &rec);
707                 query->callback(status, &rec, query->context);
708         } else
709                 query->callback(status, NULL, query->context);
710 }
711
712 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
713 {
714         kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
715 }
716
717 /**
718  * ib_sa_service_rec_query - Start Service Record operation
719  * @client:SA client
720  * @device:device to send request on
721  * @port_num: port number to send request on
722  * @method:SA method - should be get, set, or delete
723  * @rec:Service Record to send in request
724  * @comp_mask:component mask to send in request
725  * @timeout_ms:time to wait for response
726  * @gfp_mask:GFP mask to use for internal allocations
727  * @callback:function called when request completes, times out or is
728  * canceled
729  * @context:opaque user context passed to callback
730  * @sa_query:request context, used to cancel request
731  *
732  * Send a Service Record set/get/delete to the SA to register,
733  * unregister or query a service record.
734  * The callback function will be called when the request completes (or
735  * fails); status is 0 for a successful response, -EINTR if the query
736  * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
737  * occurred sending the query.  The resp parameter of the callback is
738  * only valid if status is 0.
739  *
740  * If the return value of ib_sa_service_rec_query() is negative, it is an
741  * error code.  Otherwise it is a request ID that can be used to cancel
742  * the query.
743  */
744 int ib_sa_service_rec_query(struct ib_sa_client *client,
745                             struct ib_device *device, u8 port_num, u8 method,
746                             struct ib_sa_service_rec *rec,
747                             ib_sa_comp_mask comp_mask,
748                             int timeout_ms, gfp_t gfp_mask,
749                             void (*callback)(int status,
750                                              struct ib_sa_service_rec *resp,
751                                              void *context),
752                             void *context,
753                             struct ib_sa_query **sa_query)
754 {
755         struct ib_sa_service_query *query;
756         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
757         struct ib_sa_port   *port;
758         struct ib_mad_agent *agent;
759         struct ib_sa_mad *mad;
760         int ret;
761
762         if (!sa_dev)
763                 return -ENODEV;
764
765         port  = &sa_dev->port[port_num - sa_dev->start_port];
766         agent = port->agent;
767
768         if (method != IB_MGMT_METHOD_GET &&
769             method != IB_MGMT_METHOD_SET &&
770             method != IB_SA_METHOD_DELETE)
771                 return -EINVAL;
772
773         query = kmalloc(sizeof *query, gfp_mask);
774         if (!query)
775                 return -ENOMEM;
776
777         query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
778                                                      0, IB_MGMT_SA_HDR,
779                                                      IB_MGMT_SA_DATA, gfp_mask);
780         if (!query->sa_query.mad_buf) {
781                 ret = -ENOMEM;
782                 goto err1;
783         }
784
785         ib_sa_client_get(client);
786         query->sa_query.client = client;
787         query->callback        = callback;
788         query->context         = context;
789
790         mad = query->sa_query.mad_buf->mad;
791         init_mad(mad, agent);
792
793         query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
794         query->sa_query.release  = ib_sa_service_rec_release;
795         query->sa_query.port     = port;
796         mad->mad_hdr.method      = method;
797         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
798         mad->sa_hdr.comp_mask    = comp_mask;
799
800         ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
801                 rec, mad->data);
802
803         *sa_query = &query->sa_query;
804
805         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
806         if (ret < 0)
807                 goto err2;
808
809         return ret;
810
811 err2:
812         *sa_query = NULL;
813         ib_sa_client_put(query->sa_query.client);
814         ib_free_send_mad(query->sa_query.mad_buf);
815
816 err1:
817         kfree(query);
818         return ret;
819 }
820 EXPORT_SYMBOL(ib_sa_service_rec_query);
821
822 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
823                                         int status,
824                                         struct ib_sa_mad *mad)
825 {
826         struct ib_sa_mcmember_query *query =
827                 container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
828
829         if (mad) {
830                 struct ib_sa_mcmember_rec rec;
831
832                 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
833                           mad->data, &rec);
834                 query->callback(status, &rec, query->context);
835         } else
836                 query->callback(status, NULL, query->context);
837 }
838
839 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
840 {
841         kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
842 }
843
844 int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
845                              struct ib_device *device, u8 port_num,
846                              u8 method,
847                              struct ib_sa_mcmember_rec *rec,
848                              ib_sa_comp_mask comp_mask,
849                              int timeout_ms, gfp_t gfp_mask,
850                              void (*callback)(int status,
851                                               struct ib_sa_mcmember_rec *resp,
852                                               void *context),
853                              void *context,
854                              struct ib_sa_query **sa_query)
855 {
856         struct ib_sa_mcmember_query *query;
857         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
858         struct ib_sa_port   *port;
859         struct ib_mad_agent *agent;
860         struct ib_sa_mad *mad;
861         int ret;
862
863         if (!sa_dev)
864                 return -ENODEV;
865
866         port  = &sa_dev->port[port_num - sa_dev->start_port];
867         agent = port->agent;
868
869         query = kmalloc(sizeof *query, gfp_mask);
870         if (!query)
871                 return -ENOMEM;
872
873         query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
874                                                      0, IB_MGMT_SA_HDR,
875                                                      IB_MGMT_SA_DATA, gfp_mask);
876         if (!query->sa_query.mad_buf) {
877                 ret = -ENOMEM;
878                 goto err1;
879         }
880
881         ib_sa_client_get(client);
882         query->sa_query.client = client;
883         query->callback        = callback;
884         query->context         = context;
885
886         mad = query->sa_query.mad_buf->mad;
887         init_mad(mad, agent);
888
889         query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
890         query->sa_query.release  = ib_sa_mcmember_rec_release;
891         query->sa_query.port     = port;
892         mad->mad_hdr.method      = method;
893         mad->mad_hdr.attr_id     = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
894         mad->sa_hdr.comp_mask    = comp_mask;
895
896         ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
897                 rec, mad->data);
898
899         *sa_query = &query->sa_query;
900
901         ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
902         if (ret < 0)
903                 goto err2;
904
905         return ret;
906
907 err2:
908         *sa_query = NULL;
909         ib_sa_client_put(query->sa_query.client);
910         ib_free_send_mad(query->sa_query.mad_buf);
911
912 err1:
913         kfree(query);
914         return ret;
915 }
916
917 static void send_handler(struct ib_mad_agent *agent,
918                          struct ib_mad_send_wc *mad_send_wc)
919 {
920         struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
921         unsigned long flags;
922
923         if (query->callback)
924                 switch (mad_send_wc->status) {
925                 case IB_WC_SUCCESS:
926                         /* No callback -- already got recv */
927                         break;
928                 case IB_WC_RESP_TIMEOUT_ERR:
929                         query->callback(query, -ETIMEDOUT, NULL);
930                         break;
931                 case IB_WC_WR_FLUSH_ERR:
932                         query->callback(query, -EINTR, NULL);
933                         break;
934                 default:
935                         query->callback(query, -EIO, NULL);
936                         break;
937                 }
938
939         spin_lock_irqsave(&idr_lock, flags);
940         idr_remove(&query_idr, query->id);
941         spin_unlock_irqrestore(&idr_lock, flags);
942
943         ib_free_send_mad(mad_send_wc->send_buf);
944         kref_put(&query->sm_ah->ref, free_sm_ah);
945         ib_sa_client_put(query->client);
946         query->release(query);
947 }
948
949 static void recv_handler(struct ib_mad_agent *mad_agent,
950                          struct ib_mad_recv_wc *mad_recv_wc)
951 {
952         struct ib_sa_query *query;
953         struct ib_mad_send_buf *mad_buf;
954
955         mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
956         query = mad_buf->context[0];
957
958         if (query->callback) {
959                 if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
960                         query->callback(query,
961                                         mad_recv_wc->recv_buf.mad->mad_hdr.status ?
962                                         -EINVAL : 0,
963                                         (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
964                 else
965                         query->callback(query, -EIO, NULL);
966         }
967
968         ib_free_recv_mad(mad_recv_wc);
969 }
970
971 static void ib_sa_add_one(struct ib_device *device)
972 {
973         struct ib_sa_device *sa_dev;
974         int s, e, i;
975
976         if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
977                 return;
978
979         if (device->node_type == RDMA_NODE_IB_SWITCH)
980                 s = e = 0;
981         else {
982                 s = 1;
983                 e = device->phys_port_cnt;
984         }
985
986         sa_dev = kmalloc(sizeof *sa_dev +
987                          (e - s + 1) * sizeof (struct ib_sa_port),
988                          GFP_KERNEL);
989         if (!sa_dev)
990                 return;
991
992         sa_dev->start_port = s;
993         sa_dev->end_port   = e;
994
995         for (i = 0; i <= e - s; ++i) {
996                 sa_dev->port[i].sm_ah    = NULL;
997                 sa_dev->port[i].port_num = i + s;
998                 spin_lock_init(&sa_dev->port[i].ah_lock);
999
1000                 sa_dev->port[i].agent =
1001                         ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1002                                               NULL, 0, send_handler,
1003                                               recv_handler, sa_dev);
1004                 if (IS_ERR(sa_dev->port[i].agent))
1005                         goto err;
1006
1007                 INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
1008         }
1009
1010         ib_set_client_data(device, &sa_client, sa_dev);
1011
1012         /*
1013          * We register our event handler after everything is set up,
1014          * and then update our cached info after the event handler is
1015          * registered to avoid any problems if a port changes state
1016          * during our initialization.
1017          */
1018
1019         INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
1020         if (ib_register_event_handler(&sa_dev->event_handler))
1021                 goto err;
1022
1023         for (i = 0; i <= e - s; ++i)
1024                 update_sm_ah(&sa_dev->port[i].update_task);
1025
1026         return;
1027
1028 err:
1029         while (--i >= 0)
1030                 ib_unregister_mad_agent(sa_dev->port[i].agent);
1031
1032         kfree(sa_dev);
1033
1034         return;
1035 }
1036
1037 static void ib_sa_remove_one(struct ib_device *device)
1038 {
1039         struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1040         int i;
1041
1042         if (!sa_dev)
1043                 return;
1044
1045         ib_unregister_event_handler(&sa_dev->event_handler);
1046
1047         flush_scheduled_work();
1048
1049         for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
1050                 ib_unregister_mad_agent(sa_dev->port[i].agent);
1051                 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
1052         }
1053
1054         kfree(sa_dev);
1055 }
1056
1057 static int __init ib_sa_init(void)
1058 {
1059         int ret;
1060
1061         spin_lock_init(&idr_lock);
1062         spin_lock_init(&tid_lock);
1063
1064         get_random_bytes(&tid, sizeof tid);
1065
1066         ret = ib_register_client(&sa_client);
1067         if (ret) {
1068                 printk(KERN_ERR "Couldn't register ib_sa client\n");
1069                 goto err1;
1070         }
1071
1072         ret = mcast_init();
1073         if (ret) {
1074                 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1075                 goto err2;
1076         }
1077
1078         return 0;
1079 err2:
1080         ib_unregister_client(&sa_client);
1081 err1:
1082         return ret;
1083 }
1084
1085 static void __exit ib_sa_cleanup(void)
1086 {
1087         mcast_cleanup();
1088         ib_unregister_client(&sa_client);
1089         idr_destroy(&query_idr);
1090 }
1091
1092 module_init(ib_sa_init);
1093 module_exit(ib_sa_cleanup);