1 /*
2 * Copyright (c) 2004-2009 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 * Copyright (c) 2009 HNR Consulting. All rights reserved.
6 *
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
12 *
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
16 *
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer.
20 *
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 * SOFTWARE.
34 *
35 */
36
37 /*
38 * Abstract:
39 * Implementation of osm_sa_mad_ctrl_t.
40 * This object is part of the SA object.
41 */
42
43 #if HAVE_CONFIG_H
44 # include <config.h>
45 #endif /* HAVE_CONFIG_H */
46
47 #include <string.h>
48 #include <complib/cl_debug.h>
49 #include <iba/ib_types.h>
50 #include <opensm/osm_file_ids.h>
51 #define FILE_ID OSM_FILE_SA_MAD_CTRL_C
52 #include <vendor/osm_vendor_api.h>
53 #include <opensm/osm_sa_mad_ctrl.h>
54 #include <opensm/osm_msgdef.h>
55 #include <opensm/osm_helper.h>
56 #include <opensm/osm_sa.h>
57 #include <opensm/osm_opensm.h>
58
59 /****f* opensm: SA/sa_mad_ctrl_disp_done_callback
60 * NAME
61 * sa_mad_ctrl_disp_done_callback
62 *
63 * DESCRIPTION
64 * This function is the Dispatcher callback that indicates
65 * a received MAD has been processed by the recipient.
66 *
67 * SYNOPSIS
68 */
sa_mad_ctrl_disp_done_callback(IN void * context,IN void * p_data)69 static void sa_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
70 {
71 osm_sa_mad_ctrl_t *p_ctrl = context;
72 osm_madw_t *p_madw = p_data;
73
74 OSM_LOG_ENTER(p_ctrl->p_log);
75
76 CL_ASSERT(p_madw);
77 /*
78 Return the MAD & wrapper to the pool.
79 */
80 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
81 OSM_LOG_EXIT(p_ctrl->p_log);
82 }
83
84 /************/
85
86 /****f* opensm: SA/sa_mad_ctrl_process
87 * NAME
88 * sa_mad_ctrl_process
89 *
90 * DESCRIPTION
91 * This function handles known methods for received MADs.
92 *
93 * SYNOPSIS
94 */
sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,IN osm_madw_t * p_madw,IN boolean_t is_get_request)95 static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
96 IN osm_madw_t * p_madw,
97 IN boolean_t is_get_request)
98 {
99 ib_sa_mad_t *p_sa_mad;
100 cl_disp_reg_handle_t h_disp;
101 cl_status_t status;
102 cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
103 uint64_t last_dispatched_msg_queue_time_msec;
104 uint32_t num_messages;
105
106 OSM_LOG_ENTER(p_ctrl->p_log);
107
108 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
109
110 /*
111 If the dispatcher is showing us that it is overloaded
112 there is no point in placing the request in. We should instead
113 provide immediate response - IB_RESOURCE_BUSY
114 But how do we know?
115 The dispatcher reports back the number of outstanding messages and
116 the time the last message stayed in the queue.
117 HACK: Actually, we cannot send a mad from within the receive callback;
118 thus - we will just drop it.
119 */
120
121 if (!is_get_request && p_ctrl->p_set_disp) {
122 h_disp = p_ctrl->h_set_disp;
123 goto SKIP_QUEUE_CHECK;
124 }
125
126 h_disp = p_ctrl->h_disp;
127 cl_disp_get_queue_status(h_disp, &num_messages,
128 &last_dispatched_msg_queue_time_msec);
129
130 if (num_messages > 1 && p_ctrl->p_subn->opt.max_msg_fifo_timeout &&
131 last_dispatched_msg_queue_time_msec >
132 p_ctrl->p_subn->opt.max_msg_fifo_timeout) {
133 OSM_LOG(p_ctrl->p_log, OSM_LOG_INFO,
134 /* "Responding BUSY status since the dispatcher is already" */
135 "Dropping MAD since the dispatcher is already"
136 " overloaded with %u messages and queue time of:"
137 "%" PRIu64 "[msec]\n",
138 num_messages, last_dispatched_msg_queue_time_msec);
139
140 /* send a busy response */
141 /* osm_sa_send_error(p_ctrl->p_resp, p_madw, IB_RESOURCE_BUSY); */
142
143 /* return the request to the pool */
144 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
145
146 goto Exit;
147 }
148
149 SKIP_QUEUE_CHECK:
150 /*
151 Note that attr_id (like the rest of the MAD) is in
152 network byte order.
153 */
154 switch (p_sa_mad->attr_id) {
155 case IB_MAD_ATTR_CLASS_PORT_INFO:
156 msg_id = OSM_MSG_MAD_CLASS_PORT_INFO;
157 break;
158
159 case IB_MAD_ATTR_NODE_RECORD:
160 msg_id = OSM_MSG_MAD_NODE_RECORD;
161 break;
162
163 case IB_MAD_ATTR_PORTINFO_RECORD:
164 msg_id = OSM_MSG_MAD_PORTINFO_RECORD;
165 break;
166
167 case IB_MAD_ATTR_LINK_RECORD:
168 msg_id = OSM_MSG_MAD_LINK_RECORD;
169 break;
170
171 case IB_MAD_ATTR_SMINFO_RECORD:
172 msg_id = OSM_MSG_MAD_SMINFO_RECORD;
173 break;
174
175 case IB_MAD_ATTR_SERVICE_RECORD:
176 msg_id = OSM_MSG_MAD_SERVICE_RECORD;
177 break;
178
179 case IB_MAD_ATTR_PATH_RECORD:
180 msg_id = OSM_MSG_MAD_PATH_RECORD;
181 break;
182
183 case IB_MAD_ATTR_MCMEMBER_RECORD:
184 msg_id = OSM_MSG_MAD_MCMEMBER_RECORD;
185 break;
186
187 case IB_MAD_ATTR_INFORM_INFO:
188 msg_id = OSM_MSG_MAD_INFORM_INFO;
189 break;
190
191 case IB_MAD_ATTR_VLARB_RECORD:
192 msg_id = OSM_MSG_MAD_VL_ARB_RECORD;
193 break;
194
195 case IB_MAD_ATTR_SLVL_RECORD:
196 msg_id = OSM_MSG_MAD_SLVL_TBL_RECORD;
197 break;
198
199 case IB_MAD_ATTR_PKEY_TBL_RECORD:
200 msg_id = OSM_MSG_MAD_PKEY_TBL_RECORD;
201 break;
202
203 case IB_MAD_ATTR_LFT_RECORD:
204 msg_id = OSM_MSG_MAD_LFT_RECORD;
205 break;
206
207 case IB_MAD_ATTR_GUIDINFO_RECORD:
208 msg_id = OSM_MSG_MAD_GUIDINFO_RECORD;
209 break;
210
211 case IB_MAD_ATTR_INFORM_INFO_RECORD:
212 msg_id = OSM_MSG_MAD_INFORM_INFO_RECORD;
213 break;
214
215 case IB_MAD_ATTR_SWITCH_INFO_RECORD:
216 msg_id = OSM_MSG_MAD_SWITCH_INFO_RECORD;
217 break;
218
219 case IB_MAD_ATTR_MFT_RECORD:
220 msg_id = OSM_MSG_MAD_MFT_RECORD;
221 break;
222
223 #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
224 case IB_MAD_ATTR_MULTIPATH_RECORD:
225 msg_id = OSM_MSG_MAD_MULTIPATH_RECORD;
226 break;
227 #endif
228
229 default:
230 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A01: "
231 "Unsupported attribute 0x%X (%s)\n",
232 cl_ntoh16(p_sa_mad->attr_id),
233 ib_get_sa_attr_str(p_sa_mad->attr_id));
234 osm_dump_sa_mad_v2(p_ctrl->p_log, p_sa_mad, FILE_ID, OSM_LOG_ERROR);
235 }
236
237 if (msg_id != CL_DISP_MSGID_NONE) {
238 /*
239 Post this MAD to the dispatcher for asynchronous
240 processing by the appropriate controller.
241 */
242
243 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
244 "Posting Dispatcher message %s\n",
245 osm_get_disp_msg_str(msg_id));
246
247 status = cl_disp_post(h_disp, msg_id, p_madw,
248 sa_mad_ctrl_disp_done_callback, p_ctrl);
249
250 if (status != CL_SUCCESS) {
251 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A02: "
252 "Dispatcher post message failed (%s) for attribute 0x%X (%s)\n",
253 CL_STATUS_MSG(status),
254 cl_ntoh16(p_sa_mad->attr_id),
255 ib_get_sa_attr_str(p_sa_mad->attr_id));
256
257 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
258 goto Exit;
259 }
260 } else {
261 /*
262 There is an unknown MAD attribute type for which there is
263 no recipient. Simply retire the MAD here.
264 */
265 cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
266 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
267 }
268
269 Exit:
270 OSM_LOG_EXIT(p_ctrl->p_log);
271 }
272
273 /*
274 * PARAMETERS
275 *
276 * RETURN VALUES
277 *
278 * NOTES
279 *
280 * SEE ALSO
281 *********/
282
283 /****f* opensm: SA/sa_mad_ctrl_rcv_callback
284 * NAME
285 * sa_mad_ctrl_rcv_callback
286 *
287 * DESCRIPTION
288 * This is the callback from the transport layer for received MADs.
289 *
290 * SYNOPSIS
291 */
sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,IN void * context,IN osm_madw_t * p_req_madw)292 static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
293 IN osm_madw_t * p_req_madw)
294 {
295 osm_sa_mad_ctrl_t *p_ctrl = context;
296 ib_sa_mad_t *p_sa_mad;
297 boolean_t is_get_request = FALSE;
298
299 OSM_LOG_ENTER(p_ctrl->p_log);
300
301 CL_ASSERT(p_madw);
302
303 /*
304 A MAD was received from the wire, possibly in response to a request.
305 */
306 cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd);
307
308 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
309 "%u SA MADs received\n", p_ctrl->p_stats->sa_mads_rcvd);
310
311 /*
312 * C15-0.1.3 requires not responding to any MAD if the SM is
313 * not in active state!
314 * We will not respond if the sm_state is not MASTER, or if the
315 * first_time_master_sweep flag (of the subnet) is TRUE - this
316 * flag indicates that the master still didn't finish its first
317 * sweep, so the subnet is not up and stable yet.
318 */
319 if (p_ctrl->p_subn->sm_state != IB_SMINFO_STATE_MASTER) {
320 cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
321 OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
322 "Received SA MAD while SM not MASTER. MAD ignored\n");
323 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
324 goto Exit;
325 }
326 if (p_ctrl->p_subn->first_time_master_sweep == TRUE) {
327 cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
328 OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
329 "Received SA MAD while SM in first sweep. MAD ignored\n");
330 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
331 goto Exit;
332 }
333
334 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
335
336 if (OSM_LOG_IS_ACTIVE_V2(p_ctrl->p_log, OSM_LOG_FRAMES))
337 osm_dump_sa_mad_v2(p_ctrl->p_log, p_sa_mad, FILE_ID, OSM_LOG_FRAMES);
338
339 /*
340 * C15-0.1.5 - Table 185: SA Header - p884
341 * SM_key should be either 0 or match the current SM_Key
342 * otherwise discard the MAD.
343 */
344 if (p_sa_mad->sm_key != 0 &&
345 p_sa_mad->sm_key != p_ctrl->p_subn->opt.sa_key) {
346 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A04: "
347 "Non-Zero MAD SM_Key: 0x%" PRIx64 " != SM_Key: 0x%"
348 PRIx64 "; SA MAD ignored for method 0x%X attribute 0x%X (%s)\n",
349 cl_ntoh64(p_sa_mad->sm_key),
350 cl_ntoh64(p_ctrl->p_subn->opt.sa_key),
351 p_sa_mad->method, cl_ntoh16(p_sa_mad->attr_id),
352 ib_get_sa_attr_str(p_sa_mad->attr_id));
353 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
354 goto Exit;
355 }
356
357 switch (p_sa_mad->method) {
358 case IB_MAD_METHOD_REPORT_RESP:
359 /* we do not really do anything with report responses -
360 just retire the transaction */
361 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
362 "Received Report Response. Retiring the transaction\n");
363
364 if (p_req_madw)
365 osm_mad_pool_put(p_ctrl->p_mad_pool, p_req_madw);
366 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
367
368 break;
369
370 case IB_MAD_METHOD_GET:
371 case IB_MAD_METHOD_GETTABLE:
372 #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
373 case IB_MAD_METHOD_GETMULTI:
374 #endif
375 is_get_request = TRUE;
376 /* FALLTHROUGH */
377 case IB_MAD_METHOD_SET:
378 case IB_MAD_METHOD_DELETE:
379 /* if we are closing down simply do nothing */
380 if (osm_exit_flag)
381 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
382 else
383 sa_mad_ctrl_process(p_ctrl, p_madw, is_get_request);
384 break;
385
386 default:
387 cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
388 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A05: "
389 "Unsupported method = 0x%X\n", p_sa_mad->method);
390 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
391 goto Exit;
392 }
393
394 Exit:
395 OSM_LOG_EXIT(p_ctrl->p_log);
396 }
397
398 /*
399 * PARAMETERS
400 *
401 * RETURN VALUES
402 *
403 * NOTES
404 *
405 * SEE ALSO
406 *********/
407
408 /****f* opensm: SA/sa_mad_ctrl_send_err_callback
409 * NAME
410 * sa_mad_ctrl_send_err_callback
411 *
412 * DESCRIPTION
413 * This is the callback from the transport layer for send errors
414 * on MADs that were expecting a response.
415 *
416 * SYNOPSIS
417 */
sa_mad_ctrl_send_err_callback(IN void * context,IN osm_madw_t * p_madw)418 static void sa_mad_ctrl_send_err_callback(IN void *context,
419 IN osm_madw_t * p_madw)
420 {
421 osm_sa_mad_ctrl_t *p_ctrl = context;
422 cl_status_t status;
423
424 OSM_LOG_ENTER(p_ctrl->p_log);
425
426 /*
427 We should never be here since the SA never originates a request.
428 Unless we generated a Report(Notice)
429 */
430
431 CL_ASSERT(p_madw);
432
433 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A06: "
434 "MAD completed in error (%s): "
435 "%s(%s), attr_mod 0x%x, LID %u, TID 0x%" PRIx64 "\n",
436 ib_get_err_str(p_madw->status),
437 ib_get_sa_method_str(p_madw->p_mad->method),
438 ib_get_sa_attr_str(p_madw->p_mad->attr_id),
439 cl_ntoh32(p_madw->p_mad->attr_mod),
440 cl_ntoh16(p_madw->mad_addr.dest_lid),
441 cl_ntoh64(p_madw->p_mad->trans_id));
442
443 osm_dump_sa_mad_v2(p_ctrl->p_log, osm_madw_get_sa_mad_ptr(p_madw),
444 FILE_ID, OSM_LOG_ERROR);
445
446 /*
447 An error occurred. No response was received to a request MAD.
448 Retire the original request MAD.
449 */
450
451 if (osm_madw_get_err_msg(p_madw) != CL_DISP_MSGID_NONE) {
452 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
453 "Posting Dispatcher message %s\n",
454 osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));
455
456 if (p_ctrl->p_set_disp &&
457 (p_madw->p_mad->method == IB_MAD_METHOD_SET ||
458 p_madw->p_mad->method == IB_MAD_METHOD_DELETE))
459 status = cl_disp_post(p_ctrl->h_set_disp,
460 osm_madw_get_err_msg(p_madw),
461 p_madw,
462 sa_mad_ctrl_disp_done_callback,
463 p_ctrl);
464 else
465 status = cl_disp_post(p_ctrl->h_disp,
466 osm_madw_get_err_msg(p_madw),
467 p_madw,
468 sa_mad_ctrl_disp_done_callback,
469 p_ctrl);
470 if (status != CL_SUCCESS) {
471 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A07: "
472 "Dispatcher post message failed (%s)\n",
473 CL_STATUS_MSG(status));
474 }
475 } else /* No error message was provided, just retire the MAD. */
476 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
477
478 OSM_LOG_EXIT(p_ctrl->p_log);
479 }
480
481 /*
482 * PARAMETERS
483 *
484 * RETURN VALUES
485 *
486 * NOTES
487 *
488 * SEE ALSO
489 *********/
490
osm_sa_mad_ctrl_construct(IN osm_sa_mad_ctrl_t * p_ctrl)491 void osm_sa_mad_ctrl_construct(IN osm_sa_mad_ctrl_t * p_ctrl)
492 {
493 CL_ASSERT(p_ctrl);
494 memset(p_ctrl, 0, sizeof(*p_ctrl));
495 p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
496 p_ctrl->h_set_disp = CL_DISP_INVALID_HANDLE;
497 }
498
osm_sa_mad_ctrl_destroy(IN osm_sa_mad_ctrl_t * p_ctrl)499 void osm_sa_mad_ctrl_destroy(IN osm_sa_mad_ctrl_t * p_ctrl)
500 {
501 CL_ASSERT(p_ctrl);
502 cl_disp_unregister(p_ctrl->h_disp);
503 cl_disp_unregister(p_ctrl->h_set_disp);
504 }
505
osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,IN osm_sa_t * sa,IN osm_mad_pool_t * p_mad_pool,IN osm_vendor_t * p_vendor,IN osm_subn_t * p_subn,IN osm_log_t * p_log,IN osm_stats_t * p_stats,IN cl_dispatcher_t * p_disp,IN cl_dispatcher_t * p_set_disp)506 ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
507 IN osm_sa_t * sa,
508 IN osm_mad_pool_t * p_mad_pool,
509 IN osm_vendor_t * p_vendor,
510 IN osm_subn_t * p_subn,
511 IN osm_log_t * p_log,
512 IN osm_stats_t * p_stats,
513 IN cl_dispatcher_t * p_disp,
514 IN cl_dispatcher_t * p_set_disp)
515 {
516 ib_api_status_t status = IB_SUCCESS;
517
518 OSM_LOG_ENTER(p_log);
519
520 osm_sa_mad_ctrl_construct(p_ctrl);
521
522 p_ctrl->sa = sa;
523 p_ctrl->p_log = p_log;
524 p_ctrl->p_disp = p_disp;
525 p_ctrl->p_set_disp = p_set_disp;
526 p_ctrl->p_mad_pool = p_mad_pool;
527 p_ctrl->p_vendor = p_vendor;
528 p_ctrl->p_stats = p_stats;
529 p_ctrl->p_subn = p_subn;
530
531 p_ctrl->h_disp = cl_disp_register(p_disp, CL_DISP_MSGID_NONE, NULL,
532 p_ctrl);
533
534 if (p_ctrl->h_disp == CL_DISP_INVALID_HANDLE) {
535 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A08: "
536 "Dispatcher registration failed\n");
537 status = IB_INSUFFICIENT_RESOURCES;
538 goto Exit;
539 }
540
541 if (p_set_disp) {
542 p_ctrl->h_set_disp =
543 cl_disp_register(p_set_disp, CL_DISP_MSGID_NONE, NULL,
544 p_ctrl);
545
546 if (p_ctrl->h_set_disp == CL_DISP_INVALID_HANDLE) {
547 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A0A: "
548 "SA set dispatcher registration failed\n");
549 status = IB_INSUFFICIENT_RESOURCES;
550 goto Exit;
551 }
552 }
553
554 Exit:
555 OSM_LOG_EXIT(p_log);
556 return status;
557 }
558
osm_sa_mad_ctrl_bind(IN osm_sa_mad_ctrl_t * p_ctrl,IN ib_net64_t port_guid)559 ib_api_status_t osm_sa_mad_ctrl_bind(IN osm_sa_mad_ctrl_t * p_ctrl,
560 IN ib_net64_t port_guid)
561 {
562 osm_bind_info_t bind_info;
563 ib_api_status_t status = IB_SUCCESS;
564
565 OSM_LOG_ENTER(p_ctrl->p_log);
566
567 if (p_ctrl->h_bind != OSM_BIND_INVALID_HANDLE) {
568 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A09: "
569 "Multiple binds not allowed\n");
570 status = IB_ERROR;
571 goto Exit;
572 }
573
574 bind_info.class_version = 2;
575 bind_info.is_responder = TRUE;
576 bind_info.is_report_processor = FALSE;
577 bind_info.is_trap_processor = FALSE;
578 bind_info.mad_class = IB_MCLASS_SUBN_ADM;
579 bind_info.port_guid = port_guid;
580 bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
581 bind_info.send_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;
582 bind_info.timeout = p_ctrl->sa->p_subn->opt.transaction_timeout;
583 bind_info.retries = p_ctrl->sa->p_subn->opt.transaction_retries;
584
585 OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
586 "Binding to port GUID 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
587
588 p_ctrl->h_bind = osm_vendor_bind(p_ctrl->p_vendor, &bind_info,
589 p_ctrl->p_mad_pool,
590 sa_mad_ctrl_rcv_callback,
591 sa_mad_ctrl_send_err_callback, p_ctrl);
592
593 if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
594 status = IB_ERROR;
595 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A10: "
596 "Vendor specific bind failed (%s)\n",
597 ib_get_err_str(status));
598 goto Exit;
599 }
600
601 Exit:
602 OSM_LOG_EXIT(p_ctrl->p_log);
603 return status;
604 }
605
osm_sa_mad_ctrl_unbind(IN osm_sa_mad_ctrl_t * p_ctrl)606 ib_api_status_t osm_sa_mad_ctrl_unbind(IN osm_sa_mad_ctrl_t * p_ctrl)
607 {
608 ib_api_status_t status = IB_SUCCESS;
609
610 OSM_LOG_ENTER(p_ctrl->p_log);
611
612 if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
613 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A11: "
614 "No previous bind\n");
615 status = IB_ERROR;
616 goto Exit;
617 }
618
619 osm_vendor_unbind(p_ctrl->h_bind);
620 Exit:
621 OSM_LOG_EXIT(p_ctrl->p_log);
622 return status;
623 }
624