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