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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
38 * Implementation of osm_sm_mad_ctrl_t.
39 * This object represents the SM MAD request controller object.
40 * This object is part of the opensm family of objects.
45 #endif /* HAVE_CONFIG_H */
48 #include <complib/cl_debug.h>
49 #include <iba/ib_types.h>
50 #include <opensm/osm_sm_mad_ctrl.h>
51 #include <vendor/osm_vendor_api.h>
52 #include <opensm/osm_madw.h>
53 #include <opensm/osm_msgdef.h>
54 #include <opensm/osm_helper.h>
55 #include <opensm/osm_opensm.h>
57 /****f* opensm: SM/__osm_sm_mad_ctrl_retire_trans_mad
59 * __osm_sm_mad_ctrl_retire_trans_mad
62 * This function handles clean-up of MADs associated with the SM's
63 * outstanding transactions on the wire.
69 __osm_sm_mad_ctrl_retire_trans_mad(IN osm_sm_mad_ctrl_t * const p_ctrl,
70 IN osm_madw_t * const p_madw)
74 OSM_LOG_ENTER(p_ctrl->p_log);
78 Return the MAD & wrapper to the pool.
80 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
81 "Retiring MAD with TID 0x%" PRIx64 "\n",
82 cl_ntoh64(osm_madw_get_smp_ptr(p_madw)->trans_id));
84 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
86 outstanding = osm_stats_dec_qp0_outstanding(p_ctrl->p_stats);
88 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs outstanding%s\n",
89 p_ctrl->p_stats->qp0_mads_outstanding,
90 outstanding ? "" : ": wire is clean.");
92 OSM_LOG_EXIT(p_ctrl->p_log);
97 /****f* opensm: SM/__osm_sm_mad_ctrl_disp_done_callback
99 * __osm_sm_mad_ctrl_disp_done_callback
102 * This function is the Dispatcher callback that indicates
103 * a received MAD has been processed by the recipient.
108 __osm_sm_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
110 osm_sm_mad_ctrl_t *const p_ctrl = (osm_sm_mad_ctrl_t *) context;
111 osm_madw_t *const p_madw = (osm_madw_t *) p_data;
114 OSM_LOG_ENTER(p_ctrl->p_log);
117 If the MAD that just finished processing was a response,
118 then retire the transaction, since we must have generated
121 Otherwise, retire the transaction if a response was expected,
122 as in the case of a send failure. If a response was not expected,
123 just put the MAD back in the pool, because the MAD was a query
124 from some outside agent, e.g. Get(SMInfo) from another SM.
126 p_smp = osm_madw_get_smp_ptr(p_madw);
127 if (ib_smp_is_response(p_smp)) {
128 CL_ASSERT(p_madw->resp_expected == FALSE);
129 __osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
130 } else if (p_madw->resp_expected == TRUE)
131 __osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
133 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
135 OSM_LOG_EXIT(p_ctrl->p_log);
140 /****f* opensm: SM/__osm_sm_mad_ctrl_update_wire_stats
142 * __osm_sm_mad_ctrl_update_wire_stats
145 * Updates wire stats for outstanding MADs and calls the VL15 poller.
150 __osm_sm_mad_ctrl_update_wire_stats(IN osm_sm_mad_ctrl_t * const p_ctrl)
152 uint32_t mads_on_wire;
154 OSM_LOG_ENTER(p_ctrl->p_log);
157 cl_atomic_dec(&p_ctrl->p_stats->qp0_mads_outstanding_on_wire);
159 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
160 "%u SMPs on the wire, %u outstanding\n", mads_on_wire,
161 p_ctrl->p_stats->qp0_mads_outstanding);
164 We can signal the VL15 controller to send another MAD
165 if any are waiting for transmission.
167 osm_vl15_poll(p_ctrl->p_vl15);
168 OSM_LOG_EXIT(p_ctrl->p_log);
171 /****f* opensm: SM/__osm_sm_mad_ctrl_process_get_resp
173 * __osm_sm_mad_ctrl_process_get_resp
176 * This function handles method GetResp() for received MADs.
177 * This is the most common path for QP0 MADs.
182 __osm_sm_mad_ctrl_process_get_resp(IN osm_sm_mad_ctrl_t * const p_ctrl,
183 IN osm_madw_t * p_madw,
184 IN void *transaction_context)
188 osm_madw_t *p_old_madw;
189 cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
191 OSM_LOG_ENTER(p_ctrl->p_log);
194 CL_ASSERT(transaction_context);
196 p_smp = osm_madw_get_smp_ptr(p_madw);
198 if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR && !ib_smp_is_d(p_smp)) {
199 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3102: "
200 "'D' bit not set in returned SMP\n");
201 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
204 p_old_madw = (osm_madw_t *) transaction_context;
206 __osm_sm_mad_ctrl_update_wire_stats(p_ctrl);
209 Copy the MAD Wrapper context from the requesting MAD
210 to the new MAD. This mechanism allows the recipient
211 controller to recover its own context regarding this
212 MAD transaction. Once we've copied the context, we
213 can return the original MAD to the pool.
215 osm_madw_copy_context(p_madw, p_old_madw);
216 osm_mad_pool_put(p_ctrl->p_mad_pool, p_old_madw);
219 Note that attr_id (like the rest of the MAD) is in
222 switch (p_smp->attr_id) {
223 case IB_MAD_ATTR_NODE_DESC:
224 msg_id = OSM_MSG_MAD_NODE_DESC;
226 case IB_MAD_ATTR_NODE_INFO:
227 msg_id = OSM_MSG_MAD_NODE_INFO;
229 case IB_MAD_ATTR_SWITCH_INFO:
230 msg_id = OSM_MSG_MAD_SWITCH_INFO;
232 case IB_MAD_ATTR_PORT_INFO:
233 msg_id = OSM_MSG_MAD_PORT_INFO;
235 case IB_MAD_ATTR_LIN_FWD_TBL:
236 msg_id = OSM_MSG_MAD_LFT;
238 case IB_MAD_ATTR_MCAST_FWD_TBL:
239 msg_id = OSM_MSG_MAD_MFT;
241 case IB_MAD_ATTR_SM_INFO:
242 msg_id = OSM_MSG_MAD_SM_INFO;
244 case IB_MAD_ATTR_SLVL_TABLE:
245 msg_id = OSM_MSG_MAD_SLVL;
247 case IB_MAD_ATTR_VL_ARBITRATION:
248 msg_id = OSM_MSG_MAD_VL_ARB;
250 case IB_MAD_ATTR_P_KEY_TABLE:
251 msg_id = OSM_MSG_MAD_PKEY;
254 case IB_MAD_ATTR_GUID_INFO:
255 case IB_MAD_ATTR_CLASS_PORT_INFO:
256 case IB_MAD_ATTR_NOTICE:
257 case IB_MAD_ATTR_INFORM_INFO:
259 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
260 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3103: "
261 "Unsupported attribute = 0x%X\n",
262 cl_ntoh16(p_smp->attr_id));
263 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
267 if (msg_id == CL_DISP_MSGID_NONE)
271 Post this MAD to the dispatcher for asynchronous
272 processing by the appropriate controller.
275 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
276 osm_get_disp_msg_str(msg_id));
278 status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
279 __osm_sm_mad_ctrl_disp_done_callback, p_ctrl);
281 if (status != CL_SUCCESS) {
282 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3104: "
283 "Dispatcher post message failed (%s) for attribute = 0x%X\n",
284 CL_STATUS_MSG(status), cl_ntoh16(p_smp->attr_id));
289 OSM_LOG_EXIT(p_ctrl->p_log);
292 /****f* opensm: SM/__osm_sm_mad_ctrl_process_get
294 * __osm_sm_mad_ctrl_process_get
297 * This function handles method Get() for received MADs.
302 __osm_sm_mad_ctrl_process_get(IN osm_sm_mad_ctrl_t * const p_ctrl,
303 IN osm_madw_t * p_madw)
307 cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
309 OSM_LOG_ENTER(p_ctrl->p_log);
311 p_smp = osm_madw_get_smp_ptr(p_madw);
314 Note that attr_id (like the rest of the MAD) is in
317 switch (p_smp->attr_id) {
318 case IB_MAD_ATTR_SM_INFO:
319 msg_id = OSM_MSG_MAD_SM_INFO;
323 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
324 OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
325 "Ignoring SubnGet MAD - unsupported attribute = 0x%X\n",
326 cl_ntoh16(p_smp->attr_id));
330 if (msg_id == CL_DISP_MSGID_NONE) {
332 There is an unknown MAD attribute type for which there is
333 no recipient. Simply retire the MAD here.
335 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
340 Post this MAD to the dispatcher for asynchronous
341 processing by the appropriate controller.
344 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
345 osm_get_disp_msg_str(msg_id));
347 status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
348 __osm_sm_mad_ctrl_disp_done_callback, p_ctrl);
350 if (status != CL_SUCCESS) {
351 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3106: "
352 "Dispatcher post message failed (%s)\n",
353 CL_STATUS_MSG(status));
358 OSM_LOG_EXIT(p_ctrl->p_log);
371 /****f* opensm: SM/__osm_sm_mad_ctrl_process_set
373 * __osm_sm_mad_ctrl_process_set
376 * This function handles method Set() for received MADs.
381 __osm_sm_mad_ctrl_process_set(IN osm_sm_mad_ctrl_t * const p_ctrl,
382 IN osm_madw_t * p_madw)
386 cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
388 OSM_LOG_ENTER(p_ctrl->p_log);
390 p_smp = osm_madw_get_smp_ptr(p_madw);
393 Note that attr_id (like the rest of the MAD) is in
396 switch (p_smp->attr_id) {
397 case IB_MAD_ATTR_SM_INFO:
398 msg_id = OSM_MSG_MAD_SM_INFO;
402 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
403 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3107: "
404 "Unsupported attribute = 0x%X\n",
405 cl_ntoh16(p_smp->attr_id));
406 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
410 if (msg_id == CL_DISP_MSGID_NONE) {
412 There is an unknown MAD attribute type for which there is
413 no recipient. Simply retire the MAD here.
415 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
420 Post this MAD to the dispatcher for asynchronous
421 processing by the appropriate controller.
424 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
425 osm_get_disp_msg_str(msg_id));
427 status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
428 __osm_sm_mad_ctrl_disp_done_callback, p_ctrl);
430 if (status != CL_SUCCESS) {
431 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3108: "
432 "Dispatcher post message failed (%s)\n",
433 CL_STATUS_MSG(status));
438 OSM_LOG_EXIT(p_ctrl->p_log);
451 /****f* opensm: SM/__osm_sm_mad_ctrl_process_trap
453 * __osm_sm_mad_ctrl_process_trap
456 * This function handles method Trap() for received MADs.
461 __osm_sm_mad_ctrl_process_trap(IN osm_sm_mad_ctrl_t * const p_ctrl,
462 IN osm_madw_t * p_madw)
466 cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
468 OSM_LOG_ENTER(p_ctrl->p_log);
470 p_smp = osm_madw_get_smp_ptr(p_madw);
472 /* Make sure OpenSM is master. If not - then we should not process the trap */
473 if (p_ctrl->p_subn->sm_state != IB_SMINFO_STATE_MASTER) {
474 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
475 "Received trap but OpenSM is not in MASTER state. "
477 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
482 Note that attr_id (like the rest of the MAD) is in
485 switch (p_smp->attr_id) {
486 case IB_MAD_ATTR_NOTICE:
487 msg_id = OSM_MSG_MAD_NOTICE;
491 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
492 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3109: "
493 "Unsupported attribute = 0x%X\n",
494 cl_ntoh16(p_smp->attr_id));
495 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
499 if (msg_id == CL_DISP_MSGID_NONE) {
501 There is an unknown MAD attribute type for which there is
502 no recipient. Simply retire the MAD here.
504 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
509 Post this MAD to the dispatcher for asynchronous
510 processing by the appropriate controller.
513 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "Posting Dispatcher message %s\n",
514 osm_get_disp_msg_str(msg_id));
516 status = cl_disp_post(p_ctrl->h_disp, msg_id, p_madw,
517 __osm_sm_mad_ctrl_disp_done_callback, p_ctrl);
519 if (status != CL_SUCCESS) {
520 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3110: "
521 "Dispatcher post message failed (%s)\n",
522 CL_STATUS_MSG(status));
527 OSM_LOG_EXIT(p_ctrl->p_log);
540 /****f* opensm: SM/__osm_sm_mad_ctrl_rcv_callback
542 * __osm_sm_mad_ctrl_rcv_callback
545 * This is the callback from the transport layer for received MADs.
550 __osm_sm_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,
551 IN void *bind_context,
552 IN osm_madw_t * p_req_madw)
554 osm_sm_mad_ctrl_t *p_ctrl = (osm_sm_mad_ctrl_t *) bind_context;
558 OSM_LOG_ENTER(p_ctrl->p_log);
563 A MAD was received from the wire, possibly in response to a request.
565 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd);
567 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs received\n",
568 p_ctrl->p_stats->qp0_mads_rcvd);
570 p_smp = osm_madw_get_smp_ptr(p_madw);
572 /* if we are closing down simply do nothing */
574 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR,
575 "Ignoring received mad - since we are exiting\n");
577 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_DEBUG);
579 /* retire the mad or put it back */
580 if (ib_smp_is_response(p_smp) ||
581 (p_smp->method == IB_MAD_METHOD_TRAP_REPRESS)) {
582 CL_ASSERT(p_madw->resp_expected == FALSE);
583 __osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
584 } else if (p_madw->resp_expected == TRUE)
585 __osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
587 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
592 if (osm_log_is_active(p_ctrl->p_log, OSM_LOG_FRAMES))
593 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_FRAMES);
595 if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
596 status = ib_smp_get_status(p_smp);
598 status = p_smp->status;
601 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3111: "
602 "Error status = 0x%X\n", status);
603 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
606 switch (p_smp->method) {
607 case IB_MAD_METHOD_GET_RESP:
608 CL_ASSERT(p_req_madw != NULL);
609 __osm_sm_mad_ctrl_process_get_resp(p_ctrl, p_madw, p_req_madw);
612 case IB_MAD_METHOD_GET:
613 CL_ASSERT(p_req_madw == NULL);
614 __osm_sm_mad_ctrl_process_get(p_ctrl, p_madw);
617 case IB_MAD_METHOD_TRAP:
618 CL_ASSERT(p_req_madw == NULL);
619 __osm_sm_mad_ctrl_process_trap(p_ctrl, p_madw);
622 case IB_MAD_METHOD_SET:
623 CL_ASSERT(p_req_madw == NULL);
624 __osm_sm_mad_ctrl_process_set(p_ctrl, p_madw);
627 case IB_MAD_METHOD_SEND:
628 case IB_MAD_METHOD_REPORT:
629 case IB_MAD_METHOD_REPORT_RESP:
630 case IB_MAD_METHOD_TRAP_REPRESS:
632 cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
633 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3112: "
634 "Unsupported method = 0x%X\n", p_smp->method);
635 osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
636 osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
641 OSM_LOG_EXIT(p_ctrl->p_log);
654 /****f* opensm: SM/__osm_sm_mad_ctrl_send_err_cb
656 * __osm_sm_mad_ctrl_send_err_cb
659 * This is the callback from the transport layer for send errors
660 * on MADs that were expecting a response.
665 __osm_sm_mad_ctrl_send_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
667 osm_sm_mad_ctrl_t *p_ctrl = (osm_sm_mad_ctrl_t *) bind_context;
668 ib_api_status_t status;
671 OSM_LOG_ENTER(p_ctrl->p_log);
675 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3113: "
676 "MAD completed in error (%s)\n",
677 ib_get_err_str(p_madw->status));
680 If this was a SubnSet MAD, then this error might indicate a problem
681 in configuring the subnet. In this case - need to mark that there was
682 such a problem. The subnet will not be up, and the next sweep should
683 be a heavy sweep as well.
685 p_smp = osm_madw_get_smp_ptr(p_madw);
686 if (p_smp->method == IB_MAD_METHOD_SET &&
687 (p_smp->attr_id == IB_MAD_ATTR_PORT_INFO ||
688 p_smp->attr_id == IB_MAD_ATTR_MCAST_FWD_TBL ||
689 p_smp->attr_id == IB_MAD_ATTR_SWITCH_INFO ||
690 p_smp->attr_id == IB_MAD_ATTR_LIN_FWD_TBL)) {
691 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3119: "
692 "Set method failed\n");
693 p_ctrl->p_subn->subnet_initialization_error = TRUE;
697 Since we did not get any response we suspect the DR path
698 used for the target port.
699 Find it and replace it with an alternate path.
700 This is true only if the destination lid is not 0xFFFF, since
701 then we are aiming for a specific path and not specific destination
704 /* For now - do not add the alternate dr path to the release */
706 if (p_madw->mad_addr.dest_lid != 0xFFFF) {
707 osm_physp_t *p_physp =
708 osm_get_physp_by_mad_addr(p_ctrl->p_log,
710 &(p_madw->mad_addr));
712 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3114: "
713 "Failed to find the corresponding phys port\n");
715 osm_physp_replace_dr_path_with_alternate_dr_path
716 (p_ctrl->p_log, p_ctrl->p_subn, p_physp,
723 An error occurred. No response was received to a request MAD.
724 Retire the original request MAD.
727 osm_dump_dr_smp(p_ctrl->p_log, osm_madw_get_smp_ptr(p_madw),
730 __osm_sm_mad_ctrl_update_wire_stats(p_ctrl);
732 if (osm_madw_get_err_msg(p_madw) != CL_DISP_MSGID_NONE) {
733 OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
734 "Posting Dispatcher message %s\n",
735 osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));
737 status = cl_disp_post(p_ctrl->h_disp,
738 osm_madw_get_err_msg(p_madw),
740 __osm_sm_mad_ctrl_disp_done_callback,
742 if (status != CL_SUCCESS)
743 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3115: "
744 "Dispatcher post message failed (%s)\n",
745 CL_STATUS_MSG(status));
748 No error message was provided, just retire the MAD.
750 __osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
752 OSM_LOG_EXIT(p_ctrl->p_log);
765 /**********************************************************************
766 **********************************************************************/
767 void osm_sm_mad_ctrl_construct(IN osm_sm_mad_ctrl_t * const p_ctrl)
770 memset(p_ctrl, 0, sizeof(*p_ctrl));
771 p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
774 /**********************************************************************
775 **********************************************************************/
776 void osm_sm_mad_ctrl_destroy(IN osm_sm_mad_ctrl_t * const p_ctrl)
780 if (p_ctrl->h_bind != CL_DISP_INVALID_HANDLE)
781 osm_vendor_unbind(p_ctrl->h_bind);
782 cl_disp_unregister(p_ctrl->h_disp);
785 /**********************************************************************
786 **********************************************************************/
788 osm_sm_mad_ctrl_init(IN osm_sm_mad_ctrl_t * const p_ctrl,
789 IN osm_subn_t * const p_subn,
790 IN osm_mad_pool_t * const p_mad_pool,
791 IN osm_vl15_t * const p_vl15,
792 IN osm_vendor_t * const p_vendor,
793 IN osm_log_t * const p_log,
794 IN osm_stats_t * const p_stats,
795 IN cl_plock_t * const p_lock,
796 IN cl_dispatcher_t * const p_disp)
798 ib_api_status_t status = IB_SUCCESS;
800 OSM_LOG_ENTER(p_log);
802 osm_sm_mad_ctrl_construct(p_ctrl);
804 p_ctrl->p_subn = p_subn;
805 p_ctrl->p_log = p_log;
806 p_ctrl->p_disp = p_disp;
807 p_ctrl->p_mad_pool = p_mad_pool;
808 p_ctrl->p_vendor = p_vendor;
809 p_ctrl->p_stats = p_stats;
810 p_ctrl->p_lock = p_lock;
811 p_ctrl->p_vl15 = p_vl15;
813 p_ctrl->h_disp = cl_disp_register(p_disp,
814 CL_DISP_MSGID_NONE, NULL, NULL);
816 if (p_ctrl->h_disp == CL_DISP_INVALID_HANDLE) {
817 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 3116: "
818 "Dispatcher registration failed\n");
819 status = IB_INSUFFICIENT_RESOURCES;
828 /**********************************************************************
829 **********************************************************************/
831 osm_sm_mad_ctrl_bind(IN osm_sm_mad_ctrl_t * const p_ctrl,
832 IN const ib_net64_t port_guid)
834 osm_bind_info_t bind_info;
835 ib_api_status_t status = IB_SUCCESS;
837 OSM_LOG_ENTER(p_ctrl->p_log);
839 if (p_ctrl->h_bind != OSM_BIND_INVALID_HANDLE) {
840 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3117: "
841 "Multiple binds not allowed\n");
846 bind_info.class_version = 1;
847 bind_info.is_report_processor = FALSE;
848 bind_info.is_responder = TRUE;
849 bind_info.is_trap_processor = TRUE;
850 bind_info.mad_class = IB_MCLASS_SUBN_DIR;
851 bind_info.port_guid = port_guid;
852 bind_info.recv_q_size = OSM_SM_DEFAULT_QP0_RCV_SIZE;
853 bind_info.send_q_size = OSM_SM_DEFAULT_QP0_SEND_SIZE;
855 OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
856 "Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
858 p_ctrl->h_bind = osm_vendor_bind(p_ctrl->p_vendor,
861 __osm_sm_mad_ctrl_rcv_callback,
862 __osm_sm_mad_ctrl_send_err_cb, p_ctrl);
864 if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
866 OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3118: "
867 "Vendor specific bind failed\n");
872 OSM_LOG_EXIT(p_ctrl->p_log);