]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/libvendor/osm_vendor_umadt.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / libvendor / osm_vendor_umadt.c
1 /*
2  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35
36 /*
37  * Abstract:
38  *    Implementation of osm_req_t.
39  * This object represents the generic attribute requester.
40  * This object is part of the opensm family of objects.
41  *
42  */
43
44 /*
45   Next available error code: 0x300
46 */
47
48 #if HAVE_CONFIG_H
49 #  include <config.h>
50 #endif                          /* HAVE_CONFIG_H */
51
52 #ifdef OSM_VENDOR_INTF_UMADT
53
54 #include <stdlib.h>
55 #include <stdio.h>
56 #include <dlfcn.h>
57 #include <string.h>
58
59 #include <complib/cl_qlist.h>
60 #include <complib/cl_thread.h>
61 #include <complib/cl_timer.h>
62 #include <iba/ib_types.h>
63 #include <opensm/osm_madw.h>
64 #include <opensm/osm_log.h>
65 #include <opensm/osm_mad_pool.h>
66
67 #include <vendor/osm_vendor_umadt.h>
68 #include <vendor/osm_umadt.h>
69
70 /*  GEN1 includes */
71 #include "umadt_so.h"
72 #include "ibt.h"
73 #include "statustext.h"
74
75 /* //////////////////////////////////////////////////////////////////////// */
76 /* //////////////////////////////////////////////////////////////////////// */
77 /* //////////////////////////////////////////////////////////////////////// */
78 /* //////////////////////////////////////////////////////////////////////// */
79 /* //////////////////////////////////////////////////////////////////////// */
80 /*  */
81 /*      VENDOR_MAD_INTF */
82 /*  */
83 /* //////////////////////////////////////////////////////////////////////// */
84 /* //////////////////////////////////////////////////////////////////////// */
85 /* //////////////////////////////////////////////////////////////////////// */
86 /* //////////////////////////////////////////////////////////////////////// */
87 /* //////////////////////////////////////////////////////////////////////// */
88
89 /* //////////////////// */
90 /*  Globals        // */
91 /* //////////////////// */
92 typedef struct _ib_sa_mad_vM3 {
93         uint8_t base_ver;
94         uint8_t mgmt_class;
95         uint8_t class_ver;
96         uint8_t method;
97         ib_net16_t status;
98         ib_net16_t resv;
99         ib_net64_t trans_id;
100         ib_net16_t attr_id;
101         ib_net16_t resv1;
102         ib_net32_t attr_mod;
103         ib_net64_t resv2;
104         ib_net64_t sm_key;
105
106         ib_net32_t seg_num;
107         ib_net32_t payload_len;
108         uint8_t frag_flag;
109         uint8_t edit_mod;
110         ib_net16_t window;
111         ib_net16_t attr_offset;
112         ib_net16_t resv3;
113
114         ib_net64_t comp_mask;
115
116         uint8_t data[IB_SA_DATA_SIZE];
117 } ib_sa_mad_t_vM3;
118 #define  DEFAULT_TIMER_INTERVAL_MSEC   500      /*  500msec timer interval */
119
120 void __mad_recv_processor(void *context);
121
122 boolean_t __valid_mad_handle(IN mad_bind_info_t * p_mad_bind_info);
123
124 cl_status_t
125 __match_tid_context(const cl_list_item_t * const p_list_item, void *context);
126 void __osm_vendor_timer_callback(IN void *context);
127
128 osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
129                              IN const uint32_t timeout)
130 {
131         ib_api_status_t status;
132         umadt_obj_t *p_umadt_obj;
133
134         OSM_LOG_ENTER(p_log);
135
136         p_umadt_obj = malloc(sizeof(umadt_obj_t));
137         if (p_umadt_obj) {
138                 memset(p_umadt_obj, 0, sizeof(umadt_obj_t));
139
140                 status = osm_vendor_init((osm_vendor_t *) p_umadt_obj, p_log,
141                                          timeout);
142                 if (status != IB_SUCCESS) {
143                         osm_vendor_delete((osm_vendor_t **) & p_umadt_obj);
144                 }
145         } else {
146                 printf
147                     ("osm_vendor_construct: ERROR! Unable to create Umadt object!\n");
148         }
149
150         OSM_LOG_EXIT(p_log);
151
152         return ((osm_vendor_t *) p_umadt_obj);
153 }
154
155 void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
156 {
157         umadt_obj_t *p_umadt_obj = (umadt_obj_t *) * pp_vend;
158         cl_list_item_t *p_list_item;
159         uint32_t count, i;
160         mad_bind_info_t *p_mad_bind_info;
161
162         OSM_LOG_ENTER(p_umadt_obj->p_log);
163
164         cl_spinlock_acquire(&p_umadt_obj->register_lock);
165         p_mad_bind_info =
166             (mad_bind_info_t *) cl_qlist_head(&p_umadt_obj->register_list);
167         count = cl_qlist_count(&p_umadt_obj->register_list);
168         cl_spinlock_release(&p_umadt_obj->register_lock);
169         for (i = 0; i < count; i++) {
170                 cl_spinlock_acquire(&p_umadt_obj->register_lock);
171                 p_list_item = cl_qlist_next(&p_mad_bind_info->list_item);
172                 cl_spinlock_release(&p_umadt_obj->register_lock);
173                 /*  Unbind this handle */
174                 /*  osm_vendor_ubind also removesd the item from the list */
175                 /*  osm_vendor_unbind takes the list lock so release it here */
176                 osm_vendor_unbind((osm_bind_handle_t) p_mad_bind_info);
177                 p_mad_bind_info = (mad_bind_info_t *) p_list_item;
178         }
179         dlclose(p_umadt_obj->umadt_handle);
180         free(p_umadt_obj);
181         *pp_vend = NULL;
182
183         OSM_LOG_EXIT(p_umadt_obj->p_log);
184 }
185
186 /* //////////////////////////////////////////////////////////////////////// */
187 /*  See VendorAbstractMadIntf.h for info */
188 /* //////////////////////////////////////////////////////////////////////// */
189 /*  */
190 ib_api_status_t
191 osm_vendor_init(IN osm_vendor_t * const p_vend,
192                 IN osm_log_t * const p_log, IN const uint32_t timeout)
193 {
194         FSTATUS Status;
195         PUMADT_GET_INTERFACE uMadtGetInterface;
196         char *error;
197         umadt_obj_t *p_umadt_obj = (umadt_obj_t *) p_vend;
198
199         OSM_LOG_ENTER(p_log);
200
201         p_umadt_obj->p_log = p_log;
202         p_umadt_obj->timeout = timeout;
203
204         p_umadt_obj->umadt_handle = dlopen("libibt.so", RTLD_NOW);
205
206         if (!p_umadt_obj->umadt_handle) {
207                 printf("Could not load libibt.so <%s>\n", dlerror());
208                 return IB_ERROR;
209         }
210         uMadtGetInterface =
211             dlsym(p_umadt_obj->umadt_handle, "uMadtGetInterface");
212         if ((error = dlerror()) != NULL) {
213                 printf("Could not resolve symbol uMadtGetInterface ERROR<%s>\n",
214                        error);
215                 return IB_ERROR;
216         }
217
218         Status = (*uMadtGetInterface) (&p_umadt_obj->uMadtInterface);
219         if (Status != FSUCCESS) {
220                 printf(" Error in getting uMADT interface ERROR<%d>\n", Status);
221                 return IB_ERROR;
222         }
223
224         /*  Initialize the register list and register list lock */
225         cl_qlist_init(&p_umadt_obj->register_list);
226
227         cl_spinlock_construct(&p_umadt_obj->register_lock);
228         CL_ASSERT(cl_spinlock_init(&p_umadt_obj->register_lock) == CL_SUCCESS);
229         p_umadt_obj->init_done = TRUE;
230         printf("*****SUCCESS*****\n");
231
232         OSM_LOG_EXIT(p_log);
233         return IB_SUCCESS;
234
235 }
236
237 /* //////////////////////////////////////////////////////////////////////// */
238 /*  See VendorAbstractMadIntf.h for info */
239 /* //////////////////////////////////////////////////////////////////////// */
240 ib_api_status_t
241 osm_vendor_get_ports(IN osm_vendor_t * const p_vend,
242                      IN ib_net64_t * const p_guids,
243                      IN uint32_t * const p_num_guids)
244 {
245         char *error = NULL;
246         PIBT_GET_INTERFACE pfnIbtGetInterface;
247         PIBT_INIT pfnIbtInitFunc;
248
249         FSTATUS Status;
250         uint32_t caCount, caGuidCount;
251         IB_CA_ATTRIBUTES caAttributes;
252         IB_HANDLE caHandle;
253         uint32_t i;
254         IB_PORT_ATTRIBUTES *pPortAttributesList;
255         EUI64 CaGuidArray[8];
256         void *context;
257         uint64_t *p_port_guid;
258         uint32_t free_guids;
259
260         umadt_obj_t *p_umadt_obj = (umadt_obj_t *) p_vend;
261
262         OSM_LOG_ENTER(p_umadt_obj->p_log);
263
264         CL_ASSERT(p_guids);
265         CL_ASSERT(p_num_guids);
266
267         pfnIbtInitFunc =
268             (PIBT_INIT) dlsym(p_umadt_obj->umadt_handle, "IbtInit");
269
270         if (!pfnIbtInitFunc) {
271                 printf("Error getting IbtInit function address.\n");
272                 return IB_ERROR;
273         }
274
275         (*pfnIbtInitFunc) ();
276
277         pfnIbtGetInterface =
278             (PIBT_GET_INTERFACE) dlsym(p_umadt_obj->umadt_handle,
279                                        "IbtGetInterface");
280
281         if (!pfnIbtGetInterface || (error = dlerror()) != NULL) {
282                 printf("Error getting IbtGetInterface function address.<%s>\n",
283                        error);
284                 return FALSE;
285         }
286         (*pfnIbtGetInterface) (&p_umadt_obj->IbtInterface);
287
288         caGuidCount = 8;
289         Status =
290             p_umadt_obj->IbtInterface.GetCaGuidArray(&caGuidCount,
291                                                      &CaGuidArray[0]);
292
293         if ((Status != FSUCCESS) || (caGuidCount == 0)) {
294                 return FALSE;
295         }
296
297         free_guids = *p_num_guids;
298         p_port_guid = p_guids;
299
300         /* query each ca & copy its info into callers buffer */
301         for (caCount = 0; caCount < caGuidCount; caCount++) {
302                 memset(&caAttributes, 0, sizeof(IB_CA_ATTRIBUTES));
303
304                 /* Open the CA */
305                 Status = p_umadt_obj->IbtInterface.Vpi.OpenCA(CaGuidArray[caCount], NULL,       /*  CACompletionCallback */
306                                                               NULL,     /*  AsyncEventCallback */
307                                                               NULL, &caHandle);
308                 if (Status != FSUCCESS) {
309                         return IB_ERROR;
310                 }
311
312                 Status = p_umadt_obj->IbtInterface.Vpi.QueryCA(caHandle,
313                                                                &caAttributes,
314                                                                &context);
315
316                 if (Status != FSUCCESS) {
317                         p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
318                         return IB_ERROR;
319                 }
320
321                 if (caAttributes.Ports > free_guids) {
322                         *p_num_guids = 0;
323                         memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
324                         return IB_INSUFFICIENT_MEMORY;
325                 }
326
327                 pPortAttributesList =
328                     (IB_PORT_ATTRIBUTES *) malloc(caAttributes.
329                                                   PortAttributesListSize);
330
331                 if (pPortAttributesList == NULL) {
332                         p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
333                         *p_num_guids = 0;
334                         memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
335                         return IB_INSUFFICIENT_MEMORY;
336                 }
337
338                 memset(pPortAttributesList, 0,
339                        caAttributes.PortAttributesListSize);
340
341                 caAttributes.PortAttributesList = pPortAttributesList;
342
343                 Status = p_umadt_obj->IbtInterface.Vpi.QueryCA(caHandle,
344                                                                &caAttributes,
345                                                                &context);
346
347                 if (Status != FSUCCESS) {
348                         p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
349                         *p_num_guids = 0;
350                         memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
351                         return IB_ERROR;
352                 }
353
354                 pPortAttributesList = caAttributes.PortAttributesList;
355
356                 for (i = 0; i < caAttributes.Ports; i++) {
357                         *(p_port_guid) =
358                             cl_hton64((uint64_t) pPortAttributesList->GUID);
359                         pPortAttributesList = pPortAttributesList->Next;
360                         p_port_guid++;
361                 }
362                 free(caAttributes.PortAttributesList);
363                 p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
364
365                 free_guids = free_guids - caAttributes.Ports;
366
367         }
368         *p_num_guids = *p_num_guids - free_guids;
369         return IB_SUCCESS;
370 }
371
372 /* //////////////////////////////////////////////////////////////////////// */
373 /*  See VendorAbstractMadIntf.h for info */
374 /* //////////////////////////////////////////////////////////////////////// */
375 ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
376                          IN const uint32_t mad_size,
377                          IN osm_vend_wrap_t * p_vend_wrap)
378 {
379         /* FSTATUS Status; */
380         /* uint32_t mad_count = 0; */
381         /* MadtStruct *p_madt_struct; */
382         mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) h_bind;
383         umadt_obj_t *p_umadt_obj = p_mad_bind_info->p_umadt_obj;
384         ib_mad_t *p_mad;
385         OSM_LOG_ENTER(p_umadt_obj->p_log);
386
387         CL_ASSERT(h_bind);
388
389         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
390
391         /*  Sanity check */
392         CL_ASSERT(p_umadt_obj->init_done);
393         CL_ASSERT(p_vend_wrap);
394         CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
395
396 #if 0
397         mad_count = 1;
398         Status =
399             p_umadt_obj->uMadtInterface.uMadtGetSendMad(p_mad_bind_info->
400                                                         umadt_handle,
401                                                         &mad_count,
402                                                         &p_madt_struct);
403
404         if (Status != FSUCCESS || p_madt_struct == NULL) {
405                 p_vend_wrap->p_madt_struct = NULL;
406                 return NULL;
407         }
408         p_vend_wrap->p_madt_struct = p_madt_struct;
409         p_vend_wrap->direction = SEND;
410         return ((ib_mad_t *) & p_madt_struct->IBMad);
411 #endif                          /*  0 */
412         p_mad = (ib_mad_t *) malloc(mad_size);
413         if (!p_mad) {
414                 p_vend_wrap->p_madt_struct = NULL;
415                 return NULL;
416         }
417
418         memset(p_mad, 0, mad_size);
419
420         p_vend_wrap->p_madt_struct = NULL;
421         p_vend_wrap->direction = SEND;
422         p_vend_wrap->size = mad_size;
423         return (p_mad);
424
425 }
426
427 /* //////////////////////////////////////////////////////////////////////// */
428 /*  See VendorAbstractMadIntf.h for info */
429 /* //////////////////////////////////////////////////////////////////////// */
430 void
431 osm_vendor_put(IN osm_bind_handle_t h_bind,
432                IN osm_vend_wrap_t * const p_vend_wrap,
433                IN ib_mad_t * const p_mad)
434 {
435
436         FSTATUS Status;
437
438         mad_bind_info_t *p_mad_bind_info;
439         umadt_obj_t *p_umadt_obj;
440
441         /*  */
442         /*  Validate the vendor mad transport handle */
443         /*  */
444         CL_ASSERT(h_bind);
445         p_mad_bind_info = (mad_bind_info_t *) h_bind;
446         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
447
448         /*  sanity check */
449         CL_ASSERT(p_umadt_obj->init_done);
450         CL_ASSERT(h_bind);
451         CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
452         CL_ASSERT(p_vend_wrap);
453         /* CL_ASSERT( (ib_mad_t*)&p_vend_wrap->p_madt_struct->IBMad == p_mad ); */
454
455         /*  Release the MAD based on the direction of the MAD */
456         if (p_vend_wrap->direction == SEND) {
457                 /*  */
458                 /* For a send the PostSend released the MAD with Umadt. Simply dealloacte the */
459                 /* local memory that was allocated on the osm_vendor_get() call. */
460                 /*  */
461                 free(p_mad);
462 #if 0
463                 Status =
464                     p_umadt_obj->uMadtInterface.
465                     uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
466                                         p_vend_wrap->p_madt_struct);
467                 if (Status != FSUCCESS) {
468                         /* printf("uMadtReleaseSendMad: Status  = <%d>\n", Status); */
469                         return;
470                 }
471 #endif
472         } else if (p_vend_wrap->direction == RECEIVE) {
473                 CL_ASSERT((ib_mad_t *) & p_vend_wrap->p_madt_struct->IBMad ==
474                           p_mad);
475                 Status =
476                     p_umadt_obj->uMadtInterface.
477                     uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle,
478                                         p_vend_wrap->p_madt_struct);
479                 if (Status != FSUCCESS) {
480                         /* printf("uMadtReleaseRecvMad Status=<%d>\n", Status); */
481                         return;
482                 }
483         } else {
484                 return;
485         }
486         return;
487 }
488
489 /* //////////////////////////////////////////////////////////////////////// */
490 /*  See VendorAbstractMadIntf.h for info */
491 /* //////////////////////////////////////////////////////////////////////// */
492 ib_api_status_t
493 osm_vendor_send(IN osm_bind_handle_t h_bind,
494                 IN osm_vend_wrap_t * const p_vend_wrap,
495                 IN osm_mad_addr_t * const p_mad_addr,
496                 IN ib_mad_t * const p_mad,
497                 IN void *transaction_context, IN boolean_t const resp_expected)
498 {
499         FSTATUS Status;
500
501         MadAddrStruct destAddr = { 0 };
502
503         mad_bind_info_t *p_mad_bind_info;
504         trans_context_t *p_trans_context;
505
506         umadt_obj_t *p_umadt_obj = NULL;
507
508         uint32_t mad_count = 0;
509         MadtStruct *p_madt_struct = NULL;
510         uint32_t i;
511         uint32_t num_mads = 0;
512         uint32_t seg_num = 0;
513         uint8_t *p_frag_data = NULL;
514         ib_sa_mad_t_vM3 *p_sa_mad = NULL;
515
516         CL_ASSERT(h_bind);
517         p_mad_bind_info = (mad_bind_info_t *) h_bind;
518         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
519
520         /*  sanity check */
521         CL_ASSERT(p_umadt_obj);
522         CL_ASSERT(p_umadt_obj->init_done);
523         CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
524         CL_ASSERT(p_vend_wrap);
525         CL_ASSERT(p_mad_addr);
526         CL_ASSERT(p_mad);
527         /* CL_ASSERT( (ib_mad_t*)&p_vend_wrap->p_madt_struct->IBMad == p_mad ); */
528
529         /*  */
530         /*  based on the class, fill out the address info */
531         /*  */
532         destAddr.DestLid = p_mad_addr->dest_lid;
533         destAddr.PathBits = p_mad_addr->path_bits;
534         destAddr.StaticRate = p_mad_addr->static_rate;
535
536         if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
537             p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
538                 CL_ASSERT(p_mad_addr->addr_type.smi.source_lid);
539                 destAddr.AddrType.Smi.SourceLid =
540                     p_mad_addr->addr_type.smi.source_lid;
541         } else {
542                 destAddr.AddrType.Gsi.RemoteQpNumber =
543                     p_mad_addr->addr_type.gsi.remote_qp;
544                 destAddr.AddrType.Gsi.RemoteQkey =
545                     p_mad_addr->addr_type.gsi.remote_qkey;
546                 destAddr.AddrType.Gsi.PKey = OSM_DEFAULT_PKEY;
547                 destAddr.AddrType.Gsi.ServiceLevel =
548                     p_mad_addr->addr_type.gsi.service_level;
549                 destAddr.AddrType.Gsi.GlobalRoute =
550                     p_mad_addr->addr_type.gsi.global_route;
551                 /* destAddr.AddrType.Gsi.GRHInfo = p_mad_addr->addr_type.gsi.grh_info; */
552         }
553         p_mad->trans_id = cl_ntoh64(p_mad->trans_id) << 24;
554
555         /*  */
556         /*  Create a transaction context for this send and save the TID and client context. */
557         /*  */
558
559         if (resp_expected) {
560                 p_trans_context = malloc(sizeof(trans_context_t));
561                 CL_ASSERT(p_trans_context);
562
563                 memset(p_trans_context, 0, sizeof(trans_context_t));
564                 p_trans_context->trans_id = p_mad->trans_id;
565                 p_trans_context->context = transaction_context;
566                 p_trans_context->sent_time = cl_get_time_stamp();
567
568                 cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
569                 cl_qlist_insert_tail(&p_mad_bind_info->trans_ctxt_list,
570                                      &p_trans_context->list_item);
571                 cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
572         }
573
574         if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
575             p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
576                 /*  Get one mad from uMadt */
577                 mad_count = 1;
578                 Status =
579                     p_umadt_obj->uMadtInterface.
580                     uMadtGetSendMad(p_mad_bind_info->umadt_handle, &mad_count,
581                                     &p_madt_struct);
582
583                 if (Status != FSUCCESS || p_madt_struct == NULL) {
584                         return IB_ERROR;
585                 }
586
587                 /*  No Segmentation required */
588                 memcpy(&p_madt_struct->IBMad, p_mad, MAD_BLOCK_SIZE);
589
590                 /*  Post the MAD */
591
592                 Status =
593                     p_umadt_obj->uMadtInterface.uMadtPostSend(p_mad_bind_info->
594                                                               umadt_handle,
595                                                               p_madt_struct,
596                                                               &destAddr);
597                 if (Status != FSUCCESS) {
598                         printf("uMadtPostSendMad: Status  = <%d>\n", Status);
599                         return IB_ERROR;
600                 }
601
602                 /*  Release send MAD */
603                 Status =
604                     p_umadt_obj->uMadtInterface.
605                     uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
606                                         p_madt_struct);
607                 if (Status != FSUCCESS) {
608                         printf("uMadtReleaseSendMad: Status  = <%d>\n", Status);
609                         return IB_ERROR;
610                 }
611         } else {
612
613                 /*  */
614                 /*  Segment the MAD, get the required send mads from uMadt and post the MADs. */
615                 /*  */
616                 uint32_t payload_len;
617
618                 payload_len =
619                     cl_ntoh32(((ib_sa_mad_t_vM3 *) p_mad)->payload_len);
620                 num_mads = payload_len / IB_SA_DATA_SIZE;
621                 if (payload_len % IB_SA_DATA_SIZE != 0) {
622                         num_mads++;     /*  Get one additional mad for the remainder */
623                 }
624                 for (i = 0; i < num_mads; i++) {
625                         /*  Get one mad from uMadt */
626                         mad_count = 1;
627                         Status =
628                             p_umadt_obj->uMadtInterface.
629                             uMadtGetSendMad(p_mad_bind_info->umadt_handle,
630                                             &mad_count, &p_madt_struct);
631
632                         if (Status != FSUCCESS || p_madt_struct == NULL) {
633                                 return IB_ERROR;
634                         }
635                         /*  Copy client MAD into uMadt's MAD. */
636                         if (i == 0) {   /*  First Packet */
637                                 /*  Since this is the first MAD, copy the entire MAD_SIZE */
638                                 memcpy(&p_madt_struct->IBMad, p_mad,
639                                        MAD_BLOCK_SIZE);
640
641                                 p_frag_data =
642                                     (uint8_t *) p_mad + MAD_BLOCK_SIZE;
643
644                                 p_sa_mad =
645                                     (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
646                                 if (num_mads == 1) {    /*  Only one Packet */
647                                         p_sa_mad->seg_num = 0;
648                                         p_sa_mad->frag_flag = 5;        /*  Set bit 0 for first pkt and b4 for last pkt */
649                                         /*  the payload length gets copied with the mad header above */
650                                 } else {        /*  More than one packet in this response */
651
652                                         seg_num = 1;
653                                         p_sa_mad->seg_num =
654                                             cl_ntoh32(seg_num++);
655                                         p_sa_mad->frag_flag = 1;        /*  Set bit 0 for first pkt */
656                                         /*  the payload length gets copied with the mad header above */
657                                 }
658
659                         } else if (i < num_mads - 1) {  /*  Not last packet */
660                                 /*  First copy only the header */
661                                 memcpy(&p_madt_struct->IBMad, p_mad,
662                                        IB_SA_MAD_HDR_SIZE);
663                                 /*  Set the relevant fields in the SA_MAD_HEADER */
664                                 p_sa_mad =
665                                     (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
666                                 p_sa_mad->payload_len =
667                                     cl_ntoh32(IB_SA_DATA_SIZE);
668                                 p_sa_mad->seg_num = cl_ntoh32(seg_num++);
669                                 p_sa_mad->frag_flag = 0;
670                                 /*  Now copy the fragmented data */
671                                 memcpy(((uint8_t *) & p_madt_struct->IBMad) +
672                                        IB_SA_MAD_HDR_SIZE, p_frag_data,
673                                        IB_SA_DATA_SIZE);
674                                 p_frag_data = p_frag_data + IB_SA_DATA_SIZE;
675
676                         } else if (i == num_mads - 1) { /*  Last packet */
677                                 /*  First copy only the header */
678                                 memcpy(&p_madt_struct->IBMad, p_mad,
679                                        IB_SA_MAD_HDR_SIZE);
680                                 /*  Set the relevant fields in the SA_MAD_HEADER */
681                                 p_sa_mad =
682                                     (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
683                                 p_sa_mad->seg_num = cl_ntoh32(seg_num++);
684                                 p_sa_mad->frag_flag = 4;        /*  Set Bit 2 for last pkt */
685                                 p_sa_mad->payload_len =
686                                     cl_ntoh32(cl_ntoh32
687                                               (((ib_sa_mad_t_vM3 *) p_mad)->
688                                                payload_len) % IB_SA_DATA_SIZE);
689                                 /*  Now copy the fragmented data */
690                                 memcpy((((uint8_t *) & p_madt_struct->IBMad)) +
691                                        IB_SA_MAD_HDR_SIZE, p_frag_data,
692                                        cl_ntoh32(p_sa_mad->payload_len));
693                                 p_frag_data = p_frag_data + IB_SA_DATA_SIZE;
694
695                         }
696                         /*  Post the MAD */
697                         Status =
698                             p_umadt_obj->uMadtInterface.
699                             uMadtPostSend(p_mad_bind_info->umadt_handle,
700                                           p_madt_struct, &destAddr);
701                         if (Status != FSUCCESS) {
702                                 printf("uMadtPostSendMad: Status  = <%d>\n",
703                                        Status);
704                                 return IB_ERROR;
705                         }
706
707                         /*  Release send MAD */
708                         Status =
709                             p_umadt_obj->uMadtInterface.
710                             uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
711                                                 p_madt_struct);
712                         if (Status != FSUCCESS) {
713                                 printf("uMadtReleaseSendMad: Status  = <%d>\n",
714                                        Status);
715                                 return IB_ERROR;
716                         }
717                 }
718         }
719         return (IB_SUCCESS);
720 }
721
722 /* //////////////////////////////////////////////////////////////////////// */
723 /*  See VendorAbstractMadIntf.h for info */
724 /* //////////////////////////////////////////////////////////////////////// */
725
726 osm_bind_handle_t
727 osm_vendor_bind(IN osm_vendor_t * const p_vend,
728                 IN osm_bind_info_t * const p_osm_bind_info,
729                 IN osm_mad_pool_t * const p_mad_pool,
730                 IN osm_vend_mad_recv_callback_t mad_recv_callback,
731                 IN void *context)
732 {
733         cl_status_t cl_status;
734         FSTATUS Status;         /*  GEN1 Status for Umadt */
735
736         mad_bind_info_t *p_mad_bind_info;
737         RegisterClassStruct *p_umadt_reg_class;
738
739         umadt_obj_t *p_umadt_obj;
740         OSM_LOG_ENTER(((umadt_obj_t *) p_vend)->p_log);
741
742         CL_ASSERT(p_vend);
743
744         p_umadt_obj = (umadt_obj_t *) p_vend;
745
746         /*  Sanity check */
747         CL_ASSERT(p_umadt_obj->init_done);
748         CL_ASSERT(p_osm_bind_info);
749         CL_ASSERT(p_mad_pool);
750         CL_ASSERT(mad_recv_callback);
751
752         /*  Allocate memory for registering the handle. */
753         p_mad_bind_info = (mad_bind_info_t *) malloc(sizeof(*p_mad_bind_info));
754         if (p_mad_bind_info) {
755                 memset(p_mad_bind_info, 0, sizeof(*p_mad_bind_info));
756                 p_umadt_reg_class = &p_mad_bind_info->umadt_reg_class;
757         }
758         p_umadt_reg_class->PortGuid = cl_ntoh64(p_osm_bind_info->port_guid);
759         p_umadt_reg_class->ClassId = p_osm_bind_info->mad_class;
760         p_umadt_reg_class->ClassVersion = p_osm_bind_info->class_version;
761         p_umadt_reg_class->isResponder = p_osm_bind_info->is_responder;
762         p_umadt_reg_class->isTrapProcessor = p_osm_bind_info->is_trap_processor;
763         p_umadt_reg_class->isReportProcessor =
764             p_osm_bind_info->is_report_processor;
765         p_umadt_reg_class->SendQueueSize = p_osm_bind_info->send_q_size;
766         p_umadt_reg_class->RecvQueueSize = p_osm_bind_info->recv_q_size;
767         p_umadt_reg_class->NotifySendCompletion = TRUE;
768
769         p_mad_bind_info->p_umadt_obj = p_umadt_obj;
770         p_mad_bind_info->p_mad_pool = p_mad_pool;
771         p_mad_bind_info->mad_recv_callback = mad_recv_callback;
772         p_mad_bind_info->client_context = context;
773
774         /*  register with Umadt for MAD interface */
775         Status = p_umadt_obj->uMadtInterface.uMadtRegister(p_umadt_reg_class,
776                                                            &p_mad_bind_info->
777                                                            umadt_handle);
778         if (Status != FSUCCESS) {
779                 free(p_mad_bind_info);
780                 OSM_LOG_EXIT(p_umadt_obj->p_log);
781                 return (OSM_BIND_INVALID_HANDLE);
782         }
783         CL_ASSERT(p_mad_bind_info->umadt_handle);
784         /*  */
785         /*  Start a worker thread to process receives. */
786         /*  */
787         cl_thread_construct(&p_mad_bind_info->recv_processor_thread);
788         cl_status = cl_thread_init(&p_mad_bind_info->recv_processor_thread,
789                                    __mad_recv_processor,
790                                    (void *)p_mad_bind_info, "mad_recv_worker");
791         CL_ASSERT(cl_status == CL_SUCCESS);
792
793         cl_qlist_init(&p_mad_bind_info->trans_ctxt_list);
794         cl_spinlock_construct(&p_mad_bind_info->trans_ctxt_lock);
795         cl_spinlock_init(&p_mad_bind_info->trans_ctxt_lock);
796         cl_spinlock_construct(&p_mad_bind_info->timeout_list_lock);
797         cl_spinlock_init(&p_mad_bind_info->timeout_list_lock);
798
799         cl_status = cl_timer_init(&p_mad_bind_info->timeout_timer,
800                                   __osm_vendor_timer_callback,
801                                   (void *)p_mad_bind_info);
802         CL_ASSERT(cl_status == CL_SUCCESS);
803         cl_qlist_init(&p_mad_bind_info->timeout_list);
804         /*  */
805         /*  Insert the mad_reg_struct in list and return pointer to it as the handle */
806         /*  */
807         cl_spinlock_acquire(&p_umadt_obj->register_lock);
808
809         cl_qlist_insert_head(&p_umadt_obj->register_list,
810                              &p_mad_bind_info->list_item);
811
812         cl_spinlock_release(&p_umadt_obj->register_lock);
813
814         /*
815            A timeout value of 0 means disable timeouts.
816          */
817         if (p_umadt_obj->timeout) {
818                 cl_timer_start(&p_mad_bind_info->timeout_timer,
819                                DEFAULT_TIMER_INTERVAL_MSEC);
820         }
821
822         OSM_LOG_EXIT(p_umadt_obj->p_log);
823         return ((osm_bind_handle_t) p_mad_bind_info);
824 }
825
826 /**********************************************************************
827  **********************************************************************/
828 void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
829 {
830         mad_bind_info_t *p_mad_bind_info;
831         umadt_obj_t *p_umadt_obj;
832         cl_list_item_t *p_list_item, *p_next_list_item;
833
834         CL_ASSERT(h_bind);
835         p_mad_bind_info = (mad_bind_info_t *) h_bind;
836         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
837
838         /*  sanity check */
839         CL_ASSERT(p_umadt_obj);
840         CL_ASSERT(p_umadt_obj->init_done);
841         CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
842
843         p_umadt_obj->uMadtInterface.uMadtDestroy(&p_mad_bind_info->
844                                                  umadt_handle);
845         cl_timer_destroy(&p_mad_bind_info->timeout_timer);
846         cl_thread_destroy(&p_mad_bind_info->recv_processor_thread);
847
848         cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
849         p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
850         while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
851                 p_next_list_item = cl_qlist_next(p_list_item);
852                 cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
853                                      p_list_item);
854                 free(p_list_item);
855                 p_list_item = p_next_list_item;
856         }
857         cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
858
859         cl_spinlock_acquire(&p_mad_bind_info->timeout_list_lock);
860         p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
861         while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
862                 p_next_list_item = cl_qlist_next(p_list_item);
863                 cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
864                                      p_list_item);
865                 free(p_list_item);
866                 p_list_item = p_next_list_item;
867         }
868         cl_spinlock_release(&p_mad_bind_info->timeout_list_lock);
869
870         free(p_mad_bind_info);
871 }
872
873 /**********************************************************************
874  **********************************************************************/
875 void __mad_recv_processor(IN void *context)
876 {
877         mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) context;
878         umadt_obj_t *p_umadt_obj;
879         osm_madw_t *p_osm_madw = NULL;
880         osm_vend_wrap_t *p_vend_wrap = NULL;
881         osm_mad_addr_t osm_mad_addr = { 0 };
882         cl_list_item_t *p_list_item;
883         void *transaction_context;
884
885         FSTATUS Status;
886         MadtStruct *pRecvMad = NULL;
887         MadWorkCompletion *pRecvCmp = NULL;
888
889         CL_ASSERT(context);
890
891         p_mad_bind_info = (mad_bind_info_t *) context;
892         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
893         /*  PollFor a completion */
894         /*  if FNOTFOND, then wait for a completion then again poll and return the MAD */
895         while (1) {
896                 Status =
897                     p_umadt_obj->uMadtInterface.
898                     uMadtPollForRecvCompletion(p_mad_bind_info->umadt_handle,
899                                                &pRecvMad, &pRecvCmp);
900                 if (Status != FSUCCESS) {
901                         if (Status == FNOT_FOUND) {
902                                 /* Wait for a completion */
903                                 Status = p_umadt_obj->uMadtInterface.uMadtWaitForAnyCompletion(p_mad_bind_info->umadt_handle, RECV_COMPLETION, 0x5000); /* 5 sec timeout */
904
905                                 if (Status == FTIMEOUT) {
906                                         continue;
907                                 }
908                                 CL_ASSERT(Status == FSUCCESS);
909
910                                 Status =
911                                     p_umadt_obj->uMadtInterface.
912                                     uMadtPollForRecvCompletion(p_mad_bind_info->
913                                                                umadt_handle,
914                                                                &pRecvMad,
915                                                                &pRecvCmp);
916                                 if (Status != FSUCCESS) {
917                                         printf
918                                             (" mad_recv_worker: Error in PollForRecv returning <%x>\n",
919                                              Status);
920                                         CL_ASSERT(0);
921                                 }
922                         } else {
923                                 printf
924                                     ("uMadtPollForRecvCompletion Status=<%x>\n",
925                                      Status);
926                                 CL_ASSERT(0);
927                         }
928                 }
929                 CL_ASSERT(pRecvMad);
930                 CL_ASSERT(pRecvCmp);
931
932                 if (((ib_sa_mad_t_vM3 *) (&pRecvMad->IBMad))->frag_flag & 0x20) {
933                         /*  Ignore the ACK packet */
934                         Status =
935                             p_umadt_obj->uMadtInterface.
936                             uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle,
937                                                 pRecvMad);
938                         continue;
939                 }
940                 /*  */
941                 /*  Extract the return address to pass it on to the client */
942                 /*  */
943                 osm_mad_addr.dest_lid = pRecvCmp->AddressInfo.DestLid;
944                 osm_mad_addr.path_bits = pRecvCmp->AddressInfo.PathBits;
945                 osm_mad_addr.static_rate = pRecvCmp->AddressInfo.StaticRate;
946
947                 if (p_mad_bind_info->umadt_reg_class.ClassId ==
948                     IB_MCLASS_SUBN_LID
949                     || p_mad_bind_info->umadt_reg_class.ClassId ==
950                     IB_MCLASS_SUBN_DIR) {
951                         osm_mad_addr.addr_type.smi.source_lid =
952                             pRecvCmp->AddressInfo.AddrType.Smi.SourceLid;
953                         /* osm_mad_addr.addr_type.smi.port_num = pRecvCmp->AddressInfo.AddrType.Smi.PortNumber; */
954                 } else {
955                         osm_mad_addr.addr_type.gsi.remote_qp =
956                             pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQpNumber;
957                         osm_mad_addr.addr_type.gsi.remote_qkey =
958                             pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQkey;
959                         osm_mad_addr.addr_type.gsi.pkey_ix = 0;
960                         osm_mad_addr.addr_type.gsi.service_level =
961                             pRecvCmp->AddressInfo.AddrType.Gsi.ServiceLevel;
962                         osm_mad_addr.addr_type.gsi.global_route =
963                             pRecvCmp->AddressInfo.AddrType.Gsi.GlobalRoute;
964                         /* osm_mad_addr.addr_type.gsi.grh_info = pRecvCmp->AddressInfo.AddrType.Gsi.GRHInfo; */
965                 }
966                 p_osm_madw =
967                     osm_mad_pool_get_wrapper(p_mad_bind_info->p_mad_pool,
968                                              p_mad_bind_info, MAD_BLOCK_SIZE,
969                                              (ib_mad_t *) & pRecvMad->IBMad,
970                                              &osm_mad_addr);
971                 CL_ASSERT(p_osm_madw);
972                 p_vend_wrap = osm_madw_get_vend_ptr(p_osm_madw);
973                 CL_ASSERT(p_vend_wrap);
974                 p_vend_wrap->p_madt_struct = pRecvMad;
975                 p_vend_wrap->direction = RECEIVE;
976
977                 osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
978                         "__mad_recv_processor: "
979                         "Received data p_osm_madw[0x%p].\n", p_osm_madw);
980
981                 /*  */
982                 /*  Do TID Processing. */
983                 /*  */
984                 /*  If R bit is set swap the TID */
985
986                 cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
987                 p_list_item =
988                     cl_qlist_find_from_head(&p_mad_bind_info->trans_ctxt_list,
989                                             __match_tid_context,
990                                             &p_osm_madw->p_mad->trans_id);
991
992                 if (p_list_item ==
993                     cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
994                         transaction_context = NULL;
995                 } else {
996                         transaction_context =
997                             ((trans_context_t *) p_list_item)->context;
998                         cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
999                                              p_list_item);
1000                         free(p_list_item);
1001                 }
1002                 cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
1003                 ((ib_mad_t *) p_osm_madw->p_mad)->trans_id =
1004                     cl_ntoh64(p_osm_madw->p_mad->trans_id >> 24);
1005                 osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
1006                         "__mad_recv_processor: "
1007                         "Received data p_osm_madw [0x%p]" "\n\t\t\t\tTID[0x%"
1008                         PRIx64 ", context[%p]. \n", p_osm_madw,
1009                         ((ib_mad_t *) p_osm_madw->p_mad)->trans_id,
1010                         transaction_context);
1011
1012                 (*(p_mad_bind_info->mad_recv_callback)) (p_osm_madw,
1013                                                          p_mad_bind_info->
1014                                                          client_context,
1015                                                          transaction_context);
1016
1017         }
1018 }
1019
1020 /**********************************************************************
1021  **********************************************************************/
1022
1023 cl_status_t
1024 __match_tid_context(const cl_list_item_t * const p_list_item, void *context)
1025 {
1026         if (((trans_context_t *) p_list_item)->trans_id ==
1027             *((uint64_t *) context))
1028                 return CL_SUCCESS;
1029         return CL_NOT_FOUND;
1030 }
1031
1032 /**********************************************************************
1033  **********************************************************************/
1034
1035 boolean_t __valid_mad_handle(IN mad_bind_info_t * p_mad_bind_info)
1036 {
1037
1038         umadt_obj_t *p_umadt_obj;
1039
1040         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
1041
1042         cl_spinlock_acquire(&p_umadt_obj->register_lock);
1043         if (!cl_is_item_in_qlist(&p_umadt_obj->register_list,
1044                                  &p_mad_bind_info->list_item)) {
1045                 cl_spinlock_release(&p_umadt_obj->register_lock);
1046                 return FALSE;
1047         }
1048         cl_spinlock_release(&p_umadt_obj->register_lock);
1049         return TRUE;
1050 }
1051
1052 void __osm_vendor_timer_callback(IN void *context)
1053 {
1054         uint64_t current_time;
1055         mad_bind_info_t *p_mad_bind_info;
1056         umadt_obj_t *p_umadt_obj;
1057         uint32_t timeout;
1058
1059         cl_list_item_t *p_list_item, *p_next_list_item;
1060
1061         CL_ASSERT(context);
1062
1063         p_mad_bind_info = (mad_bind_info_t *) context;
1064         p_umadt_obj = p_mad_bind_info->p_umadt_obj;
1065         timeout = p_umadt_obj->timeout * 1000;
1066
1067         current_time = cl_get_time_stamp();
1068
1069         cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
1070
1071         p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
1072         while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
1073
1074                 p_next_list_item = cl_qlist_next(p_list_item);
1075
1076                 /*  DEFAULT_PKT_TIMEOUT is in milli seconds */
1077                 if (current_time - ((trans_context_t *) p_list_item)->sent_time
1078                     > timeout) {
1079                         /*  Add this transaction to the timeout_list */
1080                         cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
1081                                              p_list_item);
1082                         cl_qlist_insert_tail(&p_mad_bind_info->timeout_list,
1083                                              p_list_item);
1084                 }
1085
1086                 p_list_item = p_next_list_item;
1087         }
1088
1089         cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
1090
1091         p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
1092         while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
1093                 osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
1094                         "__osm_vendor_timer_callback: "
1095                         "Timing out transaction context [0x%p].\n",
1096                         ((trans_context_t *) p_list_item)->context);
1097
1098                 (*(p_mad_bind_info->mad_recv_callback)) (NULL,
1099                                                          p_mad_bind_info->
1100                                                          client_context,
1101                                                          ((trans_context_t *)
1102                                                           p_list_item)->
1103                                                          context);
1104
1105                 p_next_list_item = cl_qlist_next(p_list_item);
1106                 cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
1107                                      p_list_item);
1108                 free(p_list_item);
1109                 p_list_item = p_next_list_item;
1110         }
1111
1112         cl_timer_start(&p_mad_bind_info->timeout_timer,
1113                        DEFAULT_TIMER_INTERVAL_MSEC);
1114
1115 }
1116
1117 #endif                          /* OSM_VENDOR_INTF_UMADT */