]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/libvendor/osm_vendor_al.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_al.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_AL
53
54 #include <stdlib.h>
55 #include <string.h>
56 #include <complib/cl_qlist.h>
57 #include <complib/cl_thread.h>
58 #include <complib/cl_math.h>
59 #include <complib/cl_debug.h>
60 #include <iba/ib_types.h>
61 #include <opensm/osm_madw.h>
62 #include <opensm/osm_log.h>
63 #include <opensm/osm_mad_pool.h>
64 #include <vendor/osm_vendor_api.h>
65
66 /****s* OpenSM: Vendor AL/osm_al_bind_info_t
67  * NAME
68  *   osm_al_bind_info_t
69  *
70  * DESCRIPTION
71  *    Structure containing bind information.
72  *
73  * SYNOPSIS
74  */
75 typedef struct _osm_al_bind_info {
76         osm_vendor_t *p_vend;
77         void *client_context;
78         ib_qp_handle_t h_qp;
79         ib_mad_svc_handle_t h_svc;
80         uint8_t port_num;
81         ib_pool_key_t pool_key;
82         osm_vend_mad_recv_callback_t rcv_callback;
83         osm_vend_mad_send_err_callback_t send_err_callback;
84         osm_mad_pool_t *p_osm_pool;
85         ib_av_handle_t h_dr_av;
86
87 } osm_al_bind_info_t;
88 /*
89  * FIELDS
90  * p_vend
91  *    Pointer to the vendor object.
92  *
93  * client_context
94  *    User's context passed during osm_bind
95  *
96  * h_qp
97  *    Handle the QP for this bind.
98  *
99  * h_qp_svc
100  *    Handle the QP mad service for this bind.
101  *
102  * port_num
103  *    Port number (within the HCA) of the bound port.
104  *
105  * pool_key
106  *    Pool key returned by all for this QP.
107  *
108  * h_dr_av
109  *    Address vector handle used for all directed route SMPs.
110  *
111  * SEE ALSO
112  *********/
113
114 /**********************************************************************
115  **********************************************************************/
116 inline static ib_api_status_t
117 __osm_al_convert_wcs(IN ib_wc_status_t const wc_status)
118 {
119         switch (wc_status) {
120         case IB_WCS_SUCCESS:
121                 return (IB_SUCCESS);
122
123         case IB_WCS_TIMEOUT_RETRY_ERR:
124                 return (IB_TIMEOUT);
125
126         default:
127                 return (IB_ERROR);
128         }
129 }
130
131 /**********************************************************************
132  **********************************************************************/
133 static void __osm_al_ca_err_callback(IN ib_async_event_rec_t * p_async_rec)
134 {
135         osm_vendor_t *p_vend = (osm_vendor_t *) p_async_rec->context;
136         OSM_LOG_ENTER(p_vend->p_log);
137
138         osm_log(p_vend->p_log, OSM_LOG_ERROR,
139                 "__osm_al_ca_err_callback: ERR 3B01: "
140                 "Event on channel adapter (%s).\n",
141                 ib_get_async_event_str(p_async_rec->code));
142
143         OSM_LOG_EXIT(p_vend->p_log);
144 }
145
146 /**********************************************************************
147  **********************************************************************/
148 static void __osm_al_ca_destroy_callback(IN void *context)
149 {
150         osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) context;
151         osm_vendor_t *p_vend = p_bind->p_vend;
152         OSM_LOG_ENTER(p_vend->p_log);
153
154         osm_log(p_vend->p_log, OSM_LOG_INFO,
155                 "__osm_al_ca_destroy_callback: "
156                 "Closing local channel adapter.\n");
157
158         OSM_LOG_EXIT(p_vend->p_log);
159 }
160
161 /**********************************************************************
162  **********************************************************************/
163 static void __osm_al_err_callback(IN ib_async_event_rec_t * p_async_rec)
164 {
165         osm_al_bind_info_t *p_bind =
166             (osm_al_bind_info_t *) p_async_rec->context;
167         osm_vendor_t *p_vend = p_bind->p_vend;
168         OSM_LOG_ENTER(p_vend->p_log);
169
170         osm_log(p_vend->p_log, OSM_LOG_ERROR,
171                 "__osm_al_err_callback: ERR 3B02: "
172                 "Error on QP (%s).\n",
173                 ib_get_async_event_str(p_async_rec->code));
174
175         OSM_LOG_EXIT(p_vend->p_log);
176 }
177
178 /**********************************************************************
179  **********************************************************************/
180 static void
181 __osm_al_send_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem)
182 {
183         osm_al_bind_info_t *const p_bind =
184             (osm_al_bind_info_t *) mad_svc_context;
185         osm_vendor_t *const p_vend = p_bind->p_vend;
186         osm_madw_t *const p_madw = (osm_madw_t *) p_elem->context1;
187         osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
188         ib_mad_t *p_mad;
189
190         OSM_LOG_ENTER(p_vend->p_log);
191
192         CL_ASSERT(p_vw);
193         CL_ASSERT(p_vw->h_av);
194
195         /*
196            Destroy the address vector as necessary.
197          */
198         if (p_vw->h_av != p_bind->h_dr_av) {
199                 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
200                         osm_log(p_vend->p_log, OSM_LOG_DEBUG,
201                                 "__osm_al_send_callback: "
202                                 "Destroying av handle %p.\n", p_vw->h_av);
203                 }
204
205                 ib_destroy_av(p_vw->h_av);
206         }
207
208         p_mad = ib_get_mad_buf(p_elem);
209
210         if (p_elem->resp_expected) {
211                 /*
212                    If the send was unsuccessful, notify the user
213                    for MADs that were expecting a response.
214                    A NULL mad wrapper parameter is the user's clue
215                    that the transaction turned sour.
216
217                    Otherwise, do nothing for successful sends when a
218                    reponse is expected.  The mad will be returned to the
219                    pool later.
220                  */
221                 p_madw->status = __osm_al_convert_wcs(p_elem->status);
222                 if (p_elem->status != IB_WCS_SUCCESS) {
223                         osm_log(p_vend->p_log, OSM_LOG_DEBUG,
224                                 "__osm_al_send_callback: "
225                                 "MAD completed with work queue error: %s.\n",
226                                 ib_get_wc_status_str(p_elem->status));
227                         /*
228                            Return any wrappers to the pool that may have been
229                            pre-emptively allocated to handle a receive.
230                          */
231                         if (p_vw->p_resp_madw) {
232                                 osm_mad_pool_put(p_bind->p_osm_pool,
233                                                  p_vw->p_resp_madw);
234                                 p_vw->p_resp_madw = NULL;
235                         }
236
237                         p_bind->send_err_callback(p_bind->client_context,
238                                                   p_madw);
239                 }
240         } else {
241                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
242                         "__osm_al_send_callback: "
243                         "Returning MAD to pool, TID = 0x%" PRIx64 ".\n",
244                         cl_ntoh64(p_mad->trans_id));
245                 osm_mad_pool_put(p_bind->p_osm_pool, p_madw);
246                 goto Exit;
247         }
248
249 Exit:
250         OSM_LOG_EXIT(p_vend->p_log);
251 }
252
253 /**********************************************************************
254  **********************************************************************/
255 static void
256 __osm_al_rcv_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem)
257 {
258         osm_al_bind_info_t *const p_bind =
259             (osm_al_bind_info_t *) mad_svc_context;
260         osm_vendor_t *const p_vend = p_bind->p_vend;
261         osm_madw_t *p_old_madw;
262         osm_madw_t *p_new_madw;
263         osm_vend_wrap_t *p_old_vw;
264         osm_vend_wrap_t *p_new_vw;
265         ib_mad_t *p_new_mad;
266         osm_mad_addr_t mad_addr;
267
268         OSM_LOG_ENTER(p_vend->p_log);
269
270         CL_ASSERT(p_elem->context1 == NULL);
271         CL_ASSERT(p_elem->context2 == NULL);
272
273         p_new_mad = ib_get_mad_buf(p_elem);
274
275         /*
276            In preperation for initializing the new mad wrapper,
277            Initialize the mad_addr structure for the received wire MAD.
278          */
279         mad_addr.dest_lid = p_elem->remote_lid;
280         mad_addr.path_bits = p_elem->path_bits;
281
282         /* TO DO - figure out which #define to use for the 2.5 Gb rate... */
283         mad_addr.static_rate = 0;
284
285         if (p_new_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
286             p_new_mad->mgmt_class == IB_MCLASS_SUBN_DIR) {
287                 mad_addr.addr_type.smi.source_lid = p_elem->remote_lid;
288         } else {
289                 mad_addr.addr_type.gsi.remote_qp = p_elem->remote_qp;
290                 mad_addr.addr_type.gsi.remote_qkey = p_elem->remote_qkey;
291                 mad_addr.addr_type.gsi.pkey_ix = p_elem->pkey_index;
292                 mad_addr.addr_type.gsi.service_level = p_elem->remote_sl;
293                 mad_addr.addr_type.gsi.global_route = FALSE;
294         }
295
296         /*
297            If this MAD is a response to a previous request,
298            then grab our pre-allocated MAD wrapper.
299            Otherwise, allocate a new MAD wrapper.
300          */
301         if (ib_mad_is_response(p_new_mad)) {
302                 CL_ASSERT(p_elem->send_context1 != NULL);
303                 CL_ASSERT(p_elem->send_context2 == NULL);
304
305                 p_old_madw = (osm_madw_t *) p_elem->send_context1;
306                 p_old_vw = osm_madw_get_vend_ptr(p_old_madw);
307                 p_new_madw = p_old_vw->p_resp_madw;
308
309                 CL_ASSERT(p_new_madw);
310
311                 osm_madw_init(p_new_madw, p_bind, p_elem->size, &mad_addr);
312                 osm_madw_set_mad(p_new_madw, p_new_mad);
313         } else {
314                 CL_ASSERT(p_elem->send_context1 == NULL);
315                 CL_ASSERT(p_elem->send_context2 == NULL);
316
317                 p_new_madw = osm_mad_pool_get_wrapper(p_bind->p_osm_pool,
318                                                       p_bind, p_elem->size,
319                                                       p_new_mad, &mad_addr);
320         }
321
322         CL_ASSERT(p_new_madw);
323         p_new_vw = osm_madw_get_vend_ptr(p_new_madw);
324
325         p_new_vw->h_bind = p_bind;
326         p_new_vw->size = p_elem->size;
327         p_new_vw->p_elem = p_elem;
328         p_new_vw->h_av = 0;
329         p_new_vw->p_resp_madw = NULL;
330
331         osm_log(p_vend->p_log, OSM_LOG_DEBUG,
332                 "__osm_al_rcv_callback: "
333                 "Calling receive callback function %p.\n",
334                 p_bind->rcv_callback);
335
336         p_bind->rcv_callback(p_new_madw, p_bind->client_context,
337                              p_elem->send_context1);
338
339         OSM_LOG_EXIT(p_vend->p_log);
340 }
341
342 /**********************************************************************
343  **********************************************************************/
344 ib_api_status_t
345 osm_vendor_init(IN osm_vendor_t * const p_vend,
346                 IN osm_log_t * const p_log, IN const uint32_t timeout)
347 {
348         ib_api_status_t status;
349         OSM_LOG_ENTER(p_log);
350
351         p_vend->p_log = p_log;
352
353         /*
354            Open our instance of AL.
355          */
356         status = ib_open_al(&p_vend->h_al);
357         if (status != IB_SUCCESS) {
358                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
359                         "osm_vendor_init: ERR 3B03: "
360                         "Error opening AL (%s).\n", ib_get_err_str(status));
361
362                 goto Exit;
363         }
364
365         p_vend->timeout = timeout;
366
367 Exit:
368         OSM_LOG_EXIT(p_log);
369         return (status);
370 }
371
372 /**********************************************************************
373  **********************************************************************/
374 osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
375                              IN const uint32_t timeout)
376 {
377         ib_api_status_t status;
378         osm_vendor_t *p_vend;
379
380         OSM_LOG_ENTER(p_log);
381
382         p_vend = malloc(sizeof(*p_vend));
383         if (p_vend == NULL) {
384                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
385                         "osm_vendor_new: ERR 3B04: "
386                         "Unable to allocate vendor object.\n");
387                 goto Exit;
388         }
389
390         memset(p_vend, 0, sizeof(*p_vend));
391
392         status = osm_vendor_init(p_vend, p_log, timeout);
393         if (status != IB_SUCCESS) {
394                 free(p_vend);
395                 p_vend = NULL;
396         }
397
398 Exit:
399         OSM_LOG_EXIT(p_log);
400         return (p_vend);
401 }
402
403 /**********************************************************************
404  **********************************************************************/
405 void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
406 {
407         /* TO DO - fill this in */
408         ib_close_al((*pp_vend)->h_al);
409         free(*pp_vend);
410         *pp_vend = NULL;
411 }
412
413 /**********************************************************************
414  **********************************************************************/
415 static ib_api_status_t
416 __osm_ca_info_init(IN osm_vendor_t * const p_vend,
417                    IN osm_ca_info_t * const p_ca_info,
418                    IN const ib_net64_t ca_guid)
419 {
420         ib_api_status_t status;
421
422         OSM_LOG_ENTER(p_vend->p_log);
423
424         p_ca_info->guid = ca_guid;
425
426         if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) {
427                 osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
428                         "__osm_ca_info_init: "
429                         "Querying CA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid));
430         }
431
432         status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, NULL,
433                                      &p_ca_info->attr_size);
434         if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) {
435                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
436                         "__osm_ca_info_init: ERR 3B05: "
437                         "Unexpected status getting CA attributes (%s).\n",
438                         ib_get_err_str(status));
439                 goto Exit;
440         }
441
442         CL_ASSERT(p_ca_info->attr_size);
443
444         p_ca_info->p_attr = malloc(p_ca_info->attr_size);
445         if (p_ca_info->p_attr == NULL) {
446                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
447                         "__osm_ca_info_init: ERR 3B06: "
448                         "Unable to allocate attribute storage.\n");
449                 goto Exit;
450         }
451
452         status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, p_ca_info->p_attr,
453                                      &p_ca_info->attr_size);
454         if (status != IB_SUCCESS) {
455                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
456                         "__osm_ca_info_init: ERR 3B07: "
457                         "Unexpected status getting CA attributes (%s).\n",
458                         ib_get_err_str(status));
459                 goto Exit;
460         }
461
462 Exit:
463         OSM_LOG_EXIT(p_vend->p_log);
464         return (status);
465 }
466
467 /**********************************************************************
468  **********************************************************************/
469 void
470 osm_ca_info_destroy(IN osm_vendor_t * const p_vend,
471                     IN osm_ca_info_t * const p_ca_info)
472 {
473         OSM_LOG_ENTER(p_vend->p_log);
474
475         if (p_ca_info->p_attr)
476                 free(p_ca_info->p_attr);
477
478         free(p_ca_info);
479
480         OSM_LOG_EXIT(p_vend->p_log);
481 }
482
483 /**********************************************************************
484  **********************************************************************/
485 osm_ca_info_t *osm_ca_info_new(IN osm_vendor_t * const p_vend,
486                                IN const ib_net64_t ca_guid)
487 {
488         ib_api_status_t status;
489         osm_ca_info_t *p_ca_info;
490
491         OSM_LOG_ENTER(p_vend->p_log);
492
493         CL_ASSERT(ca_guid);
494
495         p_ca_info = malloc(sizeof(*p_ca_info));
496         if (p_ca_info == NULL)
497                 goto Exit;
498
499         memset(p_ca_info, 0, sizeof(*p_ca_info));
500
501         status = __osm_ca_info_init(p_vend, p_ca_info, ca_guid);
502         if (status != IB_SUCCESS) {
503                 osm_ca_info_destroy(p_vend, p_ca_info);
504                 p_ca_info = NULL;
505                 goto Exit;
506         }
507
508 Exit:
509         OSM_LOG_EXIT(p_vend->p_log);
510         return (p_ca_info);
511 }
512
513 /**********************************************************************
514  **********************************************************************/
515 static ib_api_status_t
516 __osm_vendor_get_ca_guids(IN osm_vendor_t * const p_vend,
517                           IN ib_net64_t ** const p_guids,
518                           IN uintn_t * const p_num_guids)
519 {
520         ib_api_status_t status;
521
522         OSM_LOG_ENTER(p_vend->p_log);
523
524         CL_ASSERT(p_guids);
525         CL_ASSERT(p_num_guids);
526
527         status = ib_get_ca_guids(p_vend->h_al, NULL, p_num_guids);
528         if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) {
529                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
530                         "__osm_vendor_get_ca_guids: ERR 3B08: "
531                         "Unexpected status getting CA GUID array (%s).\n",
532                         ib_get_err_str(status));
533                 goto Exit;
534         }
535
536         if (*p_num_guids == 0) {
537                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
538                         "__osm_vendor_get_ca_guids: ERR 3B09: "
539                         "No available channel adapters.\n");
540                 status = IB_INSUFFICIENT_RESOURCES;
541                 goto Exit;
542         }
543
544         *p_guids = malloc(*p_num_guids * sizeof(**p_guids));
545         if (*p_guids == NULL) {
546                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
547                         "__osm_vendor_get_ca_guids: ERR 3B10: "
548                         "Unable to allocate CA GUID array.\n");
549                 goto Exit;
550         }
551
552         status = ib_get_ca_guids(p_vend->h_al, *p_guids, p_num_guids);
553         CL_ASSERT(*p_num_guids);
554
555         if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) {
556                 osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
557                         "__osm_vendor_get_ca_guids: "
558                         "Detected %u local channel adapters.\n", *p_num_guids);
559         }
560
561 Exit:
562         OSM_LOG_EXIT(p_vend->p_log);
563         return (status);
564 }
565
566 /****f* OpenSM: CA Info/osm_ca_info_get_pi_ptr
567  * NAME
568  * osm_ca_info_get_pi_ptr
569  *
570  * DESCRIPTION
571  * Returns a pointer to the port attribute of the specified port
572  * owned by this CA.
573  *
574  * SYNOPSIS
575  */
576 static ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t *
577                                                        const p_ca_info,
578                                                        IN const uint8_t index)
579 {
580         return (&p_ca_info->p_attr->p_port_attr[index]);
581 }
582
583 /*
584  * PARAMETERS
585  * p_ca_info
586  *    [in] Pointer to a CA Info object.
587  *
588  * index
589  *    [in] Port "index" for which to retrieve the port attribute.
590  *    The index is the offset into the ca's internal array
591  *    of port attributes.
592  *
593  * RETURN VALUE
594  * Returns a pointer to the port attribute of the specified port
595  * owned by this CA.
596  *
597  * NOTES
598  *
599  * SEE ALSO
600  *********/
601
602 /**********************************************************************
603  **********************************************************************/
604 ib_api_status_t
605 osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend,
606                              IN ib_port_attr_t * const p_attr_array,
607                              IN uint32_t * const p_num_ports)
608 {
609         ib_api_status_t status;
610
611         uint32_t ca;
612         uintn_t ca_count;
613         uint32_t port_count = 0;
614         uint8_t port_num;
615         uint32_t total_ports = 0;
616         ib_net64_t *p_ca_guid = NULL;
617         osm_ca_info_t *p_ca_info;
618
619         OSM_LOG_ENTER(p_vend->p_log);
620
621         CL_ASSERT(p_vend);
622         CL_ASSERT(p_vend->p_ca_info == NULL);
623
624         /*
625            1) Determine the number of CA's
626            2) Allocate an array big enough to hold the ca info objects.
627            3) Call again to retrieve the guids.
628          */
629         status = __osm_vendor_get_ca_guids(p_vend, &p_ca_guid, &ca_count);
630
631         p_vend->p_ca_info = malloc(ca_count * sizeof(*p_vend->p_ca_info));
632         if (p_vend->p_ca_info == NULL) {
633                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
634                         "osm_vendor_get_all_port_attr: ERR 3B11: "
635                         "Unable to allocate CA information array.\n");
636                 goto Exit;
637         }
638
639         memset(p_vend->p_ca_info, 0, ca_count * sizeof(*p_vend->p_ca_info));
640         p_vend->ca_count = ca_count;
641
642         /*
643            For each CA, retrieve the port info attributes
644          */
645         for (ca = 0; ca < ca_count; ca++) {
646                 p_ca_info = &p_vend->p_ca_info[ca];
647
648                 status = __osm_ca_info_init(p_vend, p_ca_info, p_ca_guid[ca]);
649
650                 if (status != IB_SUCCESS) {
651                         osm_log(p_vend->p_log, OSM_LOG_ERROR,
652                                 "osm_vendor_get_all_port_attr: ERR 3B12: "
653                                 "Unable to initialize CA Info object (%s).\n",
654                                 ib_get_err_str(status));
655                 }
656
657                 total_ports += osm_ca_info_get_num_ports(p_ca_info);
658         }
659
660         /*
661            If the user supplied enough storage, return the port guids,
662            otherwise, return the appropriate error.
663          */
664         if (*p_num_ports >= total_ports) {
665                 for (ca = 0; ca < ca_count; ca++) {
666                         uint32_t num_ports;
667
668                         p_ca_info = &p_vend->p_ca_info[ca];
669
670                         num_ports = osm_ca_info_get_num_ports(p_ca_info);
671
672                         for (port_num = 0; port_num < num_ports; port_num++) {
673                                 p_attr_array[port_count] =
674                                     *__osm_ca_info_get_port_attr_ptr(p_ca_info,
675                                                                      port_num);
676                                 port_count++;
677                         }
678                 }
679         } else {
680                 status = IB_INSUFFICIENT_MEMORY;
681         }
682
683         *p_num_ports = total_ports;
684
685 Exit:
686         if (p_ca_guid)
687                 free(p_ca_guid);
688
689         OSM_LOG_EXIT(p_vend->p_log);
690         return (status);
691 }
692
693 /**********************************************************************
694  **********************************************************************/
695 ib_net64_t
696 osm_vendor_get_ca_guid(IN osm_vendor_t * const p_vend,
697                        IN const ib_net64_t port_guid)
698 {
699         uint8_t index;
700         uint8_t num_ports;
701         uint32_t num_guids = 0;
702         osm_ca_info_t *p_ca_info;
703         uint32_t ca;
704
705         OSM_LOG_ENTER(p_vend->p_log);
706
707         CL_ASSERT(port_guid);
708         /*
709            First, locate the HCA that owns this port.
710          */
711         if (p_vend->p_ca_info == NULL) {
712                 /*
713                    Initialize the osm_ca_info_t array which allows
714                    us to match port GUID to CA.
715                  */
716                 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids);
717         }
718
719         CL_ASSERT(p_vend->p_ca_info);
720         CL_ASSERT(p_vend->ca_count);
721
722         for (ca = 0; ca < p_vend->ca_count; ca++) {
723                 p_ca_info = &p_vend->p_ca_info[ca];
724
725                 num_ports = osm_ca_info_get_num_ports(p_ca_info);
726                 CL_ASSERT(num_ports);
727
728                 for (index = 0; index < num_ports; index++) {
729                         if (port_guid ==
730                             osm_ca_info_get_port_guid(p_ca_info, index)) {
731                                 OSM_LOG_EXIT(p_vend->p_log);
732                                 return (osm_ca_info_get_ca_guid(p_ca_info));
733                         }
734                 }
735         }
736
737         /*
738            No local CA owns this guid!
739          */
740         osm_log(p_vend->p_log, OSM_LOG_ERROR,
741                 "osm_vendor_get_ca_guid: ERR 3B13: "
742                 "Unable to determine CA guid.\n");
743
744         OSM_LOG_EXIT(p_vend->p_log);
745         return (0);
746 }
747
748 /**********************************************************************
749  **********************************************************************/
750 uint8_t
751 osm_vendor_get_port_num(IN osm_vendor_t * const p_vend,
752                         IN const ib_net64_t port_guid)
753 {
754         uint8_t index;
755         uint8_t num_ports;
756         uint32_t num_guids = 0;
757         osm_ca_info_t *p_ca_info;
758         uint32_t ca;
759
760         OSM_LOG_ENTER(p_vend->p_log);
761
762         CL_ASSERT(port_guid);
763         /*
764            First, locate the HCA that owns this port.
765          */
766         if (p_vend->p_ca_info == NULL) {
767                 /*
768                    Initialize the osm_ca_info_t array which allows
769                    us to match port GUID to CA.
770                  */
771                 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids);
772         }
773
774         CL_ASSERT(p_vend->p_ca_info);
775         CL_ASSERT(p_vend->ca_count);
776
777         for (ca = 0; ca < p_vend->ca_count; ca++) {
778                 p_ca_info = &p_vend->p_ca_info[ca];
779
780                 num_ports = osm_ca_info_get_num_ports(p_ca_info);
781                 CL_ASSERT(num_ports);
782
783                 for (index = 0; index < num_ports; index++) {
784                         if (port_guid ==
785                             osm_ca_info_get_port_guid(p_ca_info, index)) {
786                                 OSM_LOG_EXIT(p_vend->p_log);
787                                 return (osm_ca_info_get_port_num
788                                         (p_ca_info, index));
789                         }
790                 }
791         }
792
793         /*
794            No local CA owns this guid!
795          */
796         osm_log(p_vend->p_log, OSM_LOG_ERROR,
797                 "osm_vendor_get_port_num: ERR 3B30: "
798                 "Unable to determine CA guid.\n");
799
800         OSM_LOG_EXIT(p_vend->p_log);
801         return (0);
802 }
803
804 /**********************************************************************
805  **********************************************************************/
806 static ib_api_status_t
807 __osm_vendor_open_ca(IN osm_vendor_t * const p_vend,
808                      IN const ib_net64_t port_guid)
809 {
810         ib_net64_t ca_guid;
811         ib_api_status_t status;
812
813         OSM_LOG_ENTER(p_vend->p_log);
814
815         ca_guid = osm_vendor_get_ca_guid(p_vend, port_guid);
816         if (ca_guid == 0) {
817                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
818                         "__osm_vendor_open_ca: ERR 3B31: "
819                         "Bad port GUID value 0x%" PRIx64 ".\n",
820                         cl_ntoh64(port_guid));
821                 status = IB_ERROR;
822                 goto Exit;
823         }
824
825         osm_log(p_vend->p_log, OSM_LOG_VERBOSE,
826                 "__osm_vendor_open_ca: "
827                 "Opening HCA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid));
828
829         status = ib_open_ca(p_vend->h_al,
830                             ca_guid,
831                             __osm_al_ca_err_callback, p_vend, &p_vend->h_ca);
832
833         if (status != IB_SUCCESS) {
834                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
835                         "__osm_vendor_open_ca: ERR 3B15: "
836                         "Unable to open CA (%s).\n", ib_get_err_str(status));
837                 goto Exit;
838         }
839
840         CL_ASSERT(p_vend->h_ca);
841
842         status = ib_alloc_pd(p_vend->h_ca, IB_PDT_ALIAS, p_vend, &p_vend->h_pd);
843
844         if (status != IB_SUCCESS) {
845                 ib_close_ca(p_vend->h_ca, __osm_al_ca_destroy_callback);
846                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
847                         "__osm_vendor_open_ca: ERR 3B16: "
848                         "Unable to allocate protection domain (%s).\n",
849                         ib_get_err_str(status));
850                 goto Exit;
851         }
852
853         CL_ASSERT(p_vend->h_pd);
854
855 Exit:
856         OSM_LOG_EXIT(p_vend->p_log);
857         return (status);
858 }
859
860 /**********************************************************************
861  **********************************************************************/
862 static void
863 __osm_vendor_init_av(IN const osm_al_bind_info_t * p_bind,
864                      IN ib_av_attr_t * p_av)
865 {
866         memset(p_av, 0, sizeof(*p_av));
867         p_av->port_num = p_bind->port_num;
868         p_av->dlid = IB_LID_PERMISSIVE;
869 }
870
871 /**********************************************************************
872  **********************************************************************/
873 osm_bind_handle_t
874 osm_vendor_bind(IN osm_vendor_t * const p_vend,
875                 IN osm_bind_info_t * const p_user_bind,
876                 IN osm_mad_pool_t * const p_mad_pool,
877                 IN osm_vend_mad_recv_callback_t mad_recv_callback,
878                 IN osm_vend_mad_send_err_callback_t send_err_callback,
879                 IN void *context)
880 {
881         ib_net64_t port_guid;
882         osm_al_bind_info_t *p_bind = 0;
883         ib_api_status_t status;
884         ib_qp_create_t qp_create;
885         ib_mad_svc_t mad_svc;
886         ib_av_attr_t av;
887
888         OSM_LOG_ENTER(p_vend->p_log);
889
890         CL_ASSERT(p_user_bind);
891         CL_ASSERT(p_mad_pool);
892         CL_ASSERT(mad_recv_callback);
893         CL_ASSERT(send_err_callback);
894
895         port_guid = p_user_bind->port_guid;
896
897         osm_log(p_vend->p_log, OSM_LOG_INFO,
898                 "osm_vendor_bind: "
899                 "Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
900
901         if (p_vend->h_ca == 0) {
902                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
903                         "osm_vendor_bind: "
904                         "Opening CA that owns port 0x%" PRIx64 ".\n",
905                         port_guid);
906
907                 status = __osm_vendor_open_ca(p_vend, port_guid);
908                 if (status != IB_SUCCESS) {
909                         osm_log(p_vend->p_log, OSM_LOG_ERROR,
910                                 "osm_vendor_bind: ERR 3B17: "
911                                 "Unable to Open CA (%s).\n",
912                                 ib_get_err_str(status));
913                         goto Exit;
914                 }
915         }
916
917         p_bind = malloc(sizeof(*p_bind));
918         if (p_bind == NULL) {
919                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
920                         "osm_vendor_bind: ERR 3B18: "
921                         "Unable to allocate internal bind object.\n");
922                 goto Exit;
923         }
924
925         memset(p_bind, 0, sizeof(*p_bind));
926         p_bind->p_vend = p_vend;
927         p_bind->client_context = context;
928         p_bind->port_num = osm_vendor_get_port_num(p_vend, port_guid);
929         p_bind->rcv_callback = mad_recv_callback;
930         p_bind->send_err_callback = send_err_callback;
931         p_bind->p_osm_pool = p_mad_pool;
932
933         CL_ASSERT(p_bind->port_num);
934
935         /*
936            Get the proper QP.
937          */
938         memset(&qp_create, 0, sizeof(qp_create));
939
940         switch (p_user_bind->mad_class) {
941         case IB_MCLASS_SUBN_LID:
942         case IB_MCLASS_SUBN_DIR:
943                 qp_create.qp_type = IB_QPT_QP0_ALIAS;
944                 break;
945
946         case IB_MCLASS_SUBN_ADM:
947         default:
948                 qp_create.qp_type = IB_QPT_QP1_ALIAS;
949                 break;
950         }
951
952         qp_create.sq_depth = p_user_bind->send_q_size;
953         qp_create.rq_depth = p_user_bind->recv_q_size;
954         qp_create.sq_sge = OSM_AL_SQ_SGE;
955         qp_create.rq_sge = OSM_AL_RQ_SGE;
956
957         status = ib_get_spl_qp(p_vend->h_pd,
958                                port_guid,
959                                &qp_create,
960                                p_bind,
961                                __osm_al_err_callback,
962                                &p_bind->pool_key, &p_bind->h_qp);
963
964         if (status != IB_SUCCESS) {
965                 free(p_bind);
966                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
967                         "osm_vendor_bind: ERR 3B19: "
968                         "Unable to get QP handle (%s).\n",
969                         ib_get_err_str(status));
970                 goto Exit;
971         }
972
973         CL_ASSERT(p_bind->h_qp);
974         CL_ASSERT(p_bind->pool_key);
975
976         memset(&mad_svc, 0, sizeof(mad_svc));
977
978         mad_svc.mad_svc_context = p_bind;
979         mad_svc.pfn_mad_send_cb = __osm_al_send_callback;
980         mad_svc.pfn_mad_recv_cb = __osm_al_rcv_callback;
981         mad_svc.mgmt_class = p_user_bind->mad_class;
982         mad_svc.mgmt_version = p_user_bind->class_version;
983         mad_svc.support_unsol = p_user_bind->is_responder;
984         mad_svc.method_array[IB_MAD_METHOD_GET] = TRUE;
985         mad_svc.method_array[IB_MAD_METHOD_SET] = TRUE;
986         mad_svc.method_array[IB_MAD_METHOD_DELETE] = TRUE;
987         mad_svc.method_array[IB_MAD_METHOD_TRAP] = TRUE;
988         mad_svc.method_array[IB_MAD_METHOD_GETTABLE] = TRUE;
989
990         status = ib_reg_mad_svc(p_bind->h_qp, &mad_svc, &p_bind->h_svc);
991
992         if (status != IB_SUCCESS) {
993                 free(p_bind);
994                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
995                         "osm_vendor_bind: ERR 3B21: "
996                         "Unable to register QP0 MAD service (%s).\n",
997                         ib_get_err_str(status));
998                 goto Exit;
999         }
1000
1001         __osm_vendor_init_av(p_bind, &av);
1002
1003         status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av);
1004         if (status != IB_SUCCESS) {
1005                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1006                         "osm_vendor_bind: ERR 3B22: "
1007                         "Unable to create address vector (%s).\n",
1008                         ib_get_err_str(status));
1009
1010                 goto Exit;
1011         }
1012
1013         if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
1014                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1015                         "osm_vendor_bind: "
1016                         "Allocating av handle %p.\n", p_bind->h_dr_av);
1017         }
1018
1019 Exit:
1020         OSM_LOG_EXIT(p_vend->p_log);
1021         return ((osm_bind_handle_t) p_bind);
1022 }
1023
1024 /**********************************************************************
1025  **********************************************************************/
1026 ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
1027                          IN const uint32_t mad_size,
1028                          IN osm_vend_wrap_t * const p_vw)
1029 {
1030         ib_mad_t *p_mad;
1031         osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1032         osm_vendor_t *p_vend = p_bind->p_vend;
1033         ib_api_status_t status;
1034
1035         OSM_LOG_ENTER(p_vend->p_log);
1036
1037         CL_ASSERT(p_vw);
1038
1039         p_vw->size = mad_size;
1040         p_vw->h_bind = h_bind;
1041
1042         /*
1043            Retrieve a MAD element from the pool and give the user direct
1044            access to its buffer.
1045          */
1046         status = ib_get_mad(p_bind->pool_key, mad_size, &p_vw->p_elem);
1047         if (status != IB_SUCCESS) {
1048                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1049                         "osm_vendor_get: ERR 3B25: "
1050                         "Unable to acquire MAD (%s).\n",
1051                         ib_get_err_str(status));
1052
1053                 p_mad = NULL;
1054                 goto Exit;
1055         }
1056
1057         CL_ASSERT(p_vw->p_elem);
1058         p_mad = ib_get_mad_buf(p_vw->p_elem);
1059
1060         if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
1061                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1062                         "osm_vendor_get: "
1063                         "Acquired MAD %p, size = %u.\n", p_mad, mad_size);
1064         }
1065
1066 Exit:
1067         OSM_LOG_EXIT(p_vend->p_log);
1068         return (p_mad);
1069 }
1070
1071 /**********************************************************************
1072  **********************************************************************/
1073 void
1074 osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
1075 {
1076         osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1077         osm_vendor_t *p_vend = p_bind->p_vend;
1078         ib_api_status_t status;
1079
1080         OSM_LOG_ENTER(p_vend->p_log);
1081
1082         CL_ASSERT(p_vw);
1083         CL_ASSERT(p_vw->p_elem);
1084         CL_ASSERT(p_vw->h_bind == h_bind);
1085
1086         if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
1087                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1088                         "osm_vendor_put: "
1089                         "Retiring MAD %p.\n", ib_get_mad_buf(p_vw->p_elem));
1090         }
1091
1092         status = ib_put_mad(p_vw->p_elem);
1093         if (status != IB_SUCCESS) {
1094                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1095                         "osm_vendor_put: ERR 3B26: "
1096                         "Unable to retire MAD (%s).\n", ib_get_err_str(status));
1097         }
1098
1099         OSM_LOG_EXIT(p_vend->p_log);
1100 }
1101
1102 /**********************************************************************
1103  **********************************************************************/
1104 ib_api_status_t
1105 osm_vendor_send(IN osm_bind_handle_t h_bind,
1106                 IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
1107 {
1108         osm_al_bind_info_t *const p_bind = h_bind;
1109         osm_vendor_t *const p_vend = p_bind->p_vend;
1110         osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
1111         osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
1112         ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
1113         ib_api_status_t status;
1114         ib_mad_element_t *p_elem;
1115         ib_av_attr_t av;
1116
1117         OSM_LOG_ENTER(p_vend->p_log);
1118
1119         CL_ASSERT(p_vw->h_bind == h_bind);
1120         CL_ASSERT(p_vw->p_elem);
1121
1122         p_elem = p_vw->p_elem;
1123
1124         /*
1125            If a response is expected to this MAD, then preallocate
1126            a mad wrapper to contain the wire MAD received in the
1127            response.  Allocating a wrapper here allows for easier
1128            failure paths than after we already received the wire mad.
1129          */
1130         if (resp_expected) {
1131                 p_vw->p_resp_madw =
1132                     osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
1133                 if (p_vw->p_resp_madw == NULL) {
1134                         osm_log(p_vend->p_log, OSM_LOG_ERROR,
1135                                 "osm_vendor_send: ERR 3B27: "
1136                                 "Unable to allocate MAD wrapper.\n");
1137                         status = IB_INSUFFICIENT_RESOURCES;
1138                         goto Exit;
1139                 }
1140         } else
1141                 p_vw->p_resp_madw = NULL;
1142
1143         /*
1144            For all sends other than directed route SM MADs,
1145            acquire an address vector for the destination.
1146          */
1147         if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
1148                 memset(&av, 0, sizeof(av));
1149                 av.port_num = p_bind->port_num;
1150                 av.dlid = p_mad_addr->dest_lid;
1151                 av.static_rate = p_mad_addr->static_rate;
1152                 av.path_bits = p_mad_addr->path_bits;
1153
1154                 if ((p_mad->mgmt_class != IB_MCLASS_SUBN_LID) &&
1155                     (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR)) {
1156                         av.sl = p_mad_addr->addr_type.gsi.service_level;
1157
1158                         if (p_mad_addr->addr_type.gsi.global_route) {
1159                                 av.grh_valid = TRUE;
1160                                 /* ANIL */
1161                                 /* av.grh = p_mad_addr->addr_type.gsi.grh_info; */
1162                         }
1163                 }
1164
1165                 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
1166                         osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1167                                 "osm_vendor_send: "
1168                                 "av.port_num 0x%X, "
1169                                 "av.dlid 0x%X, "
1170                                 "av.static_rate   %d, "
1171                                 "av.path_bits %d.\n",
1172                                 av.port_num, cl_ntoh16(av.dlid),
1173                                 av.static_rate, av.path_bits);
1174                 }
1175
1176                 status = ib_create_av(p_vend->h_pd, &av, &p_vw->h_av);
1177                 if (status != IB_SUCCESS) {
1178                         osm_log(p_vend->p_log, OSM_LOG_ERROR,
1179                                 "osm_vendor_send: ERR 3B28: "
1180                                 "Unable to create address vector (%s).\n",
1181                                 ib_get_err_str(status));
1182
1183                         if (p_vw->p_resp_madw)
1184                                 osm_mad_pool_put(p_bind->p_osm_pool,
1185                                                  p_vw->p_resp_madw);
1186                         goto Exit;
1187                 }
1188
1189                 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) {
1190                         osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1191                                 "osm_vendor_send: "
1192                                 "Allocating av handle %p.\n", p_vw->h_av);
1193                 }
1194         } else {
1195                 p_vw->h_av = p_bind->h_dr_av;
1196         }
1197
1198         p_elem->h_av = p_vw->h_av;
1199
1200         p_elem->context1 = p_madw;
1201         p_elem->context2 = NULL;
1202
1203         p_elem->immediate_data = 0;
1204         p_elem->p_grh = NULL;
1205         p_elem->resp_expected = resp_expected;
1206         p_elem->retry_cnt = OSM_DEFAULT_RETRY_COUNT;
1207
1208         p_elem->send_opt = IB_SEND_OPT_SIGNALED;
1209         p_elem->timeout_ms = p_vend->timeout;
1210
1211         /* Completion information. */
1212         p_elem->status = 0;     /* Not trusting AL */
1213
1214         if ((p_mad->mgmt_class == IB_MCLASS_SUBN_LID) ||
1215             (p_mad->mgmt_class == IB_MCLASS_SUBN_DIR)) {
1216                 p_elem->remote_qp = 0;
1217                 p_elem->remote_qkey = 0;
1218         } else {
1219                 p_elem->remote_qp = p_mad_addr->addr_type.gsi.remote_qp;
1220                 p_elem->remote_qkey = p_mad_addr->addr_type.gsi.remote_qkey;
1221                 osm_log(p_vend->p_log, OSM_LOG_DEBUG,
1222                         "osm_vendor_send: "
1223                         "remote qp = 0x%X, remote qkey = 0x%X.\n",
1224                         cl_ntoh32(p_elem->remote_qp),
1225                         cl_ntoh32(p_elem->remote_qkey));
1226         }
1227
1228         status = ib_send_mad(p_bind->h_svc, p_elem, NULL);
1229         if (status != IB_SUCCESS) {
1230                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1231                         "osm_vendor_send: ERR 3B29: "
1232                         "Send failed (%s).\n", ib_get_err_str(status));
1233                 if (p_vw->p_resp_madw)
1234                         osm_mad_pool_put(p_bind->p_osm_pool, p_vw->p_resp_madw);
1235                 goto Exit;
1236         }
1237
1238 Exit:
1239         OSM_LOG_EXIT(p_vend->p_log);
1240         return (status);
1241 }
1242
1243 /**********************************************************************
1244  **********************************************************************/
1245 ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
1246 {
1247         osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1248         osm_vendor_t *p_vend = p_bind->p_vend;
1249         ib_av_attr_t av;
1250         ib_api_status_t status;
1251
1252         OSM_LOG_ENTER(p_vend->p_log);
1253
1254         /*
1255            The only thing we need to do is refresh the directed
1256            route address vector.
1257          */
1258         __osm_vendor_init_av(p_bind, &av);
1259
1260         status = ib_destroy_av(p_bind->h_dr_av);
1261         if (status != IB_SUCCESS) {
1262                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1263                         "osm_vendor_local_lid_change: ERR 3B32: "
1264                         "Unable to destroy address vector (%s).\n",
1265                         ib_get_err_str(status));
1266
1267                 goto Exit;
1268         }
1269
1270         status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av);
1271         if (status != IB_SUCCESS) {
1272                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1273                         "osm_vendor_local_lid_change: ERR 3B33: "
1274                         "Unable to create address vector (%s).\n",
1275                         ib_get_err_str(status));
1276
1277                 goto Exit;
1278         }
1279
1280 Exit:
1281         OSM_LOG_EXIT(p_vend->p_log);
1282         return (status);
1283 }
1284
1285 /**********************************************************************
1286  **********************************************************************/
1287 void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
1288 {
1289         osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind;
1290         osm_vendor_t *p_vend = p_bind->p_vend;
1291         ib_api_status_t status;
1292         ib_port_attr_mod_t attr_mod;
1293
1294         OSM_LOG_ENTER(p_vend->p_log);
1295
1296         memset(&attr_mod, 0, sizeof(attr_mod));
1297
1298         attr_mod.cap.sm = is_sm_val;
1299
1300         status = ib_modify_ca(p_vend->h_ca, p_bind->port_num,
1301                               IB_CA_MOD_IS_SM, &attr_mod);
1302
1303         if (status != IB_SUCCESS) {
1304                 osm_log(p_vend->p_log, OSM_LOG_ERROR,
1305                         "osm_vendor_set_sm: ERR 3B34: "
1306                         "Unable set 'IS_SM' bit to:%u in port attributes (%s).\n",
1307                         is_sm_val, ib_get_err_str(status));
1308         }
1309
1310         OSM_LOG_EXIT(p_vend->p_log);
1311 }
1312
1313 /**********************************************************************
1314  **********************************************************************/
1315 void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
1316 {
1317
1318 }
1319
1320 #endif                          /* OSM_VENDOR_INTF_AL */