Exemplo n.º 1
0
osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,
		IN osm_bind_info_t * const p_bind_info,
		IN osm_mad_pool_t * const p_mad_pool,
		IN osm_vend_mad_recv_callback_t mad_recv_callback,
		IN osm_vend_mad_send_err_callback_t send_err_callback,
		IN void *context)
{
	osmv_bind_obj_t *p_bo;
	ib_api_status_t status;
	char hca_id[32];
	cl_status_t cl_st;
	cl_list_obj_t *p_obj;
	uint8_t hca_index;

	if (NULL == p_vend || NULL == p_bind_info || NULL == p_mad_pool
	    || NULL == mad_recv_callback || NULL == send_err_callback) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7302: "
			"NULL parameter passed in: p_vend=%p p_bind_info=%p p_mad_pool=%p recv_cb=%p send_err_cb=%p\n",
			p_vend, p_bind_info, p_mad_pool, mad_recv_callback,
			send_err_callback);

		return OSM_BIND_INVALID_HANDLE;
	}

	p_bo = malloc(sizeof(osmv_bind_obj_t));
	if (NULL == p_bo) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7303: could not allocate the bind object\n");
		return OSM_BIND_INVALID_HANDLE;
	}

	memset(p_bo, 0, sizeof(osmv_bind_obj_t));
	p_bo->p_vendor = p_vend;
	p_bo->recv_cb = mad_recv_callback;
	p_bo->send_err_cb = send_err_callback;
	p_bo->cb_context = context;
	p_bo->p_osm_pool = p_mad_pool;

	/* obtain the hca name and port num from the guid */
	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"osm_vendor_bind: "
		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
		cl_ntoh64(p_bind_info->port_guid));

	status = osm_vendor_get_guid_ca_and_port(p_bo->p_vendor,
						 p_bind_info->port_guid,
						 &(p_bo->hca_hndl),
						 hca_id,
						 &hca_index, &(p_bo->port_num));
	if (status != IB_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7304: "
			"Fail to find port number of port guid:0x%016" PRIx64
			"\n", p_bind_info->port_guid);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* Initialize the magic_ptr to the pointer of the p_bo info.
	   This will be used to signal when the object is being destroyed, so no
	   real action will be done then. */
	p_bo->magic_ptr = p_bo;

	p_bo->is_closing = FALSE;

	cl_spinlock_construct(&(p_bo->lock));
	cl_st = cl_spinlock_init(&(p_bo->lock));
	if (cl_st != CL_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7305: "
			"could not initialize the spinlock ...\n");
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"osm_vendor_bind: osmv_txnmgr_init ... \n");
	if (osmv_txnmgr_init(&p_bo->txn_mgr, p_vend->p_log, &(p_bo->lock)) !=
	    IB_SUCCESS) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7306: "
			"osmv_txnmgr_init failed \n");
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* Do the real job! (Transport-dependent) */
	if (IB_SUCCESS !=
	    osmv_transport_init(p_bind_info, hca_id, hca_index, p_bo)) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7307: "
			"osmv_transport_init failed \n");
		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}

	/* insert bind handle into db */
	p_obj = malloc(sizeof(cl_list_obj_t));
	if (NULL == p_obj) {

		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 7308: "
			"osm_vendor_bind: could not allocate the list object\n");

		osmv_transport_done(p_bo->p_transp_mgr);
		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
		cl_spinlock_destroy(&p_bo->lock);
		free(p_bo);
		return OSM_BIND_INVALID_HANDLE;
	}
	memset(p_obj, 0, sizeof(cl_list_obj_t));
	cl_qlist_set_obj(p_obj, p_bo);

	cl_qlist_insert_head(&p_vend->bind_handles, &p_obj->list_item);

	return (osm_bind_handle_t) p_bo;
}
Exemplo n.º 2
0
/**********************************************************************
 * BINDs a callback (rcv and send error) for a given class and method
 * defined by the given:  osm_bind_info_t
 **********************************************************************/
osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,
		IN osm_bind_info_t * const p_user_bind,
		IN osm_mad_pool_t * const p_mad_pool,
		IN osm_vend_mad_recv_callback_t mad_recv_callback,
		IN osm_vend_mad_send_err_callback_t send_err_callback,
		IN void *context)
{
	ib_net64_t port_guid;
	osm_ts_bind_info_t *p_bind = NULL;
	VAPI_hca_hndl_t hca_hndl;
	VAPI_hca_id_t hca_id;
	uint32_t port_num;
	ib_api_status_t status;
	int device_fd;
	char device_file[16];
	osm_ts_user_mad_filter filter;
	int ts_ioctl_ret;
	int qpn;

	OSM_LOG_ENTER(p_vend->p_log);

	CL_ASSERT(p_mad_pool);

	port_guid = p_user_bind->port_guid;

	osm_log(p_vend->p_log, OSM_LOG_INFO,
		"osm_vendor_bind: "
		"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));

	switch (p_user_bind->mad_class) {
	case IB_MCLASS_SUBN_LID:
	case IB_MCLASS_SUBN_DIR:
		p_bind = &(p_vend->smi_bind);
		qpn = 0;
		break;

	case IB_MCLASS_SUBN_ADM:
	default:
		p_bind = &(p_vend->gsi_bind);
		qpn = 1;
		break;
	}

	/* Make sure we did not previously opened the file */
	if (p_bind->ul_dev_fd >= 0) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 5004: "
			"Already binded to port %u\n", p_bind->port_num);
		goto Exit;
	}

	/*
	   We need to figure out what is the TS file name to attach to.
	   I guess it is following the index of the port in the table of
	   ports.
	 */

	/* obtain the hca name and port num from the guid */
	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"osm_vendor_bind: "
		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
		cl_ntoh64(port_guid));
	status =
	    osm_vendor_get_guid_ca_and_port(p_vend, port_guid, &hca_hndl,
					    &hca_id, &port_num);
	if (status != IB_SUCCESS) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 5005: "
			"Fail to find port number of port guid:0x%016" PRIx64
			"\n", port_guid);
		goto Exit;
	}

	/* the file name is just /dev/ts_ua0: */
	strcpy(device_file, "/dev/ts_ua0");

	osm_log(p_vend->p_log, OSM_LOG_ERROR,
		"osm_vendor_bind: " "Opening TS UL dev file:%s\n", device_file);

	/* Open the file ... */
	device_fd = open(device_file, O_RDWR);
	if (device_fd < 0) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 5006: "
			"Fail to open TS UL dev file:%s\n", device_file);
		goto Exit;
	}

	/* track this bind request info */
	p_bind->ul_dev_fd = device_fd;
	p_bind->port_num = port_num;
	p_bind->p_vend = p_vend;
	p_bind->client_context = context;
	p_bind->rcv_callback = mad_recv_callback;
	p_bind->send_err_callback = send_err_callback;
	p_bind->p_osm_pool = p_mad_pool;
	p_bind->hca_hndl = hca_hndl;

	/*
	 * Create the MAD filter on this file handle.
	 */
	filter.port = port_num;

	filter.qpn = qpn;
	filter.mgmt_class = p_user_bind->mad_class;
	filter.direction = TS_IB_MAD_DIRECTION_IN;
	filter.mask =
	    TS_IB_MAD_FILTER_DIRECTION |
	    TS_IB_MAD_FILTER_PORT |
	    TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS;

	ts_ioctl_ret = ioctl(device_fd, TS_IB_IOCSMADFILTADD, &filter);
	if (ts_ioctl_ret < 0) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"osm_vendor_bind: ERR 5014: "
			"Fail to register MAD filter with err:%u\n",
			ts_ioctl_ret);
		goto Exit;
	}

	/* Initialize the listener thread for this port */
	status = cl_thread_init(&p_bind->poller,
				__osm_vendor_ts_poller, p_bind,
				"osm ts poller");
	if (status != IB_SUCCESS)
		goto Exit;

Exit:
	OSM_LOG_EXIT(p_vend->p_log);
	return ((osm_bind_handle_t) p_bind);
}
Exemplo n.º 3
0
/*
 * Prepare an asynchronous QP (rcv) for sending inform info and
 * handling the incoming reports.
 *
 */
ib_api_status_t
osmt_bind_inform_qp(IN osmtest_t * const p_osmt, OUT osmt_qp_ctx_t * p_qp_ctx)
{
	ib_net64_t port_guid;
	VAPI_hca_hndl_t hca_hndl;
	VAPI_hca_id_t hca_id;
	uint32_t port_num;
	VAPI_ret_t vapi_ret;
	IB_MGT_ret_t mgt_ret;
	uint8_t hca_index;
	osm_log_t *p_log = &p_osmt->log;
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_log);

	port_guid = p_osmt->local_port.port_guid;

	OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to port 0x%" PRIx64 "\n",
		cl_ntoh64(port_guid));

	/* obtain the hca name and port num from the guid */
	OSM_LOG(p_log, OSM_LOG_DEBUG,
		"Finding CA and Port that owns port guid 0x%" PRIx64 "\n",
		port_guid);

	mgt_ret =
	    osm_vendor_get_guid_ca_and_port(p_osmt->p_vendor,
					    port_guid,
					    &hca_hndl,
					    &hca_id[0], &hca_index, &port_num);
	if (mgt_ret != IB_MGT_OK) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0109: "
			"Unable to obtain CA and port (%d).\n");
		status = IB_ERROR;
		goto Exit;
	}
#define OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY 0x80010000

	strncpy(p_qp_ctx->qp_bind_hndl.hca_id, hca_id, sizeof(hca_id));
	p_qp_ctx->qp_bind_hndl.hca_hndl = hca_hndl;
	p_qp_ctx->qp_bind_hndl.port_num = port_num;
	p_qp_ctx->qp_bind_hndl.max_outs_sq = 10;
	p_qp_ctx->qp_bind_hndl.max_outs_rq = 10;
	p_qp_ctx->qp_bind_hndl.qkey = OSMT_MTL_REVERSE_QP1_WELL_KNOWN_Q_KEY;

	vapi_ret = osmt_mtl_init_opened_hca(&p_qp_ctx->qp_bind_hndl);
	if (vapi_ret != VAPI_OK) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0114: "
			"Error initializing QP.\n");
		status = IB_ERROR;
		goto Exit;
	}

	/* we use the pre-allocated buffers for send and receive :
	   send from buf[0]
	   receive from buf[2]
	 */
	p_qp_ctx->p_send_buf =
	    (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + GRH_LEN;
	p_qp_ctx->p_recv_buf =
	    (uint8_t *) p_qp_ctx->qp_bind_hndl.buf_ptr + 2 * (GRH_LEN +
							      MAD_BLOCK_SIZE);

	/* Need to clear assigned memory of p_send_buf - before using it to send any data */
	memset(p_qp_ctx->p_send_buf, 0, MAD_BLOCK_SIZE);

	status = IB_SUCCESS;
	OSM_LOG(p_log, OSM_LOG_DEBUG, "Initialized QP:0x%X in VAPI Mode\n",
		p_qp_ctx->qp_bind_hndl.qp_id);

	OSM_LOG(p_log, OSM_LOG_DEBUG, "Binding to IB_MGT SMI\n");

	/* we also need a QP0 handle for sending packets */
	mgt_ret = IB_MGT_get_handle(hca_id, port_num, IB_MGT_SMI,
				    &(p_qp_ctx->ib_mgt_qp0_handle));
	if (IB_MGT_OK != mgt_ret) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0115: "
			"Error obtaining IB_MGT handle to SMI\n");
		status = IB_ERROR;
		goto Exit;
	}

Exit:
	OSM_LOG_EXIT(p_log);
	return status;
}