[IBAL] sync flags bits between free and chk versions
[mirror/winof/.git] / core / al / al_mgr_shared.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 #include "al.h"\r
34 #include "al_common.h"\r
35 #include "al_debug.h"\r
36 #if defined(EVENT_TRACING)\r
37 #ifdef offsetof\r
38 #undef offsetof\r
39 #endif\r
40 #include "al_mgr_shared.tmh"\r
41 #endif\r
42 #include "al_ci_ca.h"\r
43 #include "ib_common.h"\r
44 #include "al_mgr.h"\r
45 #include "al_pnp.h"\r
46 \r
47 ib_al_handle_t                  gh_al = NULL;\r
48 ib_pool_handle_t                gh_mad_pool = NULL;\r
49 al_mgr_t                                *gp_al_mgr = NULL;\r
50 cl_async_proc_t                 *gp_async_proc_mgr = NULL;\r
51 cl_async_proc_t                 *gp_async_pnp_mgr = NULL;\r
52 \r
53 \r
54 \r
55 void\r
56 print_al_obj(\r
57         IN                              al_obj_t * const                        p_obj )\r
58 {\r
59         CL_ASSERT( p_obj );\r
60 \r
61         UNUSED_PARAM( p_obj );\r
62 \r
63         AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
64                 ("AL object %016I64x(%s), parent: %016I64x ref_cnt: %d\n",\r
65                 (LONG_PTR)p_obj, ib_get_obj_type( p_obj ),\r
66                 (LONG_PTR)p_obj->p_parent_obj, p_obj->ref_cnt) );\r
67 }\r
68 \r
69 \r
70 void\r
71 print_al_objs(\r
72         IN              const   ib_al_handle_t                          h_al )\r
73 {\r
74         al_obj_t                *p_obj;\r
75         cl_list_item_t  *p_list_item;\r
76 \r
77         if( !gp_al_mgr )\r
78                 return;\r
79 \r
80         /* Display all access layer objects. */\r
81         for( p_list_item = cl_qlist_head( &gp_al_mgr->al_obj_list );\r
82                  p_list_item != cl_qlist_end( &gp_al_mgr->al_obj_list );\r
83                  p_list_item = cl_qlist_next( p_list_item ) )\r
84         {\r
85                 p_obj = PARENT_STRUCT( p_list_item, al_obj_t, list_item );\r
86                 if( !h_al || p_obj->h_al == h_al )\r
87                         print_al_obj( p_obj );\r
88         }\r
89 }\r
90 \r
91 \r
92 \r
93 void\r
94 print_tail_al_objs()\r
95 {\r
96         al_obj_t                *p_obj;\r
97         cl_list_item_t  *p_list_item;\r
98         int                             count = 3;\r
99 \r
100         if( !gp_al_mgr )\r
101                 return;\r
102 \r
103         /* Display all access layer objects. */\r
104         for( p_list_item = cl_qlist_tail( &gp_al_mgr->al_obj_list );\r
105                  p_list_item != cl_qlist_end( &gp_al_mgr->al_obj_list ) && count;\r
106                  p_list_item = cl_qlist_prev( p_list_item ) )\r
107         {\r
108                 p_obj = PARENT_STRUCT( p_list_item, al_obj_t, list_item );\r
109                 print_al_obj( p_obj );\r
110                 count--;\r
111         }\r
112 }\r
113 \r
114 \r
115 \r
116 /*\r
117  * Search all available CI CAs in the system to see if one exists with the\r
118  * given GUID.\r
119  */\r
120 al_ci_ca_t*\r
121 find_ci_ca(\r
122         IN              const   ib_net64_t                                      ci_ca_guid )\r
123 {\r
124         cl_list_item_t          *p_list_item;\r
125         al_ci_ca_t                      *p_ci_ca;\r
126 \r
127         AL_ENTER( AL_DBG_MGR );\r
128 \r
129         for( p_list_item = cl_qlist_head( &gp_al_mgr->ci_ca_list );\r
130                  p_list_item != cl_qlist_end( &gp_al_mgr->ci_ca_list );\r
131                  p_list_item = cl_qlist_next( p_list_item ) )\r
132         {\r
133                 p_ci_ca = PARENT_STRUCT( p_list_item, al_ci_ca_t, list_item );\r
134                 if( p_ci_ca->verbs.guid == ci_ca_guid &&\r
135                         p_ci_ca->obj.state == CL_INITIALIZED )\r
136                 {\r
137                         AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_MGR,\r
138                                 ("find_ci_ca:CA guid %I64x.\n", ci_ca_guid) );\r
139                         AL_EXIT( AL_DBG_MGR );\r
140                         return p_ci_ca;\r
141                 }\r
142         }\r
143 \r
144         AL_EXIT( AL_DBG_MGR );\r
145         return NULL;\r
146 }\r
147 \r
148 \r
149 \r
150 al_ci_ca_t*\r
151 acquire_ci_ca(\r
152         IN              const   ib_net64_t                                      ci_ca_guid,\r
153         IN              const   ib_ca_handle_t                          h_ca )\r
154 {\r
155         al_ci_ca_t                      *p_ci_ca;\r
156 \r
157         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
158         p_ci_ca = find_ci_ca( ci_ca_guid );\r
159         if( !p_ci_ca )\r
160         {\r
161                 cl_spinlock_release( &gp_al_mgr->obj.lock );\r
162                 return NULL;\r
163         }\r
164 \r
165         add_ca( p_ci_ca, h_ca );\r
166         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
167         return p_ci_ca;\r
168 }\r
169 \r
170 \r
171 \r
172 void\r
173 release_ci_ca(\r
174         IN              const   ib_ca_handle_t                          h_ca )\r
175 {\r
176         AL_ENTER( AL_DBG_MGR );\r
177         remove_ca( h_ca );\r
178         AL_EXIT( AL_DBG_MGR );\r
179 }\r
180 \r
181 \r
182 \r
183 void\r
184 add_ci_ca(\r
185         IN                              al_ci_ca_t* const                       p_ci_ca )\r
186 {\r
187         AL_ENTER( AL_DBG_MGR );\r
188         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
189         cl_qlist_insert_tail( &gp_al_mgr->ci_ca_list, &p_ci_ca->list_item );\r
190         ref_al_obj( &gp_al_mgr->obj );\r
191         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
192         AL_EXIT( AL_DBG_MGR );\r
193 }\r
194 \r
195 \r
196 void\r
197 remove_ci_ca(\r
198         IN                              al_ci_ca_t* const                       p_ci_ca )\r
199 {\r
200         AL_ENTER( AL_DBG_MGR );\r
201         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
202         cl_qlist_remove_item( &gp_al_mgr->ci_ca_list, &p_ci_ca->list_item );\r
203         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
204         deref_al_obj( &gp_al_mgr->obj );\r
205         AL_EXIT( AL_DBG_MGR );\r
206 }\r
207 \r
208 \r
209 \r
210 ib_ca_handle_t\r
211 acquire_ca(\r
212         IN              const   ib_net64_t                                      ci_ca_guid )\r
213 {\r
214         al_ci_ca_t                      *p_ci_ca;\r
215 \r
216         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
217         p_ci_ca = find_ci_ca( ci_ca_guid );\r
218         if( !p_ci_ca )\r
219         {\r
220                 cl_spinlock_release( &gp_al_mgr->obj.lock );\r
221                 return NULL;\r
222         }\r
223 \r
224         ref_al_obj( &p_ci_ca->h_ca->obj );\r
225         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
226         return p_ci_ca->h_ca;\r
227 }\r
228 \r
229 \r
230 \r
231 #define SEARCH_CA_GUID          (1)\r
232 #define SEARCH_PORT_GUID        (2)\r
233 \r
234 /*\r
235  * Return the GUID of CA with the given port GID.\r
236  */\r
237 \r
238 static ib_api_status_t\r
239 __get_guid_by_gid (\r
240         IN                              ib_al_handle_t                          h_al,\r
241         IN              const   ib_gid_t* const                         p_gid,\r
242         IN              const   uintn_t                                         type,\r
243                 OUT                     ib_net64_t* const                       p_guid )\r
244 {\r
245         ib_net64_t                      *p_guid_array = NULL;\r
246         uint32_t                        size;\r
247         uintn_t                         ca_ind, port_ind, gid_ind, ca_cnt;\r
248         ib_api_status_t         status = IB_SUCCESS;\r
249         ib_ca_attr_t            *p_ca_attr = NULL;\r
250         ib_port_attr_t          *p_port_attr = NULL;\r
251 \r
252         AL_ENTER( AL_DBG_MGR );\r
253 \r
254         CL_ASSERT( h_al && p_gid && p_guid );\r
255 \r
256         /* Get the number of CA GUIDs. */\r
257         ca_cnt = 0;\r
258         p_guid_array = NULL;\r
259         status = ib_get_ca_guids( h_al, p_guid_array, &ca_cnt );\r
260         if( status != IB_INSUFFICIENT_MEMORY )\r
261         {\r
262                 if( status == IB_SUCCESS )\r
263                 {\r
264                         status = IB_NOT_FOUND;  /* No CAs in the system */\r
265                 }\r
266                 goto end;\r
267         }\r
268 \r
269         /* Allocate an array to store the CA GUIDs. */\r
270         p_guid_array = cl_malloc( sizeof( ib_net64_t ) * ca_cnt );\r
271         if( !p_guid_array )\r
272         {\r
273                 status = IB_INSUFFICIENT_MEMORY;\r
274                 goto end;\r
275         }\r
276 \r
277         /* Get the list of CA GUIDs in the system. */\r
278         status = ib_get_ca_guids( h_al, p_guid_array, &ca_cnt );\r
279         if( status != IB_SUCCESS )\r
280                 goto end;\r
281 \r
282         /* Query each CA. */\r
283         size = 0;\r
284         p_ca_attr = NULL;\r
285         for( ca_ind = 0; ca_ind < ca_cnt; ca_ind++ )\r
286         {\r
287                 /* Query the CA and port information. */\r
288                 status = ib_query_ca_by_guid( h_al, p_guid_array[ca_ind],\r
289                         p_ca_attr, &size );\r
290 \r
291                 if( status == IB_INSUFFICIENT_MEMORY )\r
292                 {\r
293                         /* Allocate a larger buffer and requery. */\r
294                         if( p_ca_attr )\r
295                                 cl_free( p_ca_attr );\r
296 \r
297                         p_ca_attr = cl_malloc( size );\r
298                         if( !p_ca_attr )\r
299                         {\r
300                                 status = IB_INSUFFICIENT_MEMORY;\r
301                                 goto end;\r
302                         }\r
303 \r
304                         status = ib_query_ca_by_guid( h_al, p_guid_array[ca_ind],\r
305                                 p_ca_attr, &size );\r
306                 }\r
307 \r
308                 if( status != IB_SUCCESS )\r
309                         goto end;\r
310 \r
311                 /* Try to match the GID with one of the port's GIDs. */\r
312                 status = IB_NOT_FOUND;\r
313                 for( port_ind = 0; port_ind < p_ca_attr->num_ports; port_ind++ )\r
314                 {\r
315                         p_port_attr = &p_ca_attr->p_port_attr[port_ind];\r
316 \r
317                         for( gid_ind = 0; gid_ind < p_port_attr->num_gids; gid_ind++ )\r
318                         {\r
319                                 if( !cl_memcmp( &p_port_attr->p_gid_table[gid_ind], p_gid,\r
320                                         sizeof( ib_gid_t ) ) )\r
321                                 {\r
322                                         if ( type == SEARCH_CA_GUID )\r
323                                                 *p_guid = p_guid_array[ca_ind];\r
324                                         else\r
325                                                 *p_guid = p_port_attr->port_guid;\r
326                                         status = IB_SUCCESS;\r
327                                         goto end;\r
328                                 }\r
329                         }\r
330                 }\r
331         }\r
332 \r
333 end:\r
334         if ( p_ca_attr )\r
335                 cl_free ( p_ca_attr );\r
336         if ( p_guid_array )\r
337                 cl_free( p_guid_array );\r
338 \r
339         AL_EXIT( AL_DBG_MGR );\r
340         return status;\r
341 }\r
342 \r
343 \r
344 \r
345 ib_api_status_t\r
346 ib_get_ca_by_gid(\r
347         IN                              ib_al_handle_t                          h_al,\r
348         IN              const   ib_gid_t* const                         p_gid,\r
349                 OUT                     ib_net64_t* const                       p_ca_guid )\r
350 {\r
351         ib_api_status_t         status;\r
352 \r
353         AL_ENTER( AL_DBG_MGR );\r
354 \r
355         if( AL_OBJ_INVALID_HANDLE( h_al, AL_OBJ_TYPE_H_AL ) )\r
356         {\r
357                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_AL_HANDLE\n") );\r
358                 return IB_INVALID_AL_HANDLE;\r
359         }\r
360         if( !p_gid || !p_ca_guid )\r
361         {\r
362                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_PARAMETER\n") );\r
363                 return IB_INVALID_PARAMETER;\r
364         }\r
365 \r
366         status = __get_guid_by_gid( h_al, p_gid, SEARCH_CA_GUID, p_ca_guid );\r
367 \r
368         AL_EXIT( AL_DBG_MGR );\r
369         return status;\r
370 }\r
371 \r
372 \r
373 \r
374 ib_api_status_t\r
375 ib_get_port_by_gid(\r
376         IN                              ib_al_handle_t                          h_al,\r
377         IN              const   ib_gid_t* const                         p_gid,\r
378                 OUT                     ib_net64_t* const                       p_port_guid )\r
379 {\r
380         ib_api_status_t         status;\r
381 \r
382         AL_ENTER( AL_DBG_MGR );\r
383 \r
384         if( AL_OBJ_INVALID_HANDLE( h_al, AL_OBJ_TYPE_H_AL ) )\r
385         {\r
386                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_AL_HANDLE\n") );\r
387                 return IB_INVALID_AL_HANDLE;\r
388         }\r
389         if( !p_gid || !p_port_guid )\r
390         {\r
391                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_PARAMETER\n") );\r
392                 return IB_INVALID_PARAMETER;\r
393         }\r
394 \r
395         status = __get_guid_by_gid( h_al, p_gid, SEARCH_PORT_GUID, p_port_guid );\r
396 \r
397         AL_EXIT( AL_DBG_MGR );\r
398         return status;\r
399 }\r
400 \r
401 \r
402 \r
403 /*\r
404  * Return the GUIDs of all CAs the system.\r
405  */\r
406 ib_api_status_t\r
407 ib_get_ca_guids(\r
408         IN                              ib_al_handle_t                          h_al,\r
409                 OUT                     ib_net64_t* const                       p_guid_array OPTIONAL,\r
410         IN      OUT                     size_t* const                           p_guid_cnt )\r
411 {\r
412         cl_list_item_t          *p_list_item;\r
413         al_ci_ca_t                      *p_ci_ca;\r
414         uintn_t                         guid_cnt;\r
415 \r
416         AL_ENTER( AL_DBG_MGR );\r
417 \r
418         if( AL_OBJ_INVALID_HANDLE( h_al, AL_OBJ_TYPE_H_AL ) )\r
419         {\r
420                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_AL_HANDLE\n") );\r
421                 return IB_INVALID_AL_HANDLE;\r
422         }\r
423         if( !p_guid_cnt )\r
424         {\r
425                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_PARAMETER\n") );\r
426                 return IB_INVALID_PARAMETER;\r
427         }\r
428 \r
429         /* Prevent CA additions or removals. */\r
430         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
431 \r
432         /*\r
433          * Count the number of GUIDs available.  Allow CA\r
434          * additions or removals and maintain the count.\r
435          */\r
436         guid_cnt = cl_qlist_count( &gp_al_mgr->ci_ca_list );\r
437 \r
438         /* Check if a GUID array of sufficient size was provided. */\r
439         if( !p_guid_array || (*p_guid_cnt < guid_cnt) )\r
440         {\r
441                 /* Array too small. */\r
442                 cl_spinlock_release( &gp_al_mgr->obj.lock );\r
443 \r
444                 /* Return the actual count. */\r
445                 *p_guid_cnt = guid_cnt;\r
446 \r
447                 AL_EXIT( AL_DBG_MGR );\r
448                 return IB_INSUFFICIENT_MEMORY;\r
449         }\r
450 \r
451         /* Return the actual count. */\r
452         *p_guid_cnt = guid_cnt;\r
453 \r
454         /* Copy the GUIDs into the array. */\r
455         guid_cnt = 0;\r
456         for( p_list_item = cl_qlist_head( &gp_al_mgr->ci_ca_list );\r
457                  p_list_item != cl_qlist_end( &gp_al_mgr->ci_ca_list );\r
458                  p_list_item = cl_qlist_next( p_list_item ) )\r
459         {\r
460                 p_ci_ca = PARENT_STRUCT( p_list_item, al_ci_ca_t, list_item );\r
461                 p_guid_array[guid_cnt++] = p_ci_ca->verbs.guid;\r
462         }\r
463 \r
464         /* Allow CA additions or removals. */\r
465         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
466 \r
467         AL_EXIT( AL_DBG_MGR );\r
468         return IB_SUCCESS;\r
469 }\r
470 \r
471 \r
472 \r
473 static boolean_t\r
474 __match_ca_attr(\r
475         IN                              al_ci_ca_t * const                      p_ci_ca,\r
476         IN              const   uint64_t                                        attr_mask )\r
477 {\r
478         boolean_t               match;\r
479 \r
480         ci_ca_lock_attr( p_ci_ca );\r
481         \r
482         /* We don't match any attributes for CA's currently. */\r
483         UNUSED_PARAM( attr_mask );\r
484         match = TRUE;\r
485 \r
486         ci_ca_unlock_attr( p_ci_ca );\r
487 \r
488         return match;\r
489 }\r
490 \r
491 \r
492 \r
493 static ib_api_status_t\r
494 __get_ca_guid(\r
495         IN              const   uint32_t                                        index,\r
496         IN              const   uint64_t                                        attr_mask,\r
497                 OUT                     ib_net64_t* const                       p_guid )\r
498 {\r
499         uint32_t                        ca_index;\r
500         cl_list_item_t          *p_list_item;\r
501         al_ci_ca_t                      *p_ci_ca;\r
502         ib_api_status_t         status;\r
503 \r
504         AL_ENTER( AL_DBG_MGR );\r
505 \r
506         /* Prevent CA additions or removals. */\r
507         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
508 \r
509         /* Check for a valid index. */\r
510         if( index != IB_ANY_INDEX &&\r
511                 index >= cl_qlist_count( &gp_al_mgr->ci_ca_list ) )\r
512         {\r
513                 cl_spinlock_release( &gp_al_mgr->obj.lock );\r
514                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_INDEX\n") );\r
515                 return IB_INVALID_INDEX;\r
516         }\r
517 \r
518         /*\r
519          * Find the CA at the correct index and check its attributes.  Optimize\r
520          * for the "any index" case.\r
521          */\r
522         status = IB_NO_MATCH;\r
523         ca_index = 0;\r
524         for( p_list_item = cl_qlist_head( &gp_al_mgr->ci_ca_list );\r
525                  p_list_item != cl_qlist_end( &gp_al_mgr->ci_ca_list );\r
526                  p_list_item = cl_qlist_next( p_list_item ) )\r
527         {\r
528                 p_ci_ca = PARENT_STRUCT( p_list_item, al_ci_ca_t, list_item );\r
529                 \r
530                 if( (ca_index == index || index == IB_ANY_INDEX) &&\r
531                         __match_ca_attr( p_ci_ca, attr_mask ) )\r
532                 {\r
533                         *p_guid = p_ci_ca->verbs.guid;\r
534                         status = IB_SUCCESS;\r
535                         break;\r
536                 }\r
537                 ca_index++;\r
538         }\r
539 \r
540         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
541 \r
542         AL_EXIT( AL_DBG_MGR );\r
543         return status;\r
544 }\r
545 \r
546 \r
547 \r
548 static boolean_t\r
549 __match_port_attr(\r
550         IN              const   ib_port_attr_t * const          p_port_attr,\r
551         IN              const   uint64_t                                        attr_mask )\r
552 {\r
553         if( attr_mask & IB_DEV_PORT_ACTIVE )\r
554                 return( p_port_attr->link_state == IB_LINK_ACTIVE );\r
555 \r
556         return TRUE;\r
557 }\r
558 \r
559 \r
560 \r
561 static ib_api_status_t\r
562 __get_port_guid(\r
563         IN              const   uint32_t                                        index,\r
564         IN              const   uint64_t                                        attr_mask,\r
565                 OUT                     ib_net64_t* const                       p_guid )\r
566 {\r
567         uint32_t                        port_index, i;\r
568         cl_list_item_t          *p_list_item;\r
569         al_ci_ca_t                      *p_ci_ca;\r
570         ib_api_status_t         status;\r
571 \r
572         AL_ENTER( AL_DBG_MGR );\r
573 \r
574         /* Prevent CA additions or removals. */\r
575         cl_spinlock_acquire( &gp_al_mgr->obj.lock );\r
576 \r
577         /*\r
578          * Find the port at the correct index and check its attributes.  Optimize\r
579          * for the "any index" case.\r
580          */\r
581         status = IB_NO_MATCH;\r
582         port_index = 0;\r
583         for( p_list_item = cl_qlist_head( &gp_al_mgr->ci_ca_list );\r
584                  p_list_item != cl_qlist_end( &gp_al_mgr->ci_ca_list ) &&\r
585                  status != IB_SUCCESS;\r
586                  p_list_item = cl_qlist_next( p_list_item ) )\r
587         {\r
588                 p_ci_ca = PARENT_STRUCT( p_list_item, al_ci_ca_t, list_item );\r
589 \r
590                 /* Check all ports on this CA. */\r
591                 ci_ca_lock_attr( p_ci_ca );\r
592                 for( i = 0; i < p_ci_ca->p_pnp_attr->num_ports; i++ )\r
593                 {\r
594                         /* Check the attributes. */\r
595                         if( (port_index == index || index == IB_ANY_INDEX) &&\r
596                                 __match_port_attr( &p_ci_ca->p_pnp_attr->p_port_attr[i],\r
597                                 attr_mask ) )\r
598                         {\r
599                                 *p_guid = p_ci_ca->verbs.guid;\r
600                                 status = IB_SUCCESS;\r
601                                 break;\r
602                         }\r
603                         port_index++;\r
604                 }       \r
605                 ci_ca_unlock_attr( p_ci_ca );\r
606         }\r
607         cl_spinlock_release( &gp_al_mgr->obj.lock );\r
608 \r
609         /*\r
610          * See if the index was valid.  We need to perform this check at the\r
611          * end of the routine, since we don't know how many ports we have.\r
612          */\r
613         if( p_list_item == cl_qlist_end( &gp_al_mgr->ci_ca_list ) &&\r
614                 index != IB_ANY_INDEX )\r
615         {\r
616                 status = IB_INVALID_INDEX;\r
617         }\r
618 \r
619         AL_EXIT( AL_DBG_MGR );\r
620         return status;\r
621 }\r
622 \r
623 \r
624 \r
625 ib_api_status_t\r
626 ib_get_guid(\r
627         IN                              ib_al_handle_t                          h_al,\r
628         IN              const   uint32_t                                        index,\r
629         IN              const   ib_pnp_class_t                          device_type,\r
630         IN              const   uint64_t                                        attr_mask,\r
631                 OUT                     ib_net64_t* const                       p_guid )\r
632 {\r
633         ib_api_status_t         status;\r
634 \r
635         AL_ENTER( AL_DBG_MGR );\r
636 \r
637         if( AL_OBJ_INVALID_HANDLE( h_al, AL_OBJ_TYPE_H_AL ) )\r
638         {\r
639                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_AL_HANDLE\n") );\r
640                 return IB_INVALID_AL_HANDLE;\r
641         }\r
642         if( !p_guid )\r
643         {\r
644                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_PARAMETER\n") );\r
645                 return IB_INVALID_PARAMETER;\r
646         }\r
647 \r
648         switch( device_type )\r
649         {\r
650         case IB_PNP_CA:\r
651                 status = __get_ca_guid( index, attr_mask, p_guid );\r
652                 break;\r
653 \r
654         case IB_PNP_PORT:\r
655                 status = __get_port_guid( index, attr_mask, p_guid );\r
656                 break;\r
657 \r
658         case IB_PNP_IOC:\r
659                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
660                         ("IOC GUIDs not supported at this time\n") );\r
661                 return IB_UNSUPPORTED;\r
662 \r
663         default:\r
664                 AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("IB_INVALID_SETTING\n") );\r
665                 return IB_INVALID_SETTING;\r
666         }\r
667 \r
668         AL_EXIT( AL_DBG_MGR );\r
669         return status;\r
670 }\r
671 \r
672 \r
673 \r
674 \r
675 \r