* output: pkey_array\r
* return: uint16_t number of pkey(s) found\r
*************************************************************************************/\r
-static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array)\r
+static uint16_t\r
+__prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array)\r
{\r
uint16_t i, num_pKeys, cur_pkey_length;\r
NTSTATUS status;\r
BUS_EXIT( BUS_DBG_DRV );\r
return num_pKeys;\r
}\r
+\r
static NTSTATUS\r
__read_registry(\r
IN UNICODE_STRING* const p_registry_path )\r
#if DBG\r
if( g_al_dbg_flags & AL_DBG_ERR )\r
g_al_dbg_flags |= CL_DBG_ERROR;\r
+\r
+ bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP;\r
#endif\r
\r
BUS_TRACE(BUS_DBG_DRV ,\r
IN DRIVER_OBJECT *p_driver_obj,\r
IN UNICODE_STRING *p_registry_path )\r
{\r
- NTSTATUS status;\r
+ NTSTATUS status;\r
\r
BUS_ENTER( BUS_DBG_DRV );\r
\r
p_driver_obj->DriverUnload = bus_drv_unload;\r
p_driver_obj->DriverExtension->AddDevice = bus_add_device;\r
\r
+ // Mutex to synchronize multiple threads creating & deleting \r
+ // control deviceobjects. \r
+\r
+ ExInitializeFastMutex(&ControlMutex);\r
+ bfi_InstanceCount = 0;\r
+ memset( __out_bcount(sizeof(bus_filters)) (void*)bus_filters, 0,\r
+ sizeof(bus_filters) );\r
+\r
BUS_EXIT( BUS_DBG_DRV );\r
return STATUS_SUCCESS;\r
}\r
+\r
CL_TRACE_EXIT( lvl, bus_globals.dbg_lvl, msg )\r
\r
#define BUS_PRINT( lvl, msg ) \\r
- CL_PRINT( lvl, bus_globals.dbl_lvl, msg )\r
+ CL_PRINT( lvl, bus_globals.dbg_lvl, msg )\r
+\r
+/* single character Macro elemination */\r
+#define XBUS_PRINT( lvl, msg )\r
+#define XBUS_ENTER( lvl )\r
+#define XBUS_EXIT( lvl )\r
\r
#define BUS_DBG_ERROR CL_DBG_ERROR\r
#define BUS_DBG_DRV (1 << 0)\r
* in the paging, crash dump, or hibernation path.\r
*/\r
\r
-\r
/*\r
* Device extension for the device object that serves as entry point for \r
* the interface and IOCTL requests.\r
port_mgr_t *p_port_mgr;\r
iou_mgr_t *p_iou_mgr;\r
\r
- /* Interface names are generated by IoRegisterDeviceInterface. */\r
- UNICODE_STRING al_ifc_name;\r
- UNICODE_STRING ci_ifc_name;\r
-\r
/* Number of references on the upper interface. */\r
atomic32_t n_al_ifc_ref;\r
/* Number of references on the CI interface. */\r
atomic32_t n_ci_ifc_ref;\r
\r
+ struct _bus_filter_instance *bus_filter;\r
+\r
} bus_fdo_ext_t;\r
\r
\r
boolean_t b_reported_missing;\r
\r
/* Flag to control the behaviour of the driver during hibernation */\r
- uint32_t b_hibernating;\r
+ uint32_t b_hibernating;\r
\r
/* work item for handling Power Management request */\r
PIO_WORKITEM p_po_work_item;\r
/* Driver object. Used for registering of Plug and Play notifications. */\r
DRIVER_OBJECT *p_driver_obj;\r
\r
- /* Pointer to the one and only bus root. */\r
- bus_fdo_ext_t *p_bus_ext;\r
+ /* IBAL PNP event register handles */\r
+ ib_pnp_handle_t h_pnp_port;\r
+ ib_pnp_handle_t h_pnp_iou;\r
\r
} bus_globals_t;\r
\r
\r
extern bus_globals_t bus_globals;\r
\r
+/*\r
+ * Each instance of a bus filter on an HCA device stack (InfiniBandController)\r
+ * populates a bus_filter_t slot in bus_filters[MAX_BUS_FILTERS]; see\r
+ * bus_add_device(). Therefore MAX_BUS_FILTERS represents the MAX number of\r
+ * HCA's supported in a single system.\r
+ */\r
+#define MAX_BUS_FILTERS 16\r
+#define BFI_MAGIC 0xcafebabe\r
+\r
+#define BFI_PORT_MGR_OBJ 1\r
+#define BFI_IOU_MGR_OBJ 2\r
+\r
+\r
+typedef struct _bus_filter_instance\r
+{\r
+ /* Pointer to the bus filter instance FDO extention.\r
+ * if p_bus_ext is NULL, then it's an empty slot available for allocation\r
+ */\r
+ bus_fdo_ext_t *p_bus_ext;\r
+\r
+ /* HCA guid for which this bus filter is servicing */\r
+ ib_net64_t ca_guid;\r
+\r
+ /* PORT management - on a per HCA basis */\r
+ port_mgr_t *p_port_mgr;\r
+ cl_obj_t *p_port_mgr_obj;\r
+\r
+ /* IOU management - on a per HCA basis */\r
+ iou_mgr_t *p_iou_mgr;\r
+ cl_obj_t *p_iou_mgr_obj;\r
+#if DBG\r
+ ULONG magic; // initial/temp debug\r
+ char whoami[8];\r
+#endif\r
+\r
+} bus_filter_t;\r
+\r
+extern bus_filter_t bus_filters[MAX_BUS_FILTERS];\r
+extern ULONG bfi_InstanceCount;\r
+extern FAST_MUTEX ControlMutex; // serializes InstanceCount & bus_filters\r
+\r
+extern bus_filter_t *alloc_bfi( IN DRIVER_OBJECT *, OUT int * );\r
+extern int free_bfi( IN bus_filter_t *p_bfi );\r
+extern int get_bfi_count( void );\r
+extern bus_filter_t *get_bfi_by_obj( IN int obj_type, IN cl_obj_t *p_obj );\r
+extern bus_filter_t *get_bfi_by_ca_guid( IN net64_t ca_guid );\r
+extern bus_filter_t *get_set_bfi_by_ca_guid( IN net64_t ca_guid );\r
+extern char *get_obj_state_str(cl_state_t state);\r
\r
#endif /* !defined _BUS_DRIVER_H_ */\r
} bus_iou_ext_t;\r
\r
\r
-iou_mgr_t* gp_iou_mgr = NULL;\r
+typedef struct _iou_pnp_context\r
+{\r
+ bus_filter_t *p_bus_filter;\r
+ void *p_pdo_ext;\r
+\r
+} iou_pnp_ctx_t;\r
\r
\r
/*\r
IN cl_obj_t* p_obj );\r
\r
ib_api_status_t\r
-bus_reg_iou_pnp( void );\r
+bus_reg_iou_pnp(\r
+ IN bus_filter_t* p_bfi );\r
\r
ib_api_status_t\r
iou_mgr_pnp_cb(\r
*/\r
ib_api_status_t\r
create_iou_mgr(\r
+ IN bus_filter_t* p_bfi,\r
OUT iou_mgr_t** const pp_iou_mgr )\r
{\r
ib_api_status_t status;\r
cl_status_t cl_status;\r
+ iou_mgr_t *gp_iou_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- CL_ASSERT( !gp_iou_mgr );\r
+ CL_ASSERT( p_bfi->p_iou_mgr == NULL );\r
\r
gp_iou_mgr = cl_zalloc( sizeof(iou_mgr_t) );\r
if( !gp_iou_mgr )\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
- ("Failed to allocate port manager.\n") );\r
+ ("Failed to allocate IOU manager.\n") );\r
return IB_INSUFFICIENT_MEMORY;\r
}\r
+ p_bfi->p_iou_mgr = gp_iou_mgr;\r
\r
/* Construct the load service. */\r
cl_obj_construct( &gp_iou_mgr->obj, AL_OBJ_TYPE_LOADER );\r
+ p_bfi->p_iou_mgr_obj = &p_bfi->p_iou_mgr->obj; // save for destroy & free\r
cl_mutex_construct( &gp_iou_mgr->pdo_mutex );\r
cl_qlist_init( &gp_iou_mgr->iou_list );\r
\r
\r
/* Initialize the load service object. */\r
cl_status = cl_obj_init( &gp_iou_mgr->obj, CL_DESTROY_SYNC,\r
- destroying_iou_mgr, NULL, free_iou_mgr );\r
+ destroying_iou_mgr, NULL, free_iou_mgr );\r
if( cl_status != CL_SUCCESS )\r
{\r
free_iou_mgr( &gp_iou_mgr->obj );\r
return ib_convert_cl_status( cl_status );\r
}\r
\r
- /* Register for port PnP events. */\r
- status = bus_reg_iou_pnp();\r
+ /* Register for IOU PnP events. */\r
+ status = bus_reg_iou_pnp( p_bfi );\r
if( status != IB_SUCCESS )\r
{\r
- cl_obj_destroy( &gp_iou_mgr->obj );\r
+// cl_obj_destroy( &gp_iou_mgr->obj );\r
+ free_iou_mgr( &gp_iou_mgr->obj );\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
("bus_reg_iou_pnp returned %s.\n", ib_get_err_str(status)) );\r
return status;\r
}\r
\r
\r
+void\r
+destroy_iou_mgr_cb( IN void *context )\r
+{\r
+ iou_pnp_ctx_t *p_ctx = context;\r
+ bus_filter_t *p_bfi;\r
+\r
+ CL_ASSERT( p_ctx );\r
+ CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );\r
+\r
+ p_bfi = p_ctx->p_bus_filter;\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() Enter: obj %p?\n", __FUNCTION__,\r
+ p_bfi->p_iou_mgr_obj));\r
+\r
+ cl_obj_deref( p_bfi->p_iou_mgr_obj );\r
+ \r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() Exit: obj %p?\n", __FUNCTION__,\r
+ p_bfi->p_iou_mgr_obj));\r
+}\r
+\r
+\r
/*\r
* Pre-destroy the load service.\r
*/\r
IN cl_obj_t* p_obj )\r
{\r
ib_api_status_t status;\r
+ bus_filter_t *p_bfi;\r
+ iou_mgr_t *gp_iou_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_obj );\r
+ p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj );\r
+ if (p_bfi == NULL) {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n",\r
+ __FUNCTION__,p_obj));\r
+ return;\r
+ }\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_obj, gp_iou_mgr));\r
+\r
CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) );\r
- UNUSED_PARAM( p_obj );\r
\r
- /* Deregister for port PnP events. */\r
- if( gp_iou_mgr->h_pnp )\r
+ /* Deregister for iou PnP events. */\r
+ if( get_bfi_count() == 1 && bus_globals.h_pnp_iou )\r
{\r
- status = ib_dereg_pnp( gp_iou_mgr->h_pnp,\r
- (ib_pfn_destroy_cb_t)cl_obj_deref );\r
+ status = ib_dereg_pnp( bus_globals.h_pnp_iou, NULL );\r
+ bus_globals.h_pnp_iou = NULL;\r
CL_ASSERT( status == IB_SUCCESS );\r
}\r
+ cl_obj_deref( p_bfi->p_iou_mgr_obj );\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
{\r
bus_pdo_ext_t *p_ext;\r
cl_list_item_t *p_list_item;\r
+ bus_filter_t *p_bfi;\r
+ iou_mgr_t *gp_iou_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_obj );\r
+ p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj );\r
+ if ( p_bfi == NULL ) {\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s: unable to get p_bfi iou_obj %p?\n",\r
+ __FUNCTION__,p_obj) );\r
+ return;\r
+ }\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+ if ( !gp_iou_mgr ) {\r
+ // if create fails & then free is called, p_bfi->p_iou_mgr == NULL\r
+ return;\r
+ }\r
+\r
CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) );\r
\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s(%s) Mark all IOU PDOs as no longer present\n",\r
+ __FUNCTION__, p_bfi->whoami));\r
/*\r
- * Mark all IPoIB PDOs as no longer present. This will cause them\r
+ * Mark all IOU PDOs as no longer present. This will cause them\r
* to be removed when they process the IRP_MN_REMOVE_DEVICE.\r
*/\r
p_list_item = cl_qlist_remove_head( &gp_iou_mgr->iou_list );\r
{\r
CL_ASSERT( !p_ext->b_present );\r
p_ext->b_reported_missing = TRUE;\r
- BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d\n",\r
+ p_bfi->whoami,\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext,\r
+ p_ext->b_present, p_ext->b_reported_missing ) );\r
continue;\r
}\r
if( p_ext->h_ca )\r
/* Release the reference on the CA object. */\r
deref_al_obj( &p_ext->h_ca->obj );\r
}\r
+ BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s %s: PDO %p, ext %p\n",\r
+ p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_ext->cl_ext.p_self_do, p_ext ) );\r
+\r
+ BUS_TRACE( BUS_DBG_PNP,("%s(%s) p_ext->h_ca->obj.state %d ref_cnt %d\n",\r
+ __FUNCTION__, p_bfi->whoami,\r
+ p_ext->h_ca->obj.state,\r
+ p_ext->h_ca->obj.ref_cnt));//XXX\r
+\r
IoDeleteDevice( p_ext->cl_ext.p_self_do );\r
}\r
\r
cl_mutex_destroy( &gp_iou_mgr->pdo_mutex );\r
cl_obj_deinit( p_obj );\r
cl_free( gp_iou_mgr );\r
- gp_iou_mgr = NULL;\r
+\r
+ p_bfi->p_iou_mgr = NULL;\r
+ p_bfi->p_iou_mgr_obj = NULL;\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
* Register the load service for the given PnP class events.\r
*/\r
ib_api_status_t\r
-bus_reg_iou_pnp( void )\r
+bus_reg_iou_pnp( IN bus_filter_t *p_bfi )\r
{\r
ib_pnp_req_t pnp_req;\r
- ib_api_status_t status;\r
+ ib_api_status_t status = IB_SUCCESS;\r
\r
- cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
- pnp_req.pnp_class = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC;\r
- pnp_req.pnp_context = gp_iou_mgr;\r
- pnp_req.pfn_pnp_cb = iou_mgr_pnp_cb;\r
+ /* only need to register for PNP once */\r
+ if ( get_bfi_count() == 1 ) {\r
+ cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
+ pnp_req.pnp_class = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC;\r
+ pnp_req.pnp_context = NULL;\r
+ pnp_req.pfn_pnp_cb = iou_mgr_pnp_cb;\r
\r
- status = ib_reg_pnp( gh_al, &pnp_req, &gp_iou_mgr->h_pnp );\r
+ status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_iou );\r
+ }\r
\r
- if( status == IB_SUCCESS )\r
- {\r
+ if( status == IB_SUCCESS ) {\r
/* Reference the load service on behalf of the ib_reg_pnp call. */\r
- cl_obj_ref( &gp_iou_mgr->obj );\r
+ cl_obj_ref( &p_bfi->p_iou_mgr->obj );\r
}\r
\r
return status;\r
iou_mgr_pnp_cb(\r
IN ib_pnp_rec_t* p_pnp_rec )\r
{\r
- ib_api_status_t status;\r
+ ib_api_status_t status=IB_SUCCESS;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_pnp_rec );\r
- CL_ASSERT( gp_iou_mgr == p_pnp_rec->pnp_context );\r
\r
switch( p_pnp_rec->pnp_event )\r
{\r
\r
case IB_PNP_IOU_REMOVE:\r
iou_mgr_iou_remove( (ib_pnp_iou_rec_t*)p_pnp_rec );\r
+ break;\r
\r
default:\r
- status = IB_SUCCESS;\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n",\r
+ __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) ));\r
break;\r
}\r
BUS_EXIT( BUS_DBG_PNP );\r
IN IRP* const p_irp )\r
{\r
NTSTATUS status;\r
+ bus_filter_t *p_bfi;\r
+ iou_mgr_t *gp_iou_mgr;\r
+ DEVICE_RELATIONS *p_rel;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+\r
+ /* special case guid == 0 - walk all bus filter instances */\r
+ if ( ca_guid == 0ULL ) {\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+ if ( !gp_iou_mgr )\r
+ continue;\r
+ cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
+ status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp );\r
+ cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
+ }\r
+ p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
+ if ( p_rel ) {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n",\r
+ __FUNCTION__,p_rel->Count));\r
+ }\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return STATUS_SUCCESS;\r
+ }\r
+\r
+ p_bfi = get_bfi_by_ca_guid(ca_guid);\r
+ if (p_bfi == NULL) {\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s() Null p_bfi from ca_guid %I64x ?\n",__FUNCTION__,ca_guid));\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x iou_mgr %p\n",\r
+ __FUNCTION__, p_bfi->whoami, ca_guid, gp_iou_mgr) );\r
+ if (!gp_iou_mgr)\r
+ return STATUS_NO_SUCH_DEVICE;\r
+\r
cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp );\r
cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
\r
static ib_api_status_t\r
__iou_was_hibernated(\r
- IN ib_pnp_iou_rec_t* p_pnp_rec )\r
+ IN ib_pnp_iou_rec_t* p_pnp_rec,\r
+ IN bus_filter_t* p_bfi )\r
{\r
NTSTATUS status;\r
- cl_list_item_t *p_list_item;\r
- bus_iou_ext_t *p_iou_ext;\r
+ cl_list_item_t *p_list_item;\r
+ bus_iou_ext_t *p_iou_ext;\r
bus_pdo_ext_t *p_pdo_ext = NULL;\r
size_t n_devs = 0;\r
+ iou_mgr_t *gp_iou_mgr = p_bfi->p_iou_mgr;\r
cl_qlist_t* p_pdo_list = &gp_iou_mgr->iou_list;\r
+ iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
break;\r
}\r
\r
- BUS_TRACE( BUS_DBG_PNP, \r
- ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
- p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, "\r
+ "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
+ p_bfi->whoami,\r
+ p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_pdo_ext->cl_ext.p_self_do, \r
p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, \r
p_pdo_ext->b_hibernating, p_iou_ext->guid ) );\r
}\r
else \r
{\r
p_pdo_ext->b_hibernating = FALSE;\r
- p_pnp_rec->pnp_rec.context = p_pdo_ext;\r
+ p_ctx->p_pdo_ext = p_pdo_ext; // for iou_mgr_iou_remove()\r
+\r
status = IB_SUCCESS;\r
p_iou_ext = (bus_iou_ext_t*)p_pdo_ext;\r
- BUS_TRACE( BUS_DBG_PNP, \r
- ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
- p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Found PDO for %s: PDO %p, ext %p, "\r
+ "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
+ p_bfi->whoami,\r
+ p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_pdo_ext->cl_ext.p_self_do, \r
p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, \r
p_pdo_ext->b_hibernating, p_iou_ext->guid ) );\r
}\r
}\r
else \r
{\r
- BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid %I64x .\n",\r
- p_pnp_rec->pnp_rec.guid ) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid %I64x .\n",\r
+ p_bfi->whoami, p_pnp_rec->pnp_rec.guid ) );\r
status = IB_NOT_FOUND;\r
}\r
\r
NTSTATUS status;\r
DEVICE_OBJECT *p_pdo;\r
bus_iou_ext_t *p_iou_ext;\r
+ bus_filter_t *p_bfi;\r
+ iou_mgr_t *gp_iou_mgr;\r
+ iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but\r
+ p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->ca_guid );\r
+ if ( !p_bfi ) {\r
+ BUS_PRINT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n",\r
+ __FUNCTION__, p_pnp_rec->ca_guid ) );\r
+ return IB_ERROR;\r
+ }\r
+\r
+ if ( !p_ctx ) {\r
+ /*\r
+ * Allocate a PNP context for this object. pnp_rec.context is object\r
+ * unique.\r
+ */\r
+ p_ctx = cl_zalloc( sizeof(*p_ctx) );\r
+ if( !p_ctx )\r
+ {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) ca_guid 0x%I64x iou_guid(%I64x) "\r
+ "BAD alloc for PNP context\n", __FUNCTION__,\r
+ p_bfi->whoami, p_bfi->ca_guid, p_pnp_rec->guid ));\r
+\r
+ return IB_ERROR;\r
+ }\r
+ p_ctx->p_bus_filter = p_bfi;\r
+ p_pnp_rec->pnp_rec.context = p_ctx;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s(%s) ca_guid %I64x iou_guid(%I64x) ALLOC p_ctx @ %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+ p_pnp_rec->guid,p_ctx));\r
+ }\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+ /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but\r
marks with a flag. So we first try to find an existing PDO for this port,\r
- marked with this flag. If it was found, we turn off the flag and use this PDO */\r
- status = __iou_was_hibernated(p_pnp_rec);\r
+ marked with this flag. If it was found, we turn off the flag and use\r
+ this PDO */\r
+ status = __iou_was_hibernated( p_pnp_rec, p_bfi );\r
if( status != IB_NOT_FOUND )\r
{\r
BUS_EXIT( BUS_DBG_PNP );\r
\r
/* Create the PDO for the new port device. */\r
status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_iou_ext_t),\r
- NULL, FILE_DEVICE_CONTROLLER, \r
- FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
- FALSE, &p_pdo );\r
+ NULL, FILE_DEVICE_CONTROLLER, \r
+ FILE_DEVICE_SECURE_OPEN |\r
+ FILE_AUTOGENERATED_DEVICE_NAME,\r
+ FALSE, &p_pdo );\r
+\r
if( !NT_SUCCESS( status ) )\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
\r
/* Initialize the device extension. */\r
cl_init_pnp_po_ext( p_pdo, NULL, p_pdo, bus_globals.dbg_lvl,\r
- &vfptr_iou_pnp, &vfptr_iou_query_txt );\r
+ &vfptr_iou_pnp, &vfptr_iou_query_txt );\r
\r
/* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
p_pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
\r
p_iou_ext = p_pdo->DeviceExtension;\r
p_iou_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
- p_iou_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
+ p_iou_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
p_iou_ext->pdo.b_present = TRUE;\r
p_iou_ext->pdo.b_reported_missing = FALSE;\r
BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
- p_iou_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_iou_ext, p_iou_ext->pdo.b_present, p_iou_ext->pdo.b_reported_missing ) );\r
+ p_iou_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_iou_ext,\r
+ p_iou_ext->pdo.b_present, p_iou_ext->pdo.b_reported_missing ) );\r
\r
p_iou_ext->guid = p_pnp_rec->guid;\r
p_iou_ext->chassis_guid = p_pnp_rec->chassis_guid;\r
p_iou_ext->revision = cl_ntoh32( p_pnp_rec->revision );\r
cl_memcpy( p_iou_ext->desc, p_pnp_rec->desc,\r
IB_NODE_DESCRIPTION_SIZE + 1 );\r
+ p_iou_ext->n_ifc_ref = 0;\r
\r
/* Cache the CA GUID. */\r
p_iou_ext->pdo.ca_guid = p_pnp_rec->ca_guid;\r
\r
/* Store the device extension in the PDO list for future queries. */\r
cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
- cl_qlist_insert_tail( &gp_iou_mgr->iou_list,\r
- &p_iou_ext->pdo.list_item );\r
+ cl_qlist_insert_tail( &gp_iou_mgr->iou_list, &p_iou_ext->pdo.list_item );\r
cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
\r
/*\r
* Set the context of the PNP event. The context is passed in for future\r
* events on the same port.\r
*/\r
- p_pnp_rec->pnp_rec.context = p_iou_ext;\r
+ /* if not set in iou_was_hibernated(), set now */\r
+ if ( !p_ctx->p_pdo_ext )\r
+ p_ctx->p_pdo_ext = p_iou_ext;\r
\r
/* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
IoInvalidateDeviceRelations(\r
- p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
+ p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
\r
+#if 0 // XXX\r
/* Invalidate removal relations for the bus driver. */\r
IoInvalidateDeviceRelations(\r
- bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+ p_bfi->p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+#endif\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
\r
IN ib_pnp_iou_rec_t* p_pnp_rec )\r
{\r
bus_pdo_ext_t *p_ext;\r
+ iou_mgr_t *gp_iou_mgr;\r
+ bus_filter_t *p_bfi;\r
+ iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- /* The PNP record's context is the port extension. */\r
- p_ext = p_pnp_rec->pnp_rec.context;\r
+ if ( !p_ctx ) {\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return;\r
+ }\r
+\r
+ CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );\r
+ p_bfi = p_ctx->p_bus_filter;\r
+ CL_ASSERT( p_bfi );\r
+\r
+ BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x iou_mgr %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, p_bfi->p_iou_mgr));\r
+\r
+ /* fdo_release_resources() has destroyed the IOU mgr, all that needs to be\r
+ * done is cleanup the PNP IOU context; one per port.\r
+ */\r
+ if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_iou_mgr ) {\r
+ cl_free( p_ctx );\r
+ p_pnp_rec->pnp_rec.context = NULL;\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return;\r
+ }\r
+\r
+ gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+ /* Within the Bus fabric instance is the port extension; see\r
+ * was_hibernated().\r
+ */\r
+ p_ext = p_ctx->p_pdo_ext;\r
CL_ASSERT( p_ext );\r
\r
+ if (p_bfi != p_ext->p_parent_ext->bus_filter) {\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s() p_bfi(%p) != p_ext->bus_filter(%p) line %d file %s\n",\r
+ __FUNCTION__,p_bfi,p_ext->p_parent_ext->bus_filter,\r
+ __LINE__,__FILE__));\r
+ CL_ASSERT (p_bfi == p_ext->p_parent_ext->bus_filter);\r
+ }\r
+\r
/*\r
* Flag the port PDO as no longer being present. We have to wait until\r
* the PnP manager removes it to clean up. However, we do release the\r
* to proceed should it occur before the port's PDO is cleaned up.\r
*/\r
cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
- CL_ASSERT( p_ext->h_ca );\r
+ if ( !p_ext->h_ca )\r
+ {\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s() NULL h_ca? p_ext %p\n",\r
+ __FUNCTION__, p_ext ) );\r
+ return;\r
+ }\r
\r
if( p_ext->b_hibernating )\r
{\r
- BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, \r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Skip port removing for %s: PDO %p ext %p "\r
+ "present %d missing %d hibernating %d\n",\r
+ p_bfi->whoami,\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+ p_ext, p_ext->b_present, \r
p_ext->b_reported_missing, p_ext->b_hibernating ) );\r
goto hca_deref;\r
}\r
\r
p_ext->b_present = FALSE;\r
- BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+ p_ext->b_reported_missing = TRUE;\r
+\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d .\n",\r
+ p_bfi->whoami,\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present,\r
+ p_ext->b_reported_missing ) );\r
\r
+#if 0 // XXX\r
/* Invalidate removal relations for the bus driver. */\r
- IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,\r
- RemovalRelations );\r
+ IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo,\r
+ RemovalRelations );\r
+#endif\r
\r
/* Invalidate bus relations for the HCA. */\r
IoInvalidateDeviceRelations(\r
p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
\r
+ /* free PNP context */\r
+ cl_free( p_ctx );\r
+ p_pnp_rec->pnp_rec.context = NULL;\r
+\r
hca_deref:\r
deref_al_obj( &p_ext->h_ca->obj );\r
- p_ext->h_ca = NULL;\r
cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
{\r
bus_iou_ext_t *p_ext;\r
POWER_STATE po_state;\r
+ iou_mgr_t *gp_iou_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
+ gp_iou_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_iou_mgr;\r
\r
/* Remove this PDO from its list. */\r
cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
typedef struct _iou_mgr\r
{\r
cl_obj_t obj;\r
- ib_pnp_handle_t h_pnp; /* Handle for iou PnP events */\r
\r
/* Mutex protects both pointer vectors. */\r
cl_mutex_t pdo_mutex;\r
} iou_mgr_t;\r
\r
\r
+struct _bus_filter_instance;\r
+\r
ib_api_status_t\r
create_iou_mgr(\r
- OUT iou_mgr_t** const pp_iou_mgr );\r
+ IN struct _bus_filter_instance* p_bfi,\r
+ OUT iou_mgr_t** const pp_iou_mgr );\r
\r
\r
NTSTATUS\r
* Implemenation of all PnP functionality for FDO (power policy owners).\r
*/\r
\r
-\r
#include "bus_pnp.h"\r
#include "al_ca.h"\r
#include "al_init.h"\r
#include "iba/ib_ci_ifc.h"\r
\r
\r
+/* Interface names are generated by IoRegisterDeviceInterface. */\r
+static UNICODE_STRING al_ifc_name;\r
+static UNICODE_STRING ci_ifc_name;\r
+\r
+FAST_MUTEX ControlMutex;\r
+ULONG bfi_InstanceCount;\r
+bus_filter_t bus_filters[MAX_BUS_FILTERS];\r
+\r
+extern ib_al_handle_t gh_al; // NULL if AL needs init.\r
+\r
+\r
static NTSTATUS\r
fdo_start(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
OUT cl_irp_action_t* const p_action );\r
\r
static NTSTATUS\r
-fdo_query_remove_relations(\r
+fdo_query_bus_relations(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
IN IRP* const p_irp, \r
OUT cl_irp_action_t* const p_action );\r
#pragma alloc_text (PAGE, fdo_query_remove)\r
#pragma alloc_text (PAGE, fdo_release_resources)\r
#pragma alloc_text (PAGE, fdo_query_capabilities)\r
-#pragma alloc_text (PAGE, fdo_query_remove_relations)\r
+#pragma alloc_text (PAGE, fdo_query_bus_relations)\r
#pragma alloc_text (PAGE, __query_al_ifc)\r
#pragma alloc_text (PAGE, __query_ci_ifc)\r
#pragma alloc_text (PAGE, __get_relations)\r
cl_irp_skip,\r
cl_irp_skip,\r
cl_do_sync_pnp,\r
+ fdo_query_bus_relations /*cl_irp_ignore*/ ,\r
cl_irp_ignore,\r
- cl_irp_ignore,\r
- fdo_query_remove_relations,\r
+ cl_irp_skip /*fdo_query_remove_relations now _bus_relations */ ,\r
cl_irp_ignore,\r
cl_irp_ignore,\r
cl_irp_ignore,\r
{\r
NTSTATUS status;\r
DEVICE_OBJECT *p_dev_obj, *p_next_do;\r
- bus_fdo_ext_t *p_ext;\r
+ bus_fdo_ext_t *p_ext=NULL;\r
UNICODE_STRING dev_name, dos_name;\r
+ bus_filter_t *p_bfi;\r
+ int ic;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- if( bus_globals.p_bus_ext )\r
+ /* allocate a Bus Filter Instance */\r
+ p_bfi = alloc_bfi( p_driver_obj, &ic );\r
+ if ( !p_bfi )\r
{\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
- ("Bus root already exists. Only one bus root allowed.\n") );\r
- return STATUS_NO_SUCH_DEVICE;\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s() Err - Exceeded MAX_BUS_FILTERS(%d)\n",MAX_BUS_FILTERS));\r
+ return STATUS_UNSUCCESSFUL;\r
}\r
\r
- RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME );\r
- RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
-\r
/* Create the FDO device object to attach to the stack. */\r
- status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
- &dev_name, FILE_DEVICE_BUS_EXTENDER,\r
- FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
- if( !NT_SUCCESS(status) )\r
+\r
+ /* if 1st Bus Filter Instance, then create device names for user ioctl */\r
+ if ( ic == 1 )\r
{\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
- ("Failed to create bus root FDO device.\n") );\r
- return status;\r
+ RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME );\r
+ RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
+\r
+ status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
+ &dev_name, FILE_DEVICE_BUS_EXTENDER,\r
+ FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
+ if( !NT_SUCCESS(status) )\r
+ {\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
+ ("Failed to create ControlDeviceObject, status %x.\n",status) );\r
+ goto bail;\r
+ }\r
+ IoDeleteSymbolicLink( &dos_name );\r
+ status = IoCreateSymbolicLink( &dos_name, &dev_name );\r
+ if( !NT_SUCCESS(status) )\r
+ {\r
+ IoDeleteDevice( p_dev_obj );\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
+ ("Failed to create symlink for dos name.\n") );\r
+ goto bail;\r
+ }\r
+ }\r
+ else {\r
+ status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
+ NULL, FILE_DEVICE_BUS_EXTENDER,\r
+ FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
}\r
\r
- IoDeleteSymbolicLink( &dos_name );\r
- status = IoCreateSymbolicLink( &dos_name, &dev_name );\r
if( !NT_SUCCESS(status) )\r
{\r
- IoDeleteDevice( p_dev_obj );\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
- ("Failed to create symlink for dos name.\n") );\r
- return status;\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
+ ("Failed to create bus root FDO device.\n") );\r
+ goto bail;\r
}\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
+ p_ext->n_al_ifc_ref = 0;\r
+ p_ext->n_ci_ifc_ref = 0;\r
\r
p_next_do = IoAttachDeviceToDeviceStack( p_dev_obj, p_pdo );\r
if( !p_next_do )\r
{\r
IoDeleteDevice( p_dev_obj );\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, ("IoAttachToDeviceStack failed.\n") );\r
- return STATUS_NO_SUCH_DEVICE;\r
+ status = STATUS_NO_SUCH_DEVICE;\r
+ goto bail;\r
}\r
\r
cl_init_pnp_po_ext( p_dev_obj, p_next_do, p_pdo, bus_globals.dbg_lvl,\r
- &vfptr_fdo_pnp, NULL );\r
+ &vfptr_fdo_pnp, NULL );\r
+\r
+ p_bfi->p_bus_ext = p_ext;\r
+ p_ext->bus_filter = p_bfi;\r
+\r
+ /*\r
+ * if not 1st Bus Filter Instance, then finished...\r
+ */\r
+ if ( ic > 1 )\r
+ goto adxit;\r
\r
/* Register the upper interface (the one used by clients). */\r
- status = IoRegisterDeviceInterface( p_pdo, \r
- &GUID_IB_AL_INTERFACE, NULL, &p_ext->al_ifc_name );\r
+ status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_AL_INTERFACE, NULL,\r
+ &al_ifc_name );\r
if( !NT_SUCCESS( status ) )\r
{\r
IoDetachDevice( p_ext->cl_ext.p_next_do );\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
("IoRegisterDeviceInterface for upper interface returned %08x\n",\r
status) );\r
- return STATUS_NO_SUCH_DEVICE;\r
+ status = STATUS_NO_SUCH_DEVICE;\r
+ goto bail;\r
}\r
\r
- /* Register the lower interface (the one used by HCA VPDs). */\r
- status = IoRegisterDeviceInterface( p_pdo, \r
- &GUID_IB_CI_INTERFACE, NULL, &p_ext->ci_ifc_name );\r
+ /* Register the lower (CI) interface (the one used by HCA VPDs). */\r
+ status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_CI_INTERFACE, NULL,\r
+ &ci_ifc_name );\r
if( !NT_SUCCESS( status ) )\r
{\r
- RtlFreeUnicodeString( &p_ext->al_ifc_name );\r
IoDetachDevice( p_ext->cl_ext.p_next_do );\r
IoDeleteDevice( p_dev_obj );\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
("IoRegisterDeviceInterface for lower interface returned %08x\n",\r
status) );\r
- return STATUS_NO_SUCH_DEVICE;\r
+ status = STATUS_NO_SUCH_DEVICE;\r
+ goto bail;\r
}\r
\r
- bus_globals.p_bus_ext = p_ext;\r
+adxit:\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status 0\n",\r
+ __FUNCTION__, p_bfi->whoami) );\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
return STATUS_SUCCESS;\r
+\r
+bail:\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status %d\n",\r
+ __FUNCTION__,p_bfi->whoami,status) );\r
+ ic = free_bfi(p_bfi);\r
+ /* if last Bus filter, then cleanup */\r
+ if ( ic == 0 )\r
+ {\r
+ IoDeleteSymbolicLink( &dos_name );\r
+ RtlFreeUnicodeString( &al_ifc_name );\r
+ }\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return status;\r
}\r
\r
\r
NTSTATUS status;\r
bus_fdo_ext_t *p_ext;\r
ib_api_status_t ib_status;\r
+ bus_filter_t *p_bfi;\r
+ boolean_t AL_init_here = FALSE;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
+ p_bfi = p_ext->bus_filter;\r
\r
/* Handled on the way up. */\r
status = cl_do_sync_pnp( p_dev_obj, p_irp, p_action );\r
return status;\r
}\r
\r
- /* Initialize AL */\r
- ib_status = al_initialize();\r
- if( ib_status != IB_SUCCESS )\r
- {\r
- al_cleanup();\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n",\r
- ib_get_err_str(ib_status)) );\r
- return STATUS_UNSUCCESSFUL;\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+ if ( !gh_al ) {\r
+ /* Initialize AL */\r
+ ib_status = al_initialize();\r
+ if( ib_status != IB_SUCCESS )\r
+ {\r
+ al_cleanup();\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n",\r
+ ib_get_err_str(ib_status)) );\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+ AL_init_here = TRUE;\r
}\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
\r
/* Initialize the port manager. */\r
- ib_status = create_port_mgr( &p_ext->p_port_mgr );\r
+ ib_status = create_port_mgr( p_ext->bus_filter, &p_ext->p_port_mgr );\r
if( ib_status != IB_SUCCESS )\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_port_mgr returned %s.\n",\r
}\r
\r
/* Initialize the IOU manager. */\r
- ib_status = create_iou_mgr( &p_ext->p_iou_mgr );\r
+ ib_status = create_iou_mgr( p_ext->bus_filter, &p_ext->p_iou_mgr );\r
if( ib_status != IB_SUCCESS )\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_iou_mgr returned %s.\n",\r
return STATUS_UNSUCCESSFUL;\r
}\r
\r
- status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, TRUE );\r
- ASSERT( NT_SUCCESS( status ) );\r
+ if ( AL_init_here ) {\r
+ status = IoSetDeviceInterfaceState( &al_ifc_name, TRUE );\r
+ ASSERT( NT_SUCCESS( status ) );\r
\r
- status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, TRUE );\r
- ASSERT( NT_SUCCESS( status ) );\r
+ status = IoSetDeviceInterfaceState( &ci_ifc_name, TRUE );\r
+ ASSERT( NT_SUCCESS( status ) );\r
+ }\r
\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s() %s exit %x\n",__FUNCTION__,p_bfi->whoami,status));\r
BUS_EXIT( BUS_DBG_PNP );\r
+\r
return status;\r
}\r
\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s() IRP_MN_QUERY_REMOVE_DEVICE %s @ %p refs CI %d AL %d\n", \r
+ __FUNCTION__, p_ext->cl_ext.vfptr_pnp_po->identity, p_ext,\r
+ p_ext->n_ci_ifc_ref,p_ext->n_al_ifc_ref ) ); // XXX\r
+\r
if( p_ext->n_ci_ifc_ref )\r
{\r
/*\r
{\r
bus_fdo_ext_t *p_ext;\r
NTSTATUS status;\r
+ bus_filter_t *p_bfi;\r
+ int ic;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
+ ic = get_bfi_count();\r
\r
//TODO: Fail outstanding I/O operations.\r
\r
+ if (p_ext->p_port_mgr)\r
+ cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
+\r
+ if (p_ext->p_iou_mgr)\r
+ cl_obj_destroy( &p_ext->p_iou_mgr->obj );\r
+\r
+ p_bfi = p_ext->bus_filter;\r
+ CL_ASSERT( p_bfi );\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() Releasing BusFilter %s\n",\r
+ __FUNCTION__, p_bfi->whoami ));\r
+ if (p_bfi) {\r
+ p_ext->bus_filter = NULL;\r
+ p_bfi->p_bus_ext = NULL;\r
+ }\r
+\r
+ ic = free_bfi( p_bfi );\r
+\r
+ /* if not last Buf Filter Instance, then exit, otherwise cleanup/shutdown */\r
+ if ( ic > 0 ) {\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() %d remaining BusFilters\n",\r
+ __FUNCTION__, ic ));\r
+ return;\r
+ }\r
+\r
/* Disable any exported interfaces. */\r
- status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, FALSE );\r
+ status = IoSetDeviceInterfaceState( &al_ifc_name, FALSE );\r
ASSERT( NT_SUCCESS( status ) );\r
- status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, FALSE );\r
+ status = IoSetDeviceInterfaceState( &ci_ifc_name, FALSE );\r
ASSERT( NT_SUCCESS( status ) );\r
\r
/* Release the memory allocated for the interface symbolic names. */\r
- RtlFreeUnicodeString( &p_ext->ci_ifc_name );\r
- RtlFreeUnicodeString( &p_ext->al_ifc_name );\r
-\r
- cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
- cl_obj_destroy( &p_ext->p_iou_mgr->obj );\r
+ RtlFreeUnicodeString( &ci_ifc_name );\r
+ RtlFreeUnicodeString( &al_ifc_name );\r
\r
al_cleanup();\r
\r
- bus_globals.p_bus_ext = NULL;\r
-\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
}\r
\r
\r
+#if 0 // XXX\r
+\r
static NTSTATUS\r
-fdo_query_remove_relations(\r
+fdo_query_removal_relations(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
IN IRP* const p_irp, \r
OUT cl_irp_action_t* const p_action )\r
{\r
NTSTATUS status;\r
+ UNUSED_PARAM( p_dev_obj );\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- UNUSED_PARAM( p_dev_obj );\r
-\r
status = port_mgr_get_bus_relations( 0, p_irp );\r
if( status == STATUS_SUCCESS || \r
status == STATUS_NO_SUCH_DEVICE )\r
BUS_EXIT( BUS_DBG_PNP );\r
return status;\r
}\r
+#endif\r
+\r
+\r
+static NTSTATUS\r
+fdo_query_bus_relations(\r
+ IN DEVICE_OBJECT* const p_dev_obj,\r
+ IN IRP* const p_irp, \r
+ OUT cl_irp_action_t* const p_action )\r
+{\r
+ NTSTATUS status;\r
+ bus_fdo_ext_t *p_ext;\r
+ bus_filter_t *p_bfi;\r
+\r
+ BUS_ENTER( BUS_DBG_PNP );\r
+\r
+ p_ext = p_dev_obj->DeviceExtension;\r
+ CL_ASSERT( p_ext->bus_filter );\r
+ p_bfi = p_ext->bus_filter;\r
+ CL_ASSERT( p_bfi->magic == BFI_MAGIC );\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s(%s) ca_guid %I64x\n",\r
+ __FUNCTION__,p_bfi->whoami, p_bfi->ca_guid) );\r
+\r
+ if ( p_bfi->ca_guid == 0ULL )\r
+ {\r
+ /* HCA not yet bound to a BFI slot (no PNP ADD event seen), no bus\r
+ * relations yet.\r
+ */\r
+ status = STATUS_SUCCESS;\r
+ }\r
+ else\r
+ {\r
+ status = port_mgr_get_bus_relations( p_bfi->ca_guid, p_irp );\r
+ if( status == STATUS_SUCCESS || \r
+ status == STATUS_NO_SUCH_DEVICE )\r
+ {\r
+ status = iou_mgr_get_bus_relations( p_bfi->ca_guid, p_irp );\r
+ }\r
+ if( status == STATUS_NO_SUCH_DEVICE )\r
+ status = STATUS_SUCCESS;\r
+ }\r
+\r
+ switch( status )\r
+ {\r
+ case STATUS_NO_SUCH_DEVICE:\r
+ *p_action = IrpSkip;\r
+ status = STATUS_SUCCESS;\r
+ break;\r
+\r
+ case STATUS_SUCCESS:\r
+ *p_action = IrpPassDown;\r
+ break;\r
+\r
+ default:\r
+ *p_action = IrpComplete;\r
+ break;\r
+ }\r
+\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return status;\r
+}\r
\r
\r
void\r
cl_atomic_inc( &p_ext->n_al_ifc_ref );\r
ObReferenceObject( p_dev_obj );\r
\r
+ BUS_PRINT( BUS_DBG_PNP, (" %p->n_al_ifc_ref %d\n",\r
+ p_ext,p_ext->n_al_ifc_ref )); // XXX\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
cl_atomic_dec( &p_ext->n_al_ifc_ref );\r
ObDereferenceObject( p_dev_obj );\r
\r
+ BUS_PRINT( BUS_DBG_PNP, (" %p->n_al_ifc_ref %d\n",\r
+ p_ext,p_ext->n_al_ifc_ref )); // XXX\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
cl_atomic_inc( &p_ext->n_ci_ifc_ref );\r
ObReferenceObject( p_dev_obj );\r
\r
+ BUS_PRINT( BUS_DBG_PNP, (" %p->n_ci_ifc_ref %d\n",\r
+ p_ext,p_ext->n_ci_ifc_ref )); // XXX\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
cl_atomic_dec( &p_ext->n_ci_ifc_ref );\r
ObDereferenceObject( p_dev_obj );\r
\r
+ BUS_PRINT( BUS_DBG_PNP, (" %p->n_ci_ifc_ref %d\n",\r
+ p_ext,p_ext->n_ci_ifc_ref )); // XXX\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
-#pragma warning( push, 3 )\r
PAGED_CODE();\r
-#pragma warning( pop )\r
\r
p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
\r
BUS_TRACE( BUS_DBG_POWER, \r
("SET_POWER for FDO %p (ext %p): type %s, state %d, action %d \n",\r
p_dev_obj, p_ext,\r
- (p_io_stack->Parameters.Power.Type) ? "DevicePowerState" : "SystemPowerState",\r
+ (p_io_stack->Parameters.Power.Type)\r
+ ? "DevicePowerState" : "SystemPowerState",\r
p_io_stack->Parameters.Power.State.DeviceState, \r
p_io_stack->Parameters.Power.ShutdownType ));\r
\r
* the PDO will get cleaned up.\r
*/\r
p_pdo_ext->b_reported_missing = TRUE;\r
- BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, present %d, missing %d .\n",\r
- p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
- p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing ) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, "\r
+ "present %d, missing %d .\n",\r
+ p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present,\r
+ p_pdo_ext->b_reported_missing ) );\r
continue;\r
}\r
\r
if( ca_guid && p_pdo_ext->ca_guid != ca_guid )\r
continue;\r
\r
- BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p.\n", \r
+ BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p\n", \r
p_pdo_ext->cl_ext.p_self_do, p_pdo_ext->cl_ext.p_pdo, p_pdo_ext ));\r
\r
p_rel->Objects[p_rel->Count] = p_pdo_ext->cl_ext.p_pdo;\r
BUS_EXIT( BUS_DBG_PNP );\r
return STATUS_SUCCESS;\r
}\r
+\r
+\r
+/*\r
+ * find a bus filter instance (p_bfi) given an *cl_obj: port_mgr or iou_mgr. \r
+ */\r
+\r
+bus_filter_t *\r
+get_bfi_by_obj(IN int obj_type, IN cl_obj_t *p_obj )\r
+{\r
+ bus_filter_t *p_bfi;\r
+ bus_filter_t *matched=NULL;\r
+\r
+ CL_ASSERT((obj_type == BFI_PORT_MGR_OBJ) || (obj_type == BFI_IOU_MGR_OBJ));\r
+\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+\r
+ if ( !p_bfi->p_bus_ext )\r
+ continue;\r
+\r
+ if ( obj_type == BFI_PORT_MGR_OBJ ) {\r
+ if ( p_obj == p_bfi->p_port_mgr_obj ) {\r
+ matched = p_bfi;\r
+ break;\r
+ }\r
+ }\r
+ else {\r
+ if ( p_obj == p_bfi->p_iou_mgr_obj ) {\r
+ matched = p_bfi;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s() cl_obj %p type %s_MGR_OBJ --> bfi[%d] %p\n",\r
+ __FUNCTION__,p_obj,\r
+ (obj_type == BFI_PORT_MGR_OBJ ? "PORT": "IOU"),\r
+ (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+ return matched;\r
+}\r
+\r
+/*\r
+ * find a bus filter instance given an HCA guid.\r
+ */\r
+\r
+bus_filter_t *\r
+get_bfi_by_ca_guid( IN net64_t ca_guid )\r
+{\r
+ bus_filter_t *p_bfi;\r
+ bus_filter_t *matched=NULL;\r
+\r
+ if ( ca_guid == 0ULL )\r
+ {\r
+ matched = bus_filters;\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid %I64x -> bfi[0] %p\n",\r
+ __FUNCTION__, ca_guid, matched) );\r
+ CL_ASSERT( ca_guid ); // XXX\r
+ return matched;\r
+ }\r
+\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+ {\r
+ if ( !p_bfi->p_bus_ext )\r
+ continue;\r
+\r
+ if ( ca_guid == p_bfi->ca_guid )\r
+ {\r
+ matched = p_bfi;\r
+ break;\r
+ }\r
+ }\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s() guid 0x%I64x -> bfi[%d] %p\n",\r
+ __FUNCTION__, ca_guid,\r
+ (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+ return matched;\r
+}\r
+\r
+\r
+/*\r
+ * find/bind the specified ca_guid to a bus filter instance.\r
+ * Called from PORT_ADD or IOU_ADD pnp callback routines with the ca_guid from\r
+ * the pnp event record.\r
+ * Assumption is a BFI slot has been allocated in add_device() although the\r
+ * ca_guid was not known at that time; hence !ca_bound. When PNP generates an\r
+ * 'ADD' event, the port_mgr/iou_mgr pnp callback routine calls here to match\r
+ * the input ca_guid which caused the PNP event to the BFI instance by ca_guid.\r
+ * In the 1st call after add_device() the BFI slot is allocated but not yet \r
+ * bound to a CA guid. If the input ca_guid is not matched, then the 1st\r
+ * allocated but not bound BFI slot is then 'bound' by setting\r
+ * bfi->ca_guid = input ca_guid.\r
+ */\r
+\r
+bus_filter_t *\r
+get_set_bfi_by_ca_guid( IN net64_t ca_guid )\r
+{\r
+ bus_filter_t *p_bfi;\r
+ bus_filter_t *matched=NULL;\r
+ boolean_t ca_bound = FALSE;\r
+\r
+ if ( ca_guid == 0ULL )\r
+ {\r
+ matched = bus_filters;\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid 0x%I64x -> bfi[0] %p\n",\r
+ __FUNCTION__, ca_guid, matched) );\r
+ CL_ASSERT( ca_guid ); // XXX\r
+ return matched;\r
+ }\r
+\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+ {\r
+ if ( !p_bfi->p_bus_ext )\r
+ continue;\r
+\r
+ if ( ca_guid == p_bfi->ca_guid )\r
+ {\r
+ matched = p_bfi;\r
+ break;\r
+ }\r
+ }\r
+\r
+ /*\r
+ * if no match, find an 'allocated' bfi slot which does not have a bound CA.\r
+ * Bound == ca_guid != 0ULL.\r
+ */\r
+ if ( !matched )\r
+ {\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+ {\r
+ if ( !p_bfi->p_bus_ext )\r
+ continue; // not allocated.\r
+\r
+ if ( p_bfi->ca_guid == 0ULL )\r
+ {\r
+ ca_bound = TRUE;\r
+ p_bfi->ca_guid = ca_guid; // bind CA & this BFI slot; RTU.\r
+ matched = p_bfi;\r
+ break;\r
+ }\r
+ }\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+ }\r
+\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s()%sguid 0x%I64x @ bfi[%d] %p \n",\r
+ __FUNCTION__, (ca_bound ? "SET ":" "), ca_guid,\r
+ (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+ return matched;\r
+}\r
+\r
+\r
+bus_filter_t *\r
+alloc_bfi( IN DRIVER_OBJECT *p_driver_obj, OUT int *p_instance_count )\r
+{\r
+ bus_filter_t *p_bfi;\r
+ bus_filter_t *matched=NULL;\r
+\r
+ // Using unsafe function so that the IRQL remains at PASSIVE_LEVEL.\r
+ // IoCreateDeviceSecure & IoCreateSymbolicLink must be called at\r
+ // PASSIVE_LEVEL.\r
+\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+ // find 1st unused bfi slot.\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+ {\r
+ if ( !p_bfi->p_bus_ext )\r
+ {\r
+ /* temp setting until 'real' p_bus_ext is alloc; see bus_add_device.\r
+ * If p_bus_ext is ! 0, then bfi slot is allocated, although it\r
+ * may not yet have a bound CA guid; set set_get_\r
+ */\r
+ p_bfi->p_bus_ext = (bus_fdo_ext_t*)p_driver_obj;\r
+ matched = p_bfi;\r
+ *p_instance_count = ++bfi_InstanceCount; // record in-use\r
+ break;\r
+ }\r
+ }\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+#if DBG\r
+ RtlStringCbPrintfA ( p_bfi->whoami,\r
+ sizeof(p_bfi->whoami),\r
+ "bfi-%d",\r
+ (bfi_InstanceCount - 1) );\r
+\r
+ p_bfi->magic = BFI_MAGIC; // XXX debug\r
+#endif\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() %s %p\n",\r
+ __FUNCTION__, (matched ? matched->whoami:"Nobody"), matched) );\r
+\r
+ return matched;\r
+}\r
+\r
+\r
+int\r
+free_bfi( IN bus_filter_t *p_bfi )\r
+{\r
+ int remaining;\r
+\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+ p_bfi->p_bus_ext = NULL;\r
+ p_bfi->ca_guid = 0ULL;\r
+ remaining = --bfi_InstanceCount; // one less bfi in-use\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+ return remaining;\r
+}\r
+\r
+int\r
+get_bfi_count( void )\r
+{\r
+ int ic;\r
+\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+ ic = bfi_InstanceCount;\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+ return ic;\r
+}\r
+\r
+#if DBG\r
+char *get_obj_state_str(cl_state_t state)\r
+{\r
+ switch( state ) {\r
+ case CL_UNINITIALIZED:\r
+ return "UNINITIALIZED";\r
+ case CL_INITIALIZED:\r
+ return "INITIALIZED";\r
+ case CL_DESTROYING:\r
+ return "DESTROYING";\r
+ case CL_DESTROYED:\r
+ return "DESTROYED";\r
+ default:\r
+ break;\r
+ }\r
+ return "Err - Bad obj state";\r
+}\r
+#endif\r
+\r
} bus_port_ext_t;\r
\r
\r
-port_mgr_t* gp_port_mgr = NULL;\r
+typedef struct _port_pnp_context\r
+{\r
+ bus_filter_t *p_bus_filter;\r
+ void *p_pdo_ext;\r
+ int port_num;\r
+\r
+} port_pnp_ctx_t;\r
+\r
\r
extern pkey_array_t g_pkeys;\r
\r
IN cl_obj_t* p_obj );\r
\r
ib_api_status_t\r
-bus_reg_port_pnp( void );\r
+bus_reg_port_pnp(\r
+ IN bus_filter_t* p_bfi );\r
\r
ib_api_status_t\r
port_mgr_pnp_cb(\r
*/\r
ib_api_status_t\r
create_port_mgr(\r
+ IN bus_filter_t* p_bfi,\r
OUT port_mgr_t** const pp_port_mgr )\r
{\r
ib_api_status_t status;\r
cl_status_t cl_status;\r
+ port_mgr_t *gp_port_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- CL_ASSERT( !gp_port_mgr );\r
+ CL_ASSERT( p_bfi->p_port_mgr == NULL );\r
\r
gp_port_mgr = cl_zalloc( sizeof( port_mgr_t ) );\r
if( !gp_port_mgr )\r
("Failed to allocate port manager.\n") );\r
return IB_INSUFFICIENT_MEMORY;\r
}\r
+ p_bfi->p_port_mgr = gp_port_mgr;\r
\r
/* Construct the load service. */\r
cl_obj_construct( &gp_port_mgr->obj, AL_OBJ_TYPE_LOADER );\r
+ p_bfi->p_port_mgr_obj = &gp_port_mgr->obj;\r
cl_mutex_construct( &gp_port_mgr->pdo_mutex );\r
cl_qlist_init( &gp_port_mgr->port_list );\r
\r
\r
/* Initialize the load service object. */\r
cl_status = cl_obj_init( &gp_port_mgr->obj, CL_DESTROY_SYNC,\r
- destroying_port_mgr, NULL, free_port_mgr );\r
+ destroying_port_mgr, NULL, free_port_mgr );\r
+\r
if( cl_status != CL_SUCCESS )\r
{\r
free_port_mgr( &gp_port_mgr->obj );\r
return ib_convert_cl_status( cl_status );\r
}\r
\r
- /* Register for port PnP events. */\r
- status = bus_reg_port_pnp();\r
+ /* Register for port PnP events */\r
+ status = bus_reg_port_pnp(p_bfi);\r
if( status != IB_SUCCESS )\r
{\r
- cl_obj_destroy( &gp_port_mgr->obj );\r
BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
("bus_reg_port_pnp returned %s.\n", ib_get_err_str(status)) );\r
+ free_port_mgr( &gp_port_mgr->obj );\r
return status;\r
}\r
\r
IN cl_obj_t* p_obj )\r
{\r
ib_api_status_t status;\r
+ bus_filter_t *p_bfi;\r
+ port_mgr_t *gp_port_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_obj );\r
+ p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);\r
+ if (p_bfi == NULL) {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n",\r
+ __FUNCTION__,p_obj));\r
+ return;\r
+ }\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",\r
+ __FUNCTION__,p_bfi->whoami,p_obj,gp_port_mgr,\r
+ p_bfi->p_port_mgr_obj) );\r
+\r
+ CL_ASSERT( (void*)p_bfi->p_port_mgr == (void*)p_bfi->p_port_mgr_obj );\r
CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );\r
- UNUSED_PARAM( p_obj );\r
\r
- /* Deregister for port PnP events. */\r
- if( gp_port_mgr->h_pnp )\r
- {\r
- status = ib_dereg_pnp( gp_port_mgr->h_pnp,\r
- (ib_pfn_destroy_cb_t)cl_obj_deref );\r
+ /* Deregister for port PnP events if this is the last Port manager. */\r
+ if ( get_bfi_count() == 1 && bus_globals.h_pnp_port ) {\r
+ status = ib_dereg_pnp( bus_globals.h_pnp_port, NULL );\r
+ bus_globals.h_pnp_port = NULL;\r
CL_ASSERT( status == IB_SUCCESS );\r
}\r
+ cl_obj_deref( p_bfi->p_port_mgr_obj );\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
{\r
bus_pdo_ext_t *p_ext;\r
cl_list_item_t *p_list_item;\r
+ bus_filter_t *p_bfi;\r
+ port_mgr_t *gp_port_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_obj );\r
+ p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);\r
+ if (p_bfi == NULL) {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s: unable to get p_bfi for port obj %p?\n",\r
+ __FUNCTION__,p_obj));\r
+ return;\r
+ }\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+ if ( !gp_port_mgr ) {\r
+ // if create fails & then free is called, p_bfi->p_port_mgr == NULL\r
+ return;\r
+ }\r
CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );\r
\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_obj,gp_port_mgr,\r
+ p_bfi->p_port_mgr_obj) );\r
+\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ ("%s(%s) Mark all IPoIB PDOs as no longer present\n",\r
+ __FUNCTION__, p_bfi->whoami));\r
/*\r
* Mark all IPoIB PDOs as no longer present. This will cause them\r
* to be removed when they process the IRP_MN_REMOVE_DEVICE.\r
{\r
CL_ASSERT( !p_ext->b_present );\r
p_ext->b_reported_missing = TRUE;\r
- BUS_TRACE( BUS_DBG_PNP, ("%s: PDO %p, ext %p, present %d, missing %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+ BUS_TRACE( BUS_DBG_PNP,\r
+ ("%s %s: PDO %p, ext %p, present %d, missing %d .\n",\r
+ p_bfi->whoami,\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+ p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
continue;\r
}\r
if( p_ext->h_ca )\r
/* Release the reference on the CA object. */\r
deref_al_obj( &p_ext->h_ca->obj );\r
}\r
- BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p, ext %p\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext ) );\r
+\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Deleted device %s: PDO %p, ext %p\n",\r
+ p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_ext->cl_ext.p_self_do, p_ext ) );\r
+\r
+ BUS_TRACE( BUS_DBG_PNP,("%s(%s) h_ca->obj.state %s refs %d\n",\r
+ __FUNCTION__, p_bfi->whoami,\r
+ get_obj_state_str(p_ext->h_ca->obj.state),\r
+ p_ext->h_ca->obj.ref_cnt)); // XXX\r
+\r
IoDeleteDevice( p_ext->cl_ext.p_self_do );\r
}\r
\r
cl_mutex_destroy( &gp_port_mgr->pdo_mutex );\r
cl_obj_deinit( p_obj );\r
cl_free( gp_port_mgr );\r
- gp_port_mgr = NULL;\r
+\r
+ p_bfi->p_port_mgr = NULL;\r
+ p_bfi->p_port_mgr_obj = NULL;\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
}\r
\r
* Register the load service for the given PnP class events.\r
*/\r
ib_api_status_t\r
-bus_reg_port_pnp( void )\r
+bus_reg_port_pnp( IN bus_filter_t *p_bfi )\r
{\r
ib_pnp_req_t pnp_req;\r
- ib_api_status_t status;\r
+ ib_api_status_t status = IB_SUCCESS;\r
\r
- cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
- pnp_req.pnp_class = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;\r
- pnp_req.pnp_context = gp_port_mgr;\r
- pnp_req.pfn_pnp_cb = port_mgr_pnp_cb;\r
+ /* only need to register for PNP once */\r
+ ExAcquireFastMutexUnsafe(&ControlMutex);\r
+ if ( !bus_globals.h_pnp_port ) {\r
+ cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
+ pnp_req.pnp_class = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;\r
+ pnp_req.pnp_context = NULL;\r
+ pnp_req.pfn_pnp_cb = port_mgr_pnp_cb;\r
\r
- status = ib_reg_pnp( gh_al, &pnp_req, &gp_port_mgr->h_pnp );\r
+ status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_port );\r
+ }\r
+ ExReleaseFastMutexUnsafe(&ControlMutex);\r
\r
- if( status == IB_SUCCESS )\r
- {\r
- /* Reference the load service on behalf of the ib_reg_pnp call. */\r
- cl_obj_ref( &gp_port_mgr->obj );\r
+ if( status == IB_SUCCESS ) {\r
+ /* Reference this bus filter's port load service */\r
+ cl_obj_ref( &p_bfi->p_port_mgr->obj );\r
}\r
\r
return status;\r
port_mgr_pnp_cb(\r
IN ib_pnp_rec_t* p_pnp_rec )\r
{\r
- ib_api_status_t status;\r
+ ib_api_status_t status=IB_SUCCESS;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
CL_ASSERT( p_pnp_rec );\r
- CL_ASSERT( gp_port_mgr == p_pnp_rec->pnp_context );\r
\r
switch( p_pnp_rec->pnp_event )\r
{\r
\r
case IB_PNP_PORT_REMOVE:\r
port_mgr_port_remove( (ib_pnp_port_rec_t*)p_pnp_rec );\r
+ break;\r
\r
default:\r
- status = IB_SUCCESS;\r
+ XBUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n",\r
+ __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) ));\r
break;\r
}\r
BUS_EXIT( BUS_DBG_PNP );\r
+\r
return status;\r
}\r
\r
IN IRP* const p_irp )\r
{\r
NTSTATUS status;\r
+ bus_filter_t *p_bfi;\r
+ port_mgr_t *gp_port_mgr;\r
+ DEVICE_RELATIONS *p_rel;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+\r
+ /* special case guid == 0 - walk all bus filter instances */\r
+ if ( ca_guid == 0ULL ) {\r
+ for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+ if ( !gp_port_mgr )\r
+ continue;\r
+ cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
+ status = bus_get_relations( &gp_port_mgr->port_list,\r
+ ca_guid,\r
+ p_irp );\r
+ cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
+ }\r
+\r
+ p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
+ if ( p_rel ) {\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n",\r
+ __FUNCTION__,p_rel->Count));\r
+ }\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return STATUS_SUCCESS;\r
+ }\r
+\r
+ p_bfi = get_bfi_by_ca_guid(ca_guid);\r
+ if (p_bfi == NULL) {\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s() Null *p_bfi from ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return STATUS_NO_SUCH_DEVICE;\r
+ }\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x port_mgr %p\n",\r
+ __FUNCTION__, p_bfi->whoami, ca_guid, gp_port_mgr) );\r
+ if (!gp_port_mgr)\r
+ return STATUS_NO_SUCH_DEVICE;\r
+\r
cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
status = bus_get_relations( &gp_port_mgr->port_list, ca_guid, p_irp );\r
cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
\r
static ib_api_status_t\r
__port_was_hibernated(\r
- IN ib_pnp_port_rec_t* p_pnp_rec )\r
+ IN ib_pnp_port_rec_t* p_pnp_rec,\r
+ IN bus_filter_t* p_bfi )\r
{\r
NTSTATUS status;\r
- cl_list_item_t *p_list_item;\r
+ cl_list_item_t *p_list_item;\r
bus_port_ext_t *p_port_ext;\r
bus_pdo_ext_t *p_pdo_ext = NULL;\r
size_t n_devs = 0;\r
+ port_mgr_t *gp_port_mgr = p_bfi->p_port_mgr;\r
cl_qlist_t* p_pdo_list = &gp_port_mgr->port_list;\r
\r
+ port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
+\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
break;\r
}\r
\r
- BUS_TRACE( BUS_DBG_PNP, \r
- ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
- p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, "\r
+ "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
+ p_bfi->whoami,\r
+ p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_pdo_ext->cl_ext.p_self_do, \r
p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, \r
p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) );\r
}\r
p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
if( !p_pdo_ext->h_ca )\r
{\r
- BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n",\r
- p_pnp_rec->p_ca_attr->ca_guid ) );\r
+ BUS_TRACE( BUS_DBG_ERROR,\r
+ ("%s acquire_ca failed to find CA by guid %I64x\n",\r
+ p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );\r
status = IB_INVALID_GUID;\r
}\r
else \r
{\r
p_pdo_ext->b_hibernating = FALSE;\r
- p_pnp_rec->pnp_rec.context = p_pdo_ext;\r
+\r
+ CL_ASSERT( p_ctx );\r
+ p_ctx->p_pdo_ext = p_pdo_ext; // save for port_mgr_port_remove\r
+\r
status = IB_SUCCESS;\r
p_port_ext = (bus_port_ext_t*)p_pdo_ext;\r
- BUS_TRACE( BUS_DBG_PNP, \r
- ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
- p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Found PDO for %s: PDO %p, ext %p, "\r
+ "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
+ p_bfi->whoami,\r
+ p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+ p_pdo_ext->cl_ext.p_self_do, \r
p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, \r
p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) );\r
}\r
}\r
else \r
{\r
- BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid %I64x .\n",\r
- p_pnp_rec->p_ca_attr->ca_guid ) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid %I64x .\n",\r
+ p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );\r
status = IB_NOT_FOUND;\r
}\r
\r
return status;\r
}\r
\r
+\r
+void\r
+dump_pnp_port_rec( ib_pnp_port_rec_t* pr )\r
+{\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_port_rec_t* @ %p\nib_pnp_rec_t*:\n",\r
+ __FUNCTION__,pr));\r
+\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, (" Event %s\n",\r
+ ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, (" pnp_context %p\n",pr->pnp_rec.pnp_context));\r
+ BUS_PRINT( BUS_DBG_PNP, (" context %p\n",pr->pnp_rec.context));\r
+ BUS_PRINT( BUS_DBG_PNP, (" guid %I64x\n",pr->pnp_rec.guid));\r
+ BUS_PRINT( BUS_DBG_PNP, (" ca_guid %I64x\n",pr->pnp_rec.ca_guid));\r
+\r
+ if ( !pr->p_ca_attr ) {\r
+ BUS_PRINT( BUS_DBG_PNP, (" NULL *p_ca_attr ?\n"));\r
+ }\r
+ else {\r
+ BUS_PRINT( BUS_DBG_PNP, ("*p_ca_attr\n"));\r
+ BUS_PRINT( BUS_DBG_PNP, (" ca_guid 0x%I64x\n",\r
+ pr->p_ca_attr->ca_guid ) );\r
+ }\r
+ if ( !pr->p_port_attr ) {\r
+ BUS_PRINT( BUS_DBG_PNP, (" NULL *p_port_attr?\n"));\r
+ }\r
+ else {\r
+ BUS_PRINT( BUS_DBG_PNP, ("*p_port_attr:\n"));\r
+ BUS_PRINT( BUS_DBG_PNP, (" port_guid 0x%I64x port_num %d\n",\r
+ pr->p_port_attr->port_guid,\r
+ pr->p_port_attr->port_num ));\r
+ }\r
+}\r
+\r
+void\r
+dump_pnp_iou_rec( ib_pnp_iou_rec_t* pr )\r
+{\r
+ BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_iou_rec_t* @ %p\nib_pnp_rec_t*:\n",\r
+ __FUNCTION__,pr));\r
+\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, (" Event %s\n",\r
+ ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, (" pnp_context %p\n",pr->pnp_rec.pnp_context));\r
+ BUS_PRINT( BUS_DBG_PNP, (" context %p\n",pr->pnp_rec.context));\r
+ BUS_PRINT( BUS_DBG_PNP, (" guid %I64x\n",pr->pnp_rec.guid));\r
+ BUS_PRINT( BUS_DBG_PNP, (" ca_guid %I64x\n",pr->pnp_rec.ca_guid));\r
+\r
+ BUS_PRINT( BUS_DBG_PNP, ("pnp_iou_rec_t:\n" ));\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ (" guid 0x%I64x\n ca_guid %I64x\n chassis_guid %I64x\n",\r
+ pr->guid, pr->ca_guid, pr->chassis_guid ));\r
+ BUS_PRINT( BUS_DBG_PNP,\r
+ (" slot 0x%x\n vend_id 0x%x\n dev_id 0x%x revision 0x%x\n",\r
+ pr->slot, pr->vend_id, pr->dev_id, pr->revision ));\r
+ if ( pr->desc[0] ) {\r
+ BUS_PRINT( BUS_DBG_PNP, (" Desc %s\n",pr->desc ));\r
+ }\r
+}\r
+\r
+\r
ib_api_status_t\r
port_mgr_port_add(\r
IN ib_pnp_port_rec_t* p_pnp_rec )\r
uint8_t num_pdo;\r
bus_port_ext_t *p_port_ext;\r
ib_net16_t pdo_cnt;\r
+ bus_filter_t *p_bfi;\r
+ port_mgr_t *gp_port_mgr;\r
+ port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
+\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
+ CL_ASSERT( p_pnp_rec->p_ca_attr->ca_guid );\r
+\r
+ p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->p_ca_attr->ca_guid );\r
+ if ( !p_bfi ) {\r
+ BUS_PRINT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n",\r
+ __FUNCTION__, p_pnp_rec->p_ca_attr->ca_guid ) );\r
+ return IB_ERROR;\r
+ }\r
+\r
+ /*\r
+ * Allocate a PNP context for this object. pnp_rec.context is obj unique.\r
+ */\r
+ if ( !p_ctx ) {\r
+ p_ctx = cl_zalloc( sizeof(*p_ctx) );\r
+ if( !p_ctx )\r
+ {\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s(%s) ca_guid %I64x port(%d) BAD alloc PNP context\n",\r
+ __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+ p_pnp_rec->p_port_attr->port_num));\r
+ return IB_ERROR;\r
+ }\r
+ p_ctx->p_bus_filter = p_bfi;\r
+ p_ctx->port_num = p_pnp_rec->p_port_attr->port_num;\r
+ p_pnp_rec->pnp_rec.context = p_ctx;\r
+\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s(%s) ca_guid %I64x port %d ALLOC p_ctx @ %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+ p_pnp_rec->p_port_attr->port_num,p_ctx));\r
+ }\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
if( !bus_globals.b_report_port_nic )\r
{\r
BUS_EXIT( BUS_DBG_PNP );\r
return IB_NOT_DONE;\r
}\r
\r
- /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but\r
+ /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but\r
marks with a flag. So we first try to find an existing PDO for this port,\r
- marked with this flag. If it was found, we turn off the flag and use this PDO */\r
- status = __port_was_hibernated(p_pnp_rec);\r
+ marked with this flag. If it was found, we turn off the flag and use\r
+ this PDO */\r
+ status = __port_was_hibernated( p_pnp_rec, p_bfi );\r
if( status != IB_NOT_FOUND )\r
{\r
BUS_EXIT( BUS_DBG_PNP );\r
\r
for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)\r
{\r
- /* Create the PDO for the new port device. */\r
- status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),\r
- NULL, FILE_DEVICE_CONTROLLER,\r
- FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
- FALSE, &p_pdo[num_pdo] );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
- ("IoCreateDevice returned %08x.\n", status) );\r
- return IB_ERROR;\r
- }\r
+ /* Create the PDO for the new port device. */\r
+ status = IoCreateDevice( bus_globals.p_driver_obj,\r
+ sizeof(bus_port_ext_t),\r
+ NULL, FILE_DEVICE_CONTROLLER,\r
+ FILE_DEVICE_SECURE_OPEN |\r
+ FILE_AUTOGENERATED_DEVICE_NAME,\r
+ FALSE, &p_pdo[num_pdo] );\r
+ if( !NT_SUCCESS( status ) )\r
+ {\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
+ ("IoCreateDevice returned %08x.\n", status) );\r
+ return IB_ERROR;\r
+ }\r
\r
- /* Initialize the device extension. */\r
- cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo], bus_globals.dbg_lvl,\r
- &vfptr_port_pnp, &vfptr_port_query_txt );\r
+ /* Initialize the device extension. */\r
+ cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo],\r
+ bus_globals.dbg_lvl, &vfptr_port_pnp,\r
+ &vfptr_port_query_txt );\r
\r
- /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
+ /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
\r
p_port_ext = p_pdo[num_pdo]->DeviceExtension;\r
- p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
- p_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
- p_port_ext->pdo.b_present = TRUE;\r
- p_port_ext->pdo.b_reported_missing = FALSE;\r
- p_port_ext->pdo.b_hibernating = FALSE;\r
- p_port_ext->pdo.p_po_work_item = NULL;\r
- BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",\r
- p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo], p_port_ext, p_port_ext->pdo.b_present, \r
- p_port_ext->pdo.b_reported_missing ) );\r
-\r
- /* Cache the CA GUID. */\r
- p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;\r
-\r
- /* Take a reference on the parent HCA. */\r
+ p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
+ p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
+ p_port_ext->pdo.b_present = TRUE;\r
+ p_port_ext->pdo.b_reported_missing = FALSE;\r
+ p_port_ext->pdo.b_hibernating = FALSE;\r
+ p_port_ext->pdo.p_po_work_item = NULL;\r
+ BUS_TRACE( BUS_DBG_PNP,\r
+ ("Created %s %s: PDO %p,ext %p, present %d, missing %d .\n",\r
+ p_bfi->whoami,\r
+ p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo],\r
+ p_port_ext, p_port_ext->pdo.b_present,\r
+ p_port_ext->pdo.b_reported_missing ) );\r
+\r
+ /* Cache the CA GUID. */\r
+ p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;\r
+\r
+ /* Take a reference on the parent HCA. */\r
if(num_pdo > 0)\r
{\r
p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca;\r
}\r
else\r
- p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
- if( !p_port_ext->pdo.h_ca )\r
- {\r
+ p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
+\r
+ if( !p_port_ext->pdo.h_ca )\r
+ {\r
BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo[num_pdo]));\r
IoDeleteDevice( p_pdo[num_pdo]);\r
- BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );\r
- return IB_INVALID_GUID;\r
- }\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );\r
+ return IB_INVALID_GUID;\r
+ }\r
p_port_ext->port_guid.guid = p_pnp_rec->p_port_attr->port_guid;\r
- p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;\r
+ p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;\r
p_port_ext->port_guid.pkey = IB_DEFAULT_PKEY;\r
+ p_port_ext->n_ifc_ref = 0;\r
\r
if(num_pdo > 0)\r
{\r
p_port_ext->port_guid.pkey = g_pkeys.pkey_array[num_pdo -1];\r
}\r
- /* Store the device extension in the port vector for future queries. */\r
- cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
- cl_qlist_insert_tail( &gp_port_mgr->port_list,\r
- &p_port_ext->pdo.list_item );\r
- cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
\r
- /*\r
- * Set the context of the PNP event. The context is passed in for future\r
- * events on the same port.\r
- */\r
+ /* Store the device extension in the port vector for future queries. */\r
+ cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
+ cl_qlist_insert_tail( &gp_port_mgr->port_list,\r
+ &p_port_ext->pdo.list_item );\r
+ cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
+\r
+ /*\r
+ * save the port_ext, as the context is passed in for future events on\r
+ * the same port.\r
+ */\r
if(num_pdo == 0)\r
- p_pnp_rec->pnp_rec.context = p_port_ext;\r
+ p_ctx->p_pdo_ext = p_port_ext;\r
}\r
pkeys_enumerated = TRUE;\r
\r
IoInvalidateDeviceRelations(\r
p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
\r
+#if 0 // XXX\r
/* Invalidate removal relations for the bus driver. */\r
- IoInvalidateDeviceRelations(\r
- bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+ IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo,\r
+ RemovalRelations );\r
+#endif\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
return IB_SUCCESS;\r
bus_port_ext_t *p_port_ext, *pkey_port_ext;\r
DEVICE_OBJECT *p_pdo[MAX_NUM_PKEY];\r
bus_pdo_ext_t *p_pdo_ext = NULL;\r
- cl_qlist_t* p_pdo_list = &gp_port_mgr->port_list;\r
+ cl_qlist_t* p_pdo_list;\r
+ bus_filter_t *p_bfi = &bus_filters[0];// pass in ca_guid? | all CA's?\r
+ port_mgr_t *gp_port_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
+ gp_port_mgr = p_bfi->p_port_mgr; \r
+ p_pdo_list = &gp_port_mgr->port_list;\r
p_port_ext = NULL;\r
cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
\r
if (!p_port_ext)\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
- ("No existed pdo found.\n") );\r
+ ("No existing pdo found.\n") );\r
return CL_ERROR;\r
}\r
\r
for (cnt = 0; cnt < pkeys->pkey_num; cnt++)\r
{\r
-\r
/* Create the PDO for the new port device. */\r
- status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),\r
- NULL, FILE_DEVICE_CONTROLLER,\r
- FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
- FALSE, &p_pdo[cnt] );\r
+ status = IoCreateDevice( bus_globals.p_driver_obj,\r
+ sizeof(bus_port_ext_t),\r
+ NULL, FILE_DEVICE_CONTROLLER,\r
+ FILE_DEVICE_SECURE_OPEN\r
+ | FILE_AUTOGENERATED_DEVICE_NAME,\r
+ FALSE, &p_pdo[cnt] );\r
if( !NT_SUCCESS( status ) )\r
{\r
BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
\r
/* Initialize the device extension. */\r
cl_init_pnp_po_ext( p_pdo[cnt], NULL, p_pdo[cnt], bus_globals.dbg_lvl,\r
- &vfptr_port_pnp, &vfptr_port_query_txt );\r
+ &vfptr_port_pnp, &vfptr_port_query_txt );\r
\r
/* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
p_pdo[cnt]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
\r
pkey_port_ext = p_pdo[cnt]->DeviceExtension;\r
pkey_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
- pkey_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
+ pkey_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
pkey_port_ext->pdo.b_present = TRUE;\r
pkey_port_ext->pdo.b_reported_missing = FALSE;\r
pkey_port_ext->pdo.b_hibernating = FALSE;\r
pkey_port_ext->pdo.p_po_work_item = NULL;\r
- BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",\r
- pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], pkey_port_ext, pkey_port_ext->pdo.b_present, \r
+ BUS_TRACE( BUS_DBG_PNP,\r
+ ("Created device for %s: PDO %p,ext %p, present %d, missing %d\n",\r
+ pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt],\r
+ pkey_port_ext, pkey_port_ext->pdo.b_present, \r
pkey_port_ext->pdo.b_reported_missing ) );\r
\r
/* Cache the CA GUID. */\r
IoInvalidateDeviceRelations(\r
p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
\r
+#if 0 // XXX\r
/* Invalidate removal relations for the bus driver. */\r
- IoInvalidateDeviceRelations(\r
- bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+ IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo,\r
+ RemovalRelations );\r
+#endif\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
return CL_SUCCESS;\r
\r
void\r
port_mgr_port_remove(\r
- IN ib_pnp_port_rec_t* p_pnp_rec )\r
+ IN ib_pnp_port_rec_t* p_pnp_rec )\r
{\r
bus_pdo_ext_t *p_ext;\r
+ port_mgr_t *gp_port_mgr;\r
+ bus_filter_t *p_bfi;\r
+ port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
- /* The PNP record's context is the port extension. */\r
- p_ext = p_pnp_rec->pnp_rec.context;\r
+ if ( !p_ctx ) {\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return;\r
+ }\r
+\r
+ CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );\r
+ p_bfi = p_ctx->p_bus_filter;\r
+ CL_ASSERT( p_bfi );\r
+\r
+ BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x port_num %d port_mgr %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid,\r
+ p_ctx->port_num, p_bfi->p_port_mgr));\r
+\r
+ /* in the process of device remove, port_mgr has been destroyed.\r
+ * cleanup allocated PNP port context; one per port.\r
+ * The issue is the PNP PORT_REMOVE event occurs after\r
+ * fdo_release_resources() completes.\r
+ */\r
+ if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_port_mgr ) {\r
+ cl_free( p_ctx );\r
+ p_pnp_rec->pnp_rec.context = NULL;\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return;\r
+ }\r
+\r
+ gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+ /* Within the PNP record's context is the port extension ptr;\r
+ * see port_was_hibernated().\r
+ */\r
+ p_ext = p_ctx->p_pdo_ext;\r
CL_ASSERT( p_ext );\r
\r
+ CL_ASSERT(p_bfi == p_ext->p_parent_ext->bus_filter);\r
+#if DBG // XXX\r
+ if (p_bfi != p_ext->p_parent_ext->bus_filter) {\r
+ BUS_PRINT(BUS_DBG_PNP,\r
+ ("%s() p_bfi(%p) != p_ext->bus_filter(%p) line %d file %s\n",\r
+ __FUNCTION__,p_bfi,p_ext->p_parent_ext->bus_filter,\r
+ __LINE__,__FILE__));\r
+ }\r
+#endif\r
+\r
/*\r
* Flag the port PDO as no longer being present. We have to wait until\r
* the PnP manager removes it to clean up. However, we do release the\r
* reference on the CA object in order to allow the removal of the HCA\r
* to proceed should it occur before the port's PDO is cleaned up.\r
*/\r
+ if ( !p_ext->h_ca )\r
+ {\r
+ BUS_TRACE( BUS_DBG_PNP, ("%s() %s NULL h_ca? p_ext %p\n",\r
+ __FUNCTION__, p_bfi->whoami, p_ext ) );\r
+ return;\r
+ }\r
+\r
cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
CL_ASSERT( p_ext->h_ca );\r
\r
if( p_ext->b_hibernating )\r
{\r
- BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, \r
- p_ext->b_reported_missing, p_ext->b_hibernating ) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, "\r
+ "present %d, missing %d, hibernating %d .\n",\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+ p_ext, p_ext->b_present, p_ext->b_reported_missing,\r
+ p_ext->b_hibernating ) );\r
goto hca_deref;\r
}\r
\r
p_ext->b_present = FALSE;\r
- BUS_TRACE( BUS_DBG_PNP, ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",\r
- p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+ p_ext->b_reported_missing = TRUE;\r
\r
+ BUS_TRACE( BUS_DBG_PNP,\r
+ ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",\r
+ p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext,\r
+ p_ext->b_present, p_ext->b_reported_missing ) );\r
+\r
+#if 0 // XXX\r
/* Invalidate removal relations for the bus driver. */\r
- IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,\r
- RemovalRelations );\r
+ IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo,\r
+ RemovalRelations );\r
+#endif\r
\r
/* Invalidate bus relations for the HCA. */\r
IoInvalidateDeviceRelations(\r
p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
\r
+ /* Free PNP context memory */\r
+ cl_free( p_ctx );\r
+ p_pnp_rec->pnp_rec.context = NULL;\r
+\r
hca_deref:\r
deref_al_obj( &p_ext->h_ca->obj );\r
- p_ext->h_ca = NULL;\r
cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
\r
BUS_EXIT( BUS_DBG_PNP );\r
/* Notify the Power Manager that the device is started. */\r
PoSetPowerState( p_dev_obj, DevicePowerState, p_ext->dev_po_state );\r
*p_action = IrpComplete;\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
+\r
return STATUS_SUCCESS;\r
}\r
\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
\r
+BUS_PRINT( BUS_DBG_PNP, ("%s() %p->n_ifc_ref %d\n",\r
+ __FUNCTION__,p_ext,p_ext->n_ifc_ref ));\r
+\r
*p_action = IrpComplete;\r
if( p_ext->n_ifc_ref )\r
{\r
{\r
bus_port_ext_t *p_ext;\r
POWER_STATE po_state;\r
+ port_mgr_t *gp_port_mgr;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ext = p_dev_obj->DeviceExtension;\r
+ gp_port_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_port_mgr;\r
\r
/* Remove this PDO from its list. */\r
cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
- BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+ BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n",\r
+ p_dev_obj, p_ext) );\r
cl_qlist_remove_item( &gp_port_mgr->port_list, &p_ext->pdo.list_item );\r
cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
po_state.DeviceState = PowerDeviceD3;\r
cl_set_pnp_state( &p_ext->pdo.cl_ext, NotStarted );\r
/* Don't delete the device. It may simply be disabled. */\r
*p_action = IrpComplete;\r
- BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device still present: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+ BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+ ("Device %s still present: PDO %p, ext %p\n",\r
+ p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_dev_obj, p_ext) );\r
return STATUS_SUCCESS;\r
}\r
\r
/* Reset the state to RemovePending. Complib set it to Deleted. */\r
cl_rollback_pnp_state( &p_ext->pdo.cl_ext );\r
*p_action = IrpComplete;\r
- BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device not reported missing yet: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+ BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+ ("Device %s not reported missing yet: PDO %p, ext %p\n",\r
+ p_ext->pdo.cl_ext.vfptr_pnp_po->identity,\r
+ p_dev_obj, p_ext) );\r
return STATUS_SUCCESS;\r
}\r
\r
p_irp->IoStatus.Status = STATUS_SUCCESS;\r
IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
\r
- BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n",\r
- p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, p_dev_obj, p_ext ) );\r
+ BUS_PRINT/*XXX TRACE*/( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n",\r
+ p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do,\r
+ p_dev_obj, p_ext ) );\r
IoDeleteDevice( p_dev_obj );\r
\r
*p_action = IrpDoNothing;\r
ipoib_ifc_data_t *p_ipoib_data;\r
bus_port_ext_t *p_ext;\r
const GUID *p_guid;\r
- \r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ipoib_data->port_guid = p_ext->port_guid;\r
p_ipoib_data->port_num = (uint8_t)p_ext->n_port;\r
\r
+ BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+ (" %p->n_ifc_ref %d\n",p_ext,p_ext->n_ifc_ref) ); //XXX\r
+\r
BUS_EXIT( BUS_DBG_PNP );\r
return STATUS_SUCCESS;\r
}\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
-#pragma warning( push, 3 )\r
PAGED_CODE();\r
-#pragma warning( pop )\r
\r
p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
\r
typedef struct _port_mgr\r
{\r
cl_obj_t obj;\r
- ib_pnp_handle_t h_pnp; /* Handle for port PnP events */\r
\r
/* Mutex protects both pointer vectors. */\r
cl_mutex_t pdo_mutex;\r
} port_mgr_t;\r
\r
\r
+struct _bus_filter_instance;\r
+\r
ib_api_status_t\r
create_port_mgr(\r
+ IN struct _bus_filter_instance *p_bfi,\r
OUT port_mgr_t** const pp_port_mgr );\r
\r
\r
--- /dev/null
+; OpenIB InfiniBand Bus/IOU Driver.\r
+; Copyright 2005 SilverStorm Technologies all Rights Reserved.\r
+; Copyright 2006 Mellanox Technologies all Rights Reserved.\r
+\r
+[Version]\r
+Signature="$Windows NT$"\r
+Class=System\r
+ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}\r
+Provider=%OPENIB%\r
+DriverVer=04/29/2008,1.1.0000.1085\r
+\r
+; ================= Device Install section =====================\r
+\r
+; 64-bit platforms also copy 32-bit user-mode binaries.\r
+[DestinationDirs]\r
+DefaultDestDir=%DIRID_DRIVERS%\r
+\r
+[SourceDisksNames.x86]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksNames.amd64]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksNames.ia64]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksFiles.x86]\r
+ibiou.sys=1\r
+\r
+[SourceDisksFiles.amd64]\r
+ibiou.sys=1\r
+\r
+[SourceDisksFiles.ia64]\r
+ibiou.sys=1\r
+\r
+[Manufacturer]\r
+%OPENIB% = GenIOU.DeviceSection,ntx86,ntamd64,ntia64\r
+%SST% = QLogicIOU.DeviceSection,ntx86,ntamd64,ntia64\r
+\r
+[GenIOU.DeviceSection]\r
+; empty since we don't support W9x/Me\r
+\r
+[GenIOU.DeviceSection.ntx86]\r
+%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU\r
+\r
+[GenIOU.DeviceSection.ntamd64]\r
+%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU\r
+\r
+[GenIOU.DeviceSection.ntia64]\r
+%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU\r
+\r
+[QLogicIOU.DeviceSection]\r
+; empty since we don't support W9x/Me\r
+\r
+[QLogicIOU.DeviceSection.ntx86]\r
+%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010\r
+%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058\r
+%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd\r
+%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de\r
+%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0\r
+%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1\r
+\r
+[QLogicIOU.DeviceSection.ntamd64]\r
+%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010\r
+%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058\r
+%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd\r
+%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de\r
+%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0\r
+%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1\r
+\r
+[QLogicIOU.DeviceSection.ntia64]\r
+%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010\r
+%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058\r
+%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd\r
+%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de\r
+%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0\r
+%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1\r
+\r
+[Iou.DDInstall.nt]\r
+CopyFiles = Iou.CopyFiles\r
+\r
+[Iou.DDInstall.nt.Services]\r
+AddService = ibiou,%SPSVCINST_ASSOCSERVICE%,Iou.ServiceInstall\r
+;AddService = ibiou,,Iou.ServiceInstall\r
+\r
+[Iou.CopyFiles]\r
+ibiou.sys\r
+\r
+;\r
+; ============= Service Install section ==============\r
+;\r
+\r
+[Iou.ServiceInstall]\r
+DisplayName = %Iou.ServiceDesc%\r
+ServiceType = %SERVICE_KERNEL_DRIVER%\r
+StartType = %SERVICE_DEMAND_START%\r
+ErrorControl = %SERVICE_ERROR_NORMAL%\r
+ServiceBinary = %12%\ibiou.sys\r
+AddReg = Iou.ParamsReg\r
+\r
+[Iou.ParamsReg]\r
+HKR,"Parameters","DebugLevel",%REG_DWORD%,2\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x00ffffff\r
+\r
+[Strings]\r
+OPENIB = "OpenFabrics Alliance"\r
+SST = "SilverStorm Technologies"\r
+VFx.DeviceDesc = "SilverStorm VFx"\r
+VEx.DeviceDesc = "SilverStorm VEx"\r
+FVIC.DeviceDesc = "SilverStorm FVIC"\r
+EVIC.DeviceDesc = "SilverStorm EVIC"\r
+BC2FC.DeviceDesc = "QLogic InfiniBand Fibre Channel Bridge Module"\r
+BC2GE.DeviceDesc = "QLogic InfiniBand Ethernet Bridge Module"\r
+\r
+Iou.DeviceDesc = "InfiniBand I/O Unit"\r
+Iou.ServiceDesc = "OpenIB InfiniBand I/O Unit Driver"\r
+DiskId = "OpenIB InfiniBand Access Layer installation disk"\r
+SPSVCINST_NULL = 0x0\r
+SPSVCINST_ASSOCSERVICE = 0x00000002\r
+SERVICE_KERNEL_DRIVER = 1\r
+SERVICE_DEMAND_START = 3\r
+SERVICE_ERROR_NORMAL = 1\r
+REG_DWORD = 0x00010001\r
+REG_DWORD_NO_CLOBBER = 0x00010003\r
+DIRID_SYSTEM = 11\r
+DIRID_DRIVERS = 12\r
+DIRID_SYSTEM_X86 = 16425\r
--- /dev/null
+[CatalogHeader]\r
+Name=mthca.cat\r
+PublicVersion=0x0000001\r
+EncodingType=0x00010001\r
+CATATTR1=0x10010001:OSAttr:2:6.0\r
+[CatalogFiles]\r
+<hash>mthca.inf=mthca.inf\r
+<hash>mthca.sys=mthca.sys\r
+<hash>mthcau.dll=mthcau.dll\r
+<hash>mthcaud.dll=mthcaud.dll\r
+<hash>mthca32.dll=mthca32.dll\r
+<hash>mthca32d.dll=mthca32d.dll\r
+<hash>ibal.dll=ibal.dll\r
+<hash>ibald.dll=ibald.dll\r
+<hash>complib.dll=complib.dll\r
+<hash>complibd.dll=complibd.dll\r
+<hash>cl32.dll=cl32.dll\r
+<hash>cl32d.dll=cl32d.dll\r
+<hash>ibal32.dll=ibal32.dll\r
+<hash>ibal32d.dll=ibal32d.dll\r
+<hash>ibbus.sys=ibbus.sys\r
+\r
--- /dev/null
+; Mellanox Technologies InfiniBand HCAs.\r
+; Copyright 2005 Mellanox Technologies all Rights Reserved.\r
+\r
+[Version]\r
+Signature="$Windows NT$"\r
+Class=InfiniBandController\r
+ClassGUID={58517E00-D3CF-40c9-A679-CEE5752F4491}\r
+Provider=%OFA%\r
+; must be synchronized with MTHCA_DEV.H\r
+DriverVer=05/19/2008,2.0.0000.1177\r
+CatalogFile=mthca.cat\r
+\r
+; ================= Destination directory section =====================\r
+\r
+[DestinationDirs]\r
+DefaultDestDir=%DIRID_DRIVERS%\r
+MTHCA.UMCopyFiles=%DIRID_SYSTEM%\r
+MTHCA.WOW64CopyFiles=%DIRID_SYSTEM_X86%\r
+Ibal.UMCopyFiles=%DIRID_SYSTEM%\r
+Ibal.WOW64CopyFiles=%DIRID_SYSTEM_X86%\r
+\r
+; ================= Class Install section =====================\r
+\r
+[ClassInstall32]\r
+AddReg=ClassAddReg\r
+\r
+[ClassAddReg]\r
+HKR,,,0,"RDMA Channel Adapters"\r
+HKR,,Icon,,-5\r
+HKR,,SilentInstall,,0\r
+HKR,,"UpperFilters",0x00010000,"ibbus" ; enable IBBUS/AL Filter driver loading.\r
+\r
+\r
+; ================= Device Install section =====================\r
+\r
+[SourceDisksNames.x86]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksNames.amd64]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksNames.ia64]\r
+1=%DiskId%,,,""\r
+\r
+[SourceDisksFiles]\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+ibal.dll=1,,\r
+complib.dll=1,,\r
+ibald.dll=1,,\r
+complibd.dll=1,,\r
+ibbus.sys=1,,\r
+\r
+[SourceDisksFiles.amd64]\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+mthca32.dll=1,,\r
+mthca32d.dll=1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
+\r
+[SourceDisksFiles.ia64]\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+mthca32.dll=1,,\r
+mthca32d.dll=1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
+\r
+[Manufacturer]\r
+%MTL% = HCA.DeviceSection,ntx86,ntamd64,ntia64\r
+\r
+[HCA.DeviceSection]\r
+; empty since we don't support W9x/Me\r
+\r
+[HCA.DeviceSection.ntx86]\r
+%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44\r
+%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45\r
+%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278\r
+%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279\r
+%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282\r
+%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C\r
+%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D\r
+%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274\r
+%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275\r
+\r
+[HCA.DeviceSection.ntamd64]\r
+%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44\r
+%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45\r
+%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278\r
+%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279\r
+%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282\r
+%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C\r
+%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D\r
+%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274\r
+%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275\r
+\r
+[HCA.DeviceSection.ntia64]\r
+%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44\r
+%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45\r
+%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278\r
+%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279\r
+%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282\r
+%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C\r
+%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D\r
+%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274\r
+%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275\r
+\r
+[MTHCA.DDInstall.ntx86]\r
+CopyFiles = MTHCA.CopyFiles\r
+CopyFiles = MTHCA.UMCopyFiles\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
+\r
+[MTHCA.DDInstall.ntamd64]\r
+CopyFiles = MTHCA.CopyFiles\r
+CopyFiles = MTHCA.UMCopyFiles\r
+CopyFiles = MTHCA.WOW64CopyFiles\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
+\r
+[MTHCA.DDInstall.ntia64]\r
+CopyFiles = MTHCA.CopyFiles\r
+CopyFiles = MTHCA.UMCopyFiles\r
+CopyFiles = MTHCA.WOW64CopyFiles\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
+\r
+\r
+; ============== Services ==============\r
+\r
+[MTHCA.DDInstall.ntx86.Services]\r
+AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
+\r
+[MTHCA.DDInstall.ntamd64.Services]\r
+AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
+\r
+[MTHCA.DDInstall.ntia64.Services]\r
+AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
+\r
+\r
+; ============= File Copy ==============\r
+\r
+[MTHCA.CopyFiles]\r
+mthca.sys\r
+\r
+[MTHCA.UMCopyFiles]\r
+mthcau.dll,,,2\r
+mthcaud.dll,,,2\r
+\r
+[MTHCA.WOW64CopyFiles]\r
+mthcau.dll,mthca32.dll,,2\r
+mthcaud.dll,mthca32d.dll,,2\r
+\r
+[Ibal.UMCopyFiles]\r
+ibal.dll,,,2\r
+ibald.dll,,,2\r
+complib.dll,,,2\r
+complibd.dll,,,2\r
+\r
+[Ibal.WOW64CopyFiles]\r
+ibal.dll,ibal32.dll,,2\r
+ibald.dll,ibal32d.dll,,2\r
+complib.dll,cl32.dll,,2\r
+complibd.dll,cl32d.dll,,2\r
+\r
+[Ibbus.CopyFiles]\r
+ibbus.sys\r
+\r
+\r
+;\r
+; ============= MTHCA Service Install section ==============\r
+;\r
+\r
+[MTHCA.ServiceInstall]\r
+DisplayName = %MTHCA.ServiceDesc%\r
+ServiceType = %SERVICE_KERNEL_DRIVER%\r
+StartType = %SERVICE_DEMAND_START%\r
+ErrorControl = %SERVICE_ERROR_NORMAL%\r
+ServiceBinary = %12%\mthca.sys\r
+LoadOrderGroup = extended base\r
+AddReg = MTHCA.ParamsReg\r
+\r
+\r
+[MTHCA.EventLog]\r
+AddReg = MTHCA.AddEventLogReg\r
+\r
+[MTHCA.AddEventLogReg]\r
+HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\mthca.sys"\r
+HKR, , TypesSupported, 0x00010001, 7\r
+\r
+[MTHCA.ParamsReg]\r
+HKR,"Parameters","DebugLevel",%REG_DWORD%,0x00000003\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x0000ffff\r
+HKR,"Parameters","SkipTavorReset",%REG_DWORD%,0\r
+HKR,"Parameters","DisableTavorResetOnFailure",%REG_DWORD%,1\r
+HKR,"Parameters","TunePci",%REG_DWORD%,0\r
+HKR,"Parameters","ProcessorAffinity",%REG_DWORD%,0\r
+HKR,"Parameters","MaxDpcTimeUs",%REG_DWORD%,10000\r
+HKR,"Parameters","ProfileQpNum",%REG_DWORD%,0\r
+HKR,"Parameters","ProfileRdOut",%REG_DWORD%,0xffffffff\r
+HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Flags",%REG_DWORD%,0xffff\r
+HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Level",%REG_DWORD%,0x3\r
+\r
+\r
+; ============= IBBUS/AL Service Install section ==============\r
+;\r
+\r
+[Ibbus.ServiceInstall]\r
+DisplayName = %Ibbus.ServiceDesc%\r
+ServiceType = %SERVICE_KERNEL_DRIVER%\r
+StartType = %SERVICE_DEMAND_START%\r
+ErrorControl = %SERVICE_ERROR_NORMAL%\r
+ServiceBinary = %12%\ibbus.sys\r
+LoadOrderGroup = PnP Filter\r
+AddReg = Ibbus.ParamsReg\r
+Dependencies = mthca\r
+\r
+[Ibbus.ParamsReg]\r
+HKR,"Parameters","IbalDebugLevel",%REG_DWORD%,2\r
+HKR,"Parameters","IbalDebugFlags",%REG_DWORD%,0x00ffffff\r
+HKR,"Parameters","SmiPollInterval",%REG_DWORD_NO_CLOBBER%,20000\r
+HKR,"Parameters","IocQueryTimeout",%REG_DWORD_NO_CLOBBER%,250\r
+HKR,"Parameters","IocQueryRetries",%REG_DWORD_NO_CLOBBER%,4\r
+HKR,"Parameters","IocPollInterval",%REG_DWORD_NO_CLOBBER%,30000\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x80000000\r
+HKR,"Parameters","ReportPortNIC",%REG_DWORD%,1\r
+\r
+\r
+; ============= Uninstall Section =============\r
+\r
+[DefaultUninstall.ntx86]\r
+DelFiles = MTHCA.CopyFiles\r
+DelFiles = MTHCA.UMCopyFiles\r
+DelReg = MTHCA.ParamsReg\r
+DelReg = MTHCA.AddEventLogReg\r
+DelReg = ClassAddReg\r
+DelFiles = Ibal.UMCopyFiles\r
+\r
+\r
+[DefaultUninstall.ntamd64]\r
+DelFiles = MTHCA.CopyFiles\r
+DelFiles = MTHCA.UMCopyFiles\r
+DelFiles = MTHCA.WOW64CopyFiles\r
+DelReg = MTHCA.ParamsReg\r
+DelReg = MTHCA.AddEventLogReg\r
+DelReg = ClassAddReg\r
+DelFiles = Ibal.UMCopyFiles\r
+DelFiles = Ibal.WOW64CopyFiles\r
+\r
+\r
+[DefaultUninstall.ntia64]\r
+DelFiles = MTHCA.CopyFiles\r
+DelFiles = MTHCA.UMCopyFiles\r
+DelFiles = MTHCA.WOW64CopyFiles\r
+DelReg = MTHCA.ParamsReg\r
+DelReg = MTHCA.AddEventLogReg\r
+DelReg = ClassAddReg\r
+DelFiles = Ibal.UMCopyFiles\r
+DelFiles = Ibal.WOW64CopyFiles\r
+\r
+\r
+[DefaultUninstall.Services]\r
+DelService = Ibbus,%SPSVCINST_STOPSERVICE%\r
+DelService = mthca,%SPSVCINST_STOPSERVICE%\r
+\r
+\r
+[Strings]\r
+IBClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}"\r
+OFA = "OpenFabrics Alliance"\r
+MTL="Mellanox Technologies Ltd."\r
+MTHCA.ServiceDesc = "Driver for Mellanox InfiniHost Devices"\r
+MT23108.DeviceDesc="InfiniHost (MT23108) - Mellanox InfiniBand HCA"\r
+MT23109.DeviceDesc="InfiniHost (MT23109) - Mellanox InfiniBand HCA (burner device)"\r
+MT25208.DeviceDesc="InfiniHost (MT25208) - Mellanox InfiniBand HCA for PCI Express"\r
+MT25209.DeviceDesc="InfiniHost (MT25209) - Mellanox InfiniBand HCA for PCI Express (burner device)"\r
+MT25218.DeviceDesc="InfiniHost III Ex (MT25218) - Mellanox InfiniBand HCA for PCI Express"\r
+MT24204.DeviceDesc="InfiniHost III Lx (MT24204) - Mellanox InfiniBand HCA for PCI Express"\r
+MT24205.DeviceDesc="InfiniHost III Lx (MT24205) - Mellanox InfiniBand HCA for PCI Express (burner device)"\r
+MT25204.DeviceDesc="InfiniHost III Lx (MT25204) - Mellanox InfiniBand HCA for PCI Express"\r
+MT25205.DeviceDesc="InfiniHost III Lx (MT25205) - Mellanox InfiniBand HCA for PCI Express (burner device)"\r
+DiskId = "Mellanox InfiniBand HCA installation disk"\r
+Ibbus.ServiceDesc = "InfiniBand Bus/Fabric/AL (Filter Driver)"\r
+SPSVCINST_NULL = 0x0\r
+SPSVCINST_ASSOCSERVICE = 0x00000002\r
+SPSVCINST_STOPSERVICE = 0x00000200\r
+SERVICE_KERNEL_DRIVER = 1\r
+SERVICE_DEMAND_START = 3\r
+SERVICE_ERROR_NORMAL = 1\r
+REG_DWORD = 0x00010001\r
+REG_DWORD_NO_CLOBBER = 0x00010003\r
+REG_MULTI_SZ_APPEND = 0x00010008\r
+DIRID_SYSTEM = 11\r
+DIRID_DRIVERS = 12\r
+DIRID_SYSTEM_X86 = 16425\r
+\r