Пример #1
0
ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl, IN osm_vendor_t * p_vend,
			      IN osm_log_t * p_log, IN osm_stats_t * p_stats,
			      IN int32_t max_wire_smps,
			      IN int32_t max_wire_smps2,
			      IN uint32_t max_smps_timeout)
{
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_log);

	p_vl->p_vend = p_vend;
	p_vl->p_log = p_log;
	p_vl->p_stats = p_stats;
	p_vl->max_wire_smps = max_wire_smps;
	p_vl->max_wire_smps2 = max_wire_smps2;
	p_vl->max_smps_timeout = max_wire_smps < max_wire_smps2 ?
				 max_smps_timeout : EVENT_NO_TIMEOUT;

	status = cl_event_init(&p_vl->signal, FALSE);
	if (status != IB_SUCCESS)
		goto Exit;

	p_vl->state = OSM_VL15_STATE_READY;

	status = cl_spinlock_init(&p_vl->lock);
	if (status != IB_SUCCESS)
		goto Exit;

	/*
	   Initialize the thread after all other dependent objects
	   have been initialized.
	 */
	status = cl_thread_init(&p_vl->poller, vl15_poller, p_vl,
				"opensm poller");
Exit:
	OSM_LOG_EXIT(p_log);
	return status;
}
Пример #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);
}
Пример #3
0
osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,
		IN osm_bind_info_t * const p_osm_bind_info,
		IN osm_mad_pool_t * const p_mad_pool,
		IN osm_vend_mad_recv_callback_t mad_recv_callback,
		IN void *context)
{
	cl_status_t cl_status;
	FSTATUS Status;		/*  GEN1 Status for Umadt */

	mad_bind_info_t *p_mad_bind_info;
	RegisterClassStruct *p_umadt_reg_class;

	umadt_obj_t *p_umadt_obj;
	OSM_LOG_ENTER(((umadt_obj_t *) p_vend)->p_log);

	CL_ASSERT(p_vend);

	p_umadt_obj = (umadt_obj_t *) p_vend;

	/*  Sanity check */
	CL_ASSERT(p_umadt_obj->init_done);
	CL_ASSERT(p_osm_bind_info);
	CL_ASSERT(p_mad_pool);
	CL_ASSERT(mad_recv_callback);

	/*  Allocate memory for registering the handle. */
	p_mad_bind_info = (mad_bind_info_t *) malloc(sizeof(*p_mad_bind_info));
	if (p_mad_bind_info) {
		memset(p_mad_bind_info, 0, sizeof(*p_mad_bind_info));
		p_umadt_reg_class = &p_mad_bind_info->umadt_reg_class;
	}
	p_umadt_reg_class->PortGuid = cl_ntoh64(p_osm_bind_info->port_guid);
	p_umadt_reg_class->ClassId = p_osm_bind_info->mad_class;
	p_umadt_reg_class->ClassVersion = p_osm_bind_info->class_version;
	p_umadt_reg_class->isResponder = p_osm_bind_info->is_responder;
	p_umadt_reg_class->isTrapProcessor = p_osm_bind_info->is_trap_processor;
	p_umadt_reg_class->isReportProcessor =
	    p_osm_bind_info->is_report_processor;
	p_umadt_reg_class->SendQueueSize = p_osm_bind_info->send_q_size;
	p_umadt_reg_class->RecvQueueSize = p_osm_bind_info->recv_q_size;
	p_umadt_reg_class->NotifySendCompletion = TRUE;

	p_mad_bind_info->p_umadt_obj = p_umadt_obj;
	p_mad_bind_info->p_mad_pool = p_mad_pool;
	p_mad_bind_info->mad_recv_callback = mad_recv_callback;
	p_mad_bind_info->client_context = context;

	/*  register with Umadt for MAD interface */
	Status = p_umadt_obj->uMadtInterface.uMadtRegister(p_umadt_reg_class,
							   &p_mad_bind_info->
							   umadt_handle);
	if (Status != FSUCCESS) {
		free(p_mad_bind_info);
		OSM_LOG_EXIT(p_umadt_obj->p_log);
		return (OSM_BIND_INVALID_HANDLE);
	}
	CL_ASSERT(p_mad_bind_info->umadt_handle);
	/*  */
	/*  Start a worker thread to process receives. */
	/*  */
	cl_thread_construct(&p_mad_bind_info->recv_processor_thread);
	cl_status = cl_thread_init(&p_mad_bind_info->recv_processor_thread,
				   __mad_recv_processor,
				   (void *)p_mad_bind_info, "mad_recv_worker");
	CL_ASSERT(cl_status == CL_SUCCESS);

	cl_qlist_init(&p_mad_bind_info->trans_ctxt_list);
	cl_spinlock_construct(&p_mad_bind_info->trans_ctxt_lock);
	cl_spinlock_init(&p_mad_bind_info->trans_ctxt_lock);
	cl_spinlock_construct(&p_mad_bind_info->timeout_list_lock);
	cl_spinlock_init(&p_mad_bind_info->timeout_list_lock);

	cl_status = cl_timer_init(&p_mad_bind_info->timeout_timer,
				  __osm_vendor_timer_callback,
				  (void *)p_mad_bind_info);
	CL_ASSERT(cl_status == CL_SUCCESS);
	cl_qlist_init(&p_mad_bind_info->timeout_list);
	/*  */
	/*  Insert the mad_reg_struct in list and return pointer to it as the handle */
	/*  */
	cl_spinlock_acquire(&p_umadt_obj->register_lock);

	cl_qlist_insert_head(&p_umadt_obj->register_list,
			     &p_mad_bind_info->list_item);

	cl_spinlock_release(&p_umadt_obj->register_lock);

	/*
	   A timeout value of 0 means disable timeouts.
	 */
	if (p_umadt_obj->timeout) {
		cl_timer_start(&p_mad_bind_info->timeout_timer,
			       DEFAULT_TIMER_INTERVAL_MSEC);
	}

	OSM_LOG_EXIT(p_umadt_obj->p_log);
	return ((osm_bind_handle_t) p_mad_bind_info);
}
Пример #4
0
ib_api_status_t
osmv_transport_init(IN osm_bind_info_t * p_info,
		    IN char hca_id[VENDOR_HCA_MAXNAMES],
		    IN uint8_t hca_idx, IN osmv_bind_obj_t * p_bo)
{
	cl_status_t cl_st;
	char device_file[16];
	int device_fd;
	int ts_ioctl_ret;
	osmv_TOPSPIN_transport_mgr_t *p_mgr =
	    malloc(sizeof(osmv_TOPSPIN_transport_mgr_t));
	int qpn;

	if (!p_mgr) {
		return IB_INSUFFICIENT_MEMORY;
	}

	memset(p_mgr, 0, sizeof(osmv_TOPSPIN_transport_mgr_t));

	/* open TopSpin file device */
	/* HACK: assume last char in hostid is the HCA index */
	sprintf(device_file, "/dev/ts_ua%u", hca_idx);
	device_fd = open(device_file, O_RDWR);
	if (device_fd < 0) {
		fprintf(stderr, "Fatal: Fail to open the file:%s err:%d\n",
			device_file, errno);
		return IB_ERROR;
	}

	/*
	 * Create the MAD filter on this file handle.
	 */

	p_mgr->filter.port = p_bo->port_num;
	p_mgr->filter.direction = TS_IB_MAD_DIRECTION_IN;
	p_mgr->filter.mask =
	    TS_IB_MAD_FILTER_DIRECTION |
	    TS_IB_MAD_FILTER_PORT |
	    TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS;

	switch (p_info->mad_class) {
	case IB_MCLASS_SUBN_LID:
	case IB_MCLASS_SUBN_DIR:
		qpn = 0;
		p_mgr->filter.qpn = qpn;
		p_mgr->filter.mgmt_class = IB_MCLASS_SUBN_LID;
		ts_ioctl_ret =
		    ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter);
		if (ts_ioctl_ret < 0) {
			return IB_ERROR;
		}

		p_mgr->filter.mgmt_class = IB_MCLASS_SUBN_DIR;
		ts_ioctl_ret =
		    ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter);
		if (ts_ioctl_ret < 0) {
			return IB_ERROR;
		}

		break;

	case IB_MCLASS_SUBN_ADM:
	default:
		qpn = 1;
		p_mgr->filter.qpn = qpn;
		p_mgr->filter.mgmt_class = p_info->mad_class;
		ts_ioctl_ret =
		    ioctl(device_fd, TS_IB_IOCSMADFILTADD, &p_mgr->filter);
		if (ts_ioctl_ret < 0) {
			return IB_ERROR;
		}
		break;
	}

	p_mgr->device_fd = device_fd;

	p_bo->p_transp_mgr = p_mgr;

	/* 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;

	/* init receiver thread */
	cl_st =
	    cl_thread_init(&p_mgr->receiver, __osmv_TOPSPIN_receiver_thr,
			   (void *)p_bo, "osmv TOPSPIN rcv thr");

	return (ib_api_status_t) cl_st;
}