Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/infiniband/core/sa_query.c (Version 2.6.25) and /linux/drivers/infiniband/core/sa_query.c (Version 2.6.31.13)


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