Ejemplo n.º 1
0
/****f* opensm: SM/__osm_sm_mad_ctrl_disp_done_callback
 * NAME
 * __osm_sm_mad_ctrl_disp_done_callback
 *
 * DESCRIPTION
 * This function is the Dispatcher callback that indicates
 * a received MAD has been processed by the recipient.
 *
 * SYNOPSIS
 */
static void
__osm_sm_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
{
	osm_sm_mad_ctrl_t *const p_ctrl = (osm_sm_mad_ctrl_t *) context;
	osm_madw_t *const p_madw = (osm_madw_t *) p_data;
	ib_smp_t *p_smp;

	OSM_LOG_ENTER(p_ctrl->p_log);

	/*
	   If the MAD that just finished processing was a response,
	   then retire the transaction, since we must have generated
	   the request.

	   Otherwise, retire the transaction if a response was expected,
	   as in the case of a send failure. If a response was not expected,
	   just put the MAD back in the pool, because the MAD was a query
	   from some outside agent, e.g. Get(SMInfo) from another SM.
	 */
	p_smp = osm_madw_get_smp_ptr(p_madw);
	if (ib_smp_is_response(p_smp)) {
		CL_ASSERT(p_madw->resp_expected == FALSE);
		__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
	} else if (p_madw->resp_expected == TRUE)
		__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
	else
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);

	OSM_LOG_EXIT(p_ctrl->p_log);
}
Ejemplo n.º 2
0
static void resp_make_resp_smp(IN osm_sm_t * sm, IN const ib_smp_t * p_src_smp,
                               IN ib_net16_t status,
                               IN const uint8_t * p_payload,
                               OUT ib_smp_t * p_dest_smp)
{
    OSM_LOG_ENTER(sm->p_log);

    CL_ASSERT(p_dest_smp);
    CL_ASSERT(p_src_smp);
    CL_ASSERT(!ib_smp_is_response(p_src_smp));

    *p_dest_smp = *p_src_smp;
    if (p_src_smp->method == IB_MAD_METHOD_GET ||
            p_src_smp->method == IB_MAD_METHOD_SET) {
        p_dest_smp->method = IB_MAD_METHOD_GET_RESP;
        p_dest_smp->status = status;
    } else if (p_src_smp->method == IB_MAD_METHOD_TRAP) {
        p_dest_smp->method = IB_MAD_METHOD_TRAP_REPRESS;
        p_dest_smp->status = 0;
    } else {
        OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 1302: "
                "src smp method unsupported 0x%X\n", p_src_smp->method);
        goto Exit;
    }

    if (p_src_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
        p_dest_smp->status |= IB_SMP_DIRECTION;

    p_dest_smp->dr_dlid = p_dest_smp->dr_slid;
    p_dest_smp->dr_slid = p_dest_smp->dr_dlid;
    memcpy(&p_dest_smp->data, p_payload, IB_SMP_DATA_SIZE);

Exit:
    OSM_LOG_EXIT(sm->p_log);
}
Ejemplo n.º 3
0
/****f* opensm: SM/__osm_sm_mad_ctrl_rcv_callback
 * NAME
 * __osm_sm_mad_ctrl_rcv_callback
 *
 * DESCRIPTION
 * This is the callback from the transport layer for received MADs.
 *
 * SYNOPSIS
 */
static void
__osm_sm_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw,
			       IN void *bind_context,
			       IN osm_madw_t * p_req_madw)
{
	osm_sm_mad_ctrl_t *p_ctrl = (osm_sm_mad_ctrl_t *) bind_context;
	ib_smp_t *p_smp;
	ib_net16_t status;

	OSM_LOG_ENTER(p_ctrl->p_log);

	CL_ASSERT(p_madw);

	/*
	   A MAD was received from the wire, possibly in response to a request.
	 */
	cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd);

	OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG, "%u QP0 MADs received\n",
		p_ctrl->p_stats->qp0_mads_rcvd);

	p_smp = osm_madw_get_smp_ptr(p_madw);

	/* if we are closing down simply do nothing */
	if (osm_exit_flag) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR,
			"Ignoring received mad - since we are exiting\n");

		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_DEBUG);

		/* retire the mad or put it back */
		if (ib_smp_is_response(p_smp) ||
		    (p_smp->method == IB_MAD_METHOD_TRAP_REPRESS)) {
			CL_ASSERT(p_madw->resp_expected == FALSE);
			__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
		} else if (p_madw->resp_expected == TRUE)
			__osm_sm_mad_ctrl_retire_trans_mad(p_ctrl, p_madw);
		else
			osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);

		goto Exit;
	}

	if (osm_log_is_active(p_ctrl->p_log, OSM_LOG_FRAMES))
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_FRAMES);

	if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
		status = ib_smp_get_status(p_smp);
	else
		status = p_smp->status;

	if (status != 0) {
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3111: "
			"Error status = 0x%X\n", status);
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
	}

	switch (p_smp->method) {
	case IB_MAD_METHOD_GET_RESP:
		CL_ASSERT(p_req_madw != NULL);
		__osm_sm_mad_ctrl_process_get_resp(p_ctrl, p_madw, p_req_madw);
		break;

	case IB_MAD_METHOD_GET:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_get(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_TRAP:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_trap(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_SET:
		CL_ASSERT(p_req_madw == NULL);
		__osm_sm_mad_ctrl_process_set(p_ctrl, p_madw);
		break;

	case IB_MAD_METHOD_SEND:
	case IB_MAD_METHOD_REPORT:
	case IB_MAD_METHOD_REPORT_RESP:
	case IB_MAD_METHOD_TRAP_REPRESS:
	default:
		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3112: "
			"Unsupported method = 0x%X\n", p_smp->method);
		osm_dump_dr_smp(p_ctrl->p_log, p_smp, OSM_LOG_ERROR);
		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_ctrl->p_log);
}