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.11.8)


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