From: stansmith Date: Sat, 2 Aug 2008 00:43:15 +0000 (+0000) Subject: [IBBUS] ibbus as a filter driver. tested for mthca, see etc\ for mthca.inf example... X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=0147004a66081b629896cf14c7b6466e3daddb8e;p=~shefty%2Frdma-win.git [IBBUS] ibbus as a filter driver. tested for mthca, see etc\ for mthca.inf example. Starting on ConnectX ASAP. git-svn-id: svn://openib.tc.cornell.edu/gen1@1453 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/branches/winverbs/core/bus/kernel/bus_driver.c b/branches/winverbs/core/bus/kernel/bus_driver.c index b39d2965..98e5a1e0 100644 --- a/branches/winverbs/core/bus/kernel/bus_driver.c +++ b/branches/winverbs/core/bus/kernel/bus_driver.c @@ -191,7 +191,8 @@ __read_machine_name( void ) * output: pkey_array * return: uint16_t number of pkey(s) found *************************************************************************************/ -static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array) +static uint16_t +__prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array) { uint16_t i, num_pKeys, cur_pkey_length; NTSTATUS status; @@ -320,6 +321,7 @@ static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t BUS_EXIT( BUS_DBG_DRV ); return num_pKeys; } + static NTSTATUS __read_registry( IN UNICODE_STRING* const p_registry_path ) @@ -440,6 +442,8 @@ __read_registry( #if DBG if( g_al_dbg_flags & AL_DBG_ERR ) g_al_dbg_flags |= CL_DBG_ERROR; + + bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP; #endif BUS_TRACE(BUS_DBG_DRV , @@ -667,7 +671,7 @@ DriverEntry( IN DRIVER_OBJECT *p_driver_obj, IN UNICODE_STRING *p_registry_path ) { - NTSTATUS status; + NTSTATUS status; BUS_ENTER( BUS_DBG_DRV ); @@ -707,6 +711,15 @@ DriverEntry( p_driver_obj->DriverUnload = bus_drv_unload; p_driver_obj->DriverExtension->AddDevice = bus_add_device; + // Mutex to synchronize multiple threads creating & deleting + // control deviceobjects. + + ExInitializeFastMutex(&ControlMutex); + bfi_InstanceCount = 0; + memset( __out_bcount(sizeof(bus_filters)) (void*)bus_filters, 0, + sizeof(bus_filters) ); + BUS_EXIT( BUS_DBG_DRV ); return STATUS_SUCCESS; } + diff --git a/branches/winverbs/core/bus/kernel/bus_driver.h b/branches/winverbs/core/bus/kernel/bus_driver.h index bee33af5..e4ff16e0 100644 --- a/branches/winverbs/core/bus/kernel/bus_driver.h +++ b/branches/winverbs/core/bus/kernel/bus_driver.h @@ -74,7 +74,12 @@ CL_TRACE_EXIT( lvl, bus_globals.dbg_lvl, msg ) #define BUS_PRINT( lvl, msg ) \ - CL_PRINT( lvl, bus_globals.dbl_lvl, msg ) + CL_PRINT( lvl, bus_globals.dbg_lvl, msg ) + +/* single character Macro elemination */ +#define XBUS_PRINT( lvl, msg ) +#define XBUS_ENTER( lvl ) +#define XBUS_EXIT( lvl ) #define BUS_DBG_ERROR CL_DBG_ERROR #define BUS_DBG_DRV (1 << 0) @@ -93,7 +98,6 @@ * in the paging, crash dump, or hibernation path. */ - /* * Device extension for the device object that serves as entry point for * the interface and IOCTL requests. @@ -112,15 +116,13 @@ typedef struct _bus_fdo_ext port_mgr_t *p_port_mgr; iou_mgr_t *p_iou_mgr; - /* Interface names are generated by IoRegisterDeviceInterface. */ - UNICODE_STRING al_ifc_name; - UNICODE_STRING ci_ifc_name; - /* Number of references on the upper interface. */ atomic32_t n_al_ifc_ref; /* Number of references on the CI interface. */ atomic32_t n_ci_ifc_ref; + struct _bus_filter_instance *bus_filter; + } bus_fdo_ext_t; @@ -174,7 +176,7 @@ typedef struct _bus_pdo_ext boolean_t b_reported_missing; /* Flag to control the behaviour of the driver during hibernation */ - uint32_t b_hibernating; + uint32_t b_hibernating; /* work item for handling Power Management request */ PIO_WORKITEM p_po_work_item; @@ -196,13 +198,62 @@ typedef struct _bus_globals /* Driver object. Used for registering of Plug and Play notifications. */ DRIVER_OBJECT *p_driver_obj; - /* Pointer to the one and only bus root. */ - bus_fdo_ext_t *p_bus_ext; + /* IBAL PNP event register handles */ + ib_pnp_handle_t h_pnp_port; + ib_pnp_handle_t h_pnp_iou; } bus_globals_t; extern bus_globals_t bus_globals; +/* + * Each instance of a bus filter on an HCA device stack (InfiniBandController) + * populates a bus_filter_t slot in bus_filters[MAX_BUS_FILTERS]; see + * bus_add_device(). Therefore MAX_BUS_FILTERS represents the MAX number of + * HCA's supported in a single system. + */ +#define MAX_BUS_FILTERS 16 +#define BFI_MAGIC 0xcafebabe + +#define BFI_PORT_MGR_OBJ 1 +#define BFI_IOU_MGR_OBJ 2 + + +typedef struct _bus_filter_instance +{ + /* Pointer to the bus filter instance FDO extention. + * if p_bus_ext is NULL, then it's an empty slot available for allocation + */ + bus_fdo_ext_t *p_bus_ext; + + /* HCA guid for which this bus filter is servicing */ + ib_net64_t ca_guid; + + /* PORT management - on a per HCA basis */ + port_mgr_t *p_port_mgr; + cl_obj_t *p_port_mgr_obj; + + /* IOU management - on a per HCA basis */ + iou_mgr_t *p_iou_mgr; + cl_obj_t *p_iou_mgr_obj; +#if DBG + ULONG magic; // initial/temp debug + char whoami[8]; +#endif + +} bus_filter_t; + +extern bus_filter_t bus_filters[MAX_BUS_FILTERS]; +extern ULONG bfi_InstanceCount; +extern FAST_MUTEX ControlMutex; // serializes InstanceCount & bus_filters + +extern bus_filter_t *alloc_bfi( IN DRIVER_OBJECT *, OUT int * ); +extern int free_bfi( IN bus_filter_t *p_bfi ); +extern int get_bfi_count( void ); +extern bus_filter_t *get_bfi_by_obj( IN int obj_type, IN cl_obj_t *p_obj ); +extern bus_filter_t *get_bfi_by_ca_guid( IN net64_t ca_guid ); +extern bus_filter_t *get_set_bfi_by_ca_guid( IN net64_t ca_guid ); +extern char *get_obj_state_str(cl_state_t state); #endif /* !defined _BUS_DRIVER_H_ */ diff --git a/branches/winverbs/core/bus/kernel/bus_iou_mgr.c b/branches/winverbs/core/bus/kernel/bus_iou_mgr.c index 277730f8..d5391740 100644 --- a/branches/winverbs/core/bus/kernel/bus_iou_mgr.c +++ b/branches/winverbs/core/bus/kernel/bus_iou_mgr.c @@ -83,7 +83,12 @@ typedef struct _bus_iou_ext } bus_iou_ext_t; -iou_mgr_t* gp_iou_mgr = NULL; +typedef struct _iou_pnp_context +{ + bus_filter_t *p_bus_filter; + void *p_pdo_ext; + +} iou_pnp_ctx_t; /* @@ -98,7 +103,8 @@ free_iou_mgr( IN cl_obj_t* p_obj ); ib_api_status_t -bus_reg_iou_pnp( void ); +bus_reg_iou_pnp( + IN bus_filter_t* p_bfi ); ib_api_status_t iou_mgr_pnp_cb( @@ -278,25 +284,29 @@ static const cl_vfptr_query_txt_t vfptr_iou_query_txt = { */ ib_api_status_t create_iou_mgr( + IN bus_filter_t* p_bfi, OUT iou_mgr_t** const pp_iou_mgr ) { ib_api_status_t status; cl_status_t cl_status; + iou_mgr_t *gp_iou_mgr; BUS_ENTER( BUS_DBG_PNP ); - CL_ASSERT( !gp_iou_mgr ); + CL_ASSERT( p_bfi->p_iou_mgr == NULL ); gp_iou_mgr = cl_zalloc( sizeof(iou_mgr_t) ); if( !gp_iou_mgr ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("Failed to allocate port manager.\n") ); + ("Failed to allocate IOU manager.\n") ); return IB_INSUFFICIENT_MEMORY; } + p_bfi->p_iou_mgr = gp_iou_mgr; /* Construct the load service. */ cl_obj_construct( &gp_iou_mgr->obj, AL_OBJ_TYPE_LOADER ); + p_bfi->p_iou_mgr_obj = &p_bfi->p_iou_mgr->obj; // save for destroy & free cl_mutex_construct( &gp_iou_mgr->pdo_mutex ); cl_qlist_init( &gp_iou_mgr->iou_list ); @@ -311,7 +321,7 @@ create_iou_mgr( /* Initialize the load service object. */ cl_status = cl_obj_init( &gp_iou_mgr->obj, CL_DESTROY_SYNC, - destroying_iou_mgr, NULL, free_iou_mgr ); + destroying_iou_mgr, NULL, free_iou_mgr ); if( cl_status != CL_SUCCESS ) { free_iou_mgr( &gp_iou_mgr->obj ); @@ -320,11 +330,12 @@ create_iou_mgr( return ib_convert_cl_status( cl_status ); } - /* Register for port PnP events. */ - status = bus_reg_iou_pnp(); + /* Register for IOU PnP events. */ + status = bus_reg_iou_pnp( p_bfi ); if( status != IB_SUCCESS ) { - cl_obj_destroy( &gp_iou_mgr->obj ); +// cl_obj_destroy( &gp_iou_mgr->obj ); + free_iou_mgr( &gp_iou_mgr->obj ); BUS_TRACE_EXIT( BUS_DBG_ERROR, ("bus_reg_iou_pnp returned %s.\n", ib_get_err_str(status)) ); return status; @@ -337,6 +348,26 @@ create_iou_mgr( } +void +destroy_iou_mgr_cb( IN void *context ) +{ + iou_pnp_ctx_t *p_ctx = context; + bus_filter_t *p_bfi; + + CL_ASSERT( p_ctx ); + CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC ); + + p_bfi = p_ctx->p_bus_filter; + BUS_PRINT(BUS_DBG_PNP, ("%s() Enter: obj %p?\n", __FUNCTION__, + p_bfi->p_iou_mgr_obj)); + + cl_obj_deref( p_bfi->p_iou_mgr_obj ); + + BUS_PRINT(BUS_DBG_PNP, ("%s() Exit: obj %p?\n", __FUNCTION__, + p_bfi->p_iou_mgr_obj)); +} + + /* * Pre-destroy the load service. */ @@ -345,20 +376,34 @@ destroying_iou_mgr( IN cl_obj_t* p_obj ) { ib_api_status_t status; + bus_filter_t *p_bfi; + iou_mgr_t *gp_iou_mgr; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_obj ); + p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj ); + if (p_bfi == NULL) { + BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n", + __FUNCTION__,p_obj)); + return; + } + gp_iou_mgr = p_bfi->p_iou_mgr; + + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p\n", + __FUNCTION__, p_bfi->whoami, p_obj, gp_iou_mgr)); + CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) ); - UNUSED_PARAM( p_obj ); - /* Deregister for port PnP events. */ - if( gp_iou_mgr->h_pnp ) + /* Deregister for iou PnP events. */ + if( get_bfi_count() == 1 && bus_globals.h_pnp_iou ) { - status = ib_dereg_pnp( gp_iou_mgr->h_pnp, - (ib_pfn_destroy_cb_t)cl_obj_deref ); + status = ib_dereg_pnp( bus_globals.h_pnp_iou, NULL ); + bus_globals.h_pnp_iou = NULL; CL_ASSERT( status == IB_SUCCESS ); } + cl_obj_deref( p_bfi->p_iou_mgr_obj ); + BUS_EXIT( BUS_DBG_PNP ); } @@ -372,14 +417,30 @@ free_iou_mgr( { bus_pdo_ext_t *p_ext; cl_list_item_t *p_list_item; + bus_filter_t *p_bfi; + iou_mgr_t *gp_iou_mgr; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_obj ); + p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj ); + if ( p_bfi == NULL ) { + BUS_PRINT( BUS_DBG_PNP, ("%s: unable to get p_bfi iou_obj %p?\n", + __FUNCTION__,p_obj) ); + return; + } + gp_iou_mgr = p_bfi->p_iou_mgr; + if ( !gp_iou_mgr ) { + // if create fails & then free is called, p_bfi->p_iou_mgr == NULL + return; + } + CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) ); + BUS_PRINT( BUS_DBG_PNP, ("%s(%s) Mark all IOU PDOs as no longer present\n", + __FUNCTION__, p_bfi->whoami)); /* - * Mark all IPoIB PDOs as no longer present. This will cause them + * Mark all IOU PDOs as no longer present. This will cause them * to be removed when they process the IRP_MN_REMOVE_DEVICE. */ p_list_item = cl_qlist_remove_head( &gp_iou_mgr->iou_list ); @@ -391,8 +452,10 @@ free_iou_mgr( { CL_ASSERT( !p_ext->b_present ); p_ext->b_reported_missing = TRUE; - BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n", - p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) ); + BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d\n", + p_bfi->whoami, + p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, + p_ext->b_present, p_ext->b_reported_missing ) ); continue; } if( p_ext->h_ca ) @@ -404,13 +467,25 @@ free_iou_mgr( /* Release the reference on the CA object. */ deref_al_obj( &p_ext->h_ca->obj ); } + BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s %s: PDO %p, ext %p\n", + p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity, + p_ext->cl_ext.p_self_do, p_ext ) ); + + BUS_TRACE( BUS_DBG_PNP,("%s(%s) p_ext->h_ca->obj.state %d ref_cnt %d\n", + __FUNCTION__, p_bfi->whoami, + p_ext->h_ca->obj.state, + p_ext->h_ca->obj.ref_cnt));//XXX + IoDeleteDevice( p_ext->cl_ext.p_self_do ); } cl_mutex_destroy( &gp_iou_mgr->pdo_mutex ); cl_obj_deinit( p_obj ); cl_free( gp_iou_mgr ); - gp_iou_mgr = NULL; + + p_bfi->p_iou_mgr = NULL; + p_bfi->p_iou_mgr_obj = NULL; + BUS_EXIT( BUS_DBG_PNP ); } @@ -419,22 +494,24 @@ free_iou_mgr( * Register the load service for the given PnP class events. */ ib_api_status_t -bus_reg_iou_pnp( void ) +bus_reg_iou_pnp( IN bus_filter_t *p_bfi ) { ib_pnp_req_t pnp_req; - ib_api_status_t status; + ib_api_status_t status = IB_SUCCESS; - cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) ); - pnp_req.pnp_class = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC; - pnp_req.pnp_context = gp_iou_mgr; - pnp_req.pfn_pnp_cb = iou_mgr_pnp_cb; + /* only need to register for PNP once */ + if ( get_bfi_count() == 1 ) { + cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) ); + pnp_req.pnp_class = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC; + pnp_req.pnp_context = NULL; + pnp_req.pfn_pnp_cb = iou_mgr_pnp_cb; - status = ib_reg_pnp( gh_al, &pnp_req, &gp_iou_mgr->h_pnp ); + status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_iou ); + } - if( status == IB_SUCCESS ) - { + if( status == IB_SUCCESS ) { /* Reference the load service on behalf of the ib_reg_pnp call. */ - cl_obj_ref( &gp_iou_mgr->obj ); + cl_obj_ref( &p_bfi->p_iou_mgr->obj ); } return status; @@ -448,12 +525,11 @@ ib_api_status_t iou_mgr_pnp_cb( IN ib_pnp_rec_t* p_pnp_rec ) { - ib_api_status_t status; + ib_api_status_t status=IB_SUCCESS; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_pnp_rec ); - CL_ASSERT( gp_iou_mgr == p_pnp_rec->pnp_context ); switch( p_pnp_rec->pnp_event ) { @@ -463,9 +539,11 @@ iou_mgr_pnp_cb( case IB_PNP_IOU_REMOVE: iou_mgr_iou_remove( (ib_pnp_iou_rec_t*)p_pnp_rec ); + break; default: - status = IB_SUCCESS; + BUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n", + __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) )); break; } BUS_EXIT( BUS_DBG_PNP ); @@ -482,9 +560,47 @@ iou_mgr_get_bus_relations( IN IRP* const p_irp ) { NTSTATUS status; + bus_filter_t *p_bfi; + iou_mgr_t *gp_iou_mgr; + DEVICE_RELATIONS *p_rel; BUS_ENTER( BUS_DBG_PNP ); + BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid)); + + /* special case guid == 0 - walk all bus filter instances */ + if ( ca_guid == 0ULL ) { + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) { + gp_iou_mgr = p_bfi->p_iou_mgr; + if ( !gp_iou_mgr ) + continue; + cl_mutex_acquire( &gp_iou_mgr->pdo_mutex ); + status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp ); + cl_mutex_release( &gp_iou_mgr->pdo_mutex ); + } + p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information; + if ( p_rel ) { + BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n", + __FUNCTION__,p_rel->Count)); + } + BUS_EXIT( BUS_DBG_PNP ); + return STATUS_SUCCESS; + } + + p_bfi = get_bfi_by_ca_guid(ca_guid); + if (p_bfi == NULL) { + BUS_PRINT(BUS_DBG_PNP, + ("%s() Null p_bfi from ca_guid %I64x ?\n",__FUNCTION__,ca_guid)); + BUS_EXIT( BUS_DBG_PNP ); + return STATUS_UNSUCCESSFUL; + } + gp_iou_mgr = p_bfi->p_iou_mgr; + + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x iou_mgr %p\n", + __FUNCTION__, p_bfi->whoami, ca_guid, gp_iou_mgr) ); + if (!gp_iou_mgr) + return STATUS_NO_SUCH_DEVICE; + cl_mutex_acquire( &gp_iou_mgr->pdo_mutex ); status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp ); cl_mutex_release( &gp_iou_mgr->pdo_mutex ); @@ -496,14 +612,17 @@ iou_mgr_get_bus_relations( static ib_api_status_t __iou_was_hibernated( - IN ib_pnp_iou_rec_t* p_pnp_rec ) + IN ib_pnp_iou_rec_t* p_pnp_rec, + IN bus_filter_t* p_bfi ) { NTSTATUS status; - cl_list_item_t *p_list_item; - bus_iou_ext_t *p_iou_ext; + cl_list_item_t *p_list_item; + bus_iou_ext_t *p_iou_ext; bus_pdo_ext_t *p_pdo_ext = NULL; size_t n_devs = 0; + iou_mgr_t *gp_iou_mgr = p_bfi->p_iou_mgr; cl_qlist_t* p_pdo_list = &gp_iou_mgr->iou_list; + iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; BUS_ENTER( BUS_DBG_PNP ); @@ -525,9 +644,11 @@ __iou_was_hibernated( break; } - BUS_TRACE( BUS_DBG_PNP, - ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n", - p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, + BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, " + "present %d, missing %d, hibernating %d, port_guid %I64x.\n", + p_bfi->whoami, + p_pdo_ext->cl_ext.vfptr_pnp_po->identity, + p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, p_pdo_ext->b_hibernating, p_iou_ext->guid ) ); } @@ -545,20 +666,23 @@ __iou_was_hibernated( else { p_pdo_ext->b_hibernating = FALSE; - p_pnp_rec->pnp_rec.context = p_pdo_ext; + p_ctx->p_pdo_ext = p_pdo_ext; // for iou_mgr_iou_remove() + status = IB_SUCCESS; p_iou_ext = (bus_iou_ext_t*)p_pdo_ext; - BUS_TRACE( BUS_DBG_PNP, - ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n", - p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, + BUS_TRACE( BUS_DBG_PNP, ("%s Found PDO for %s: PDO %p, ext %p, " + "present %d, missing %d, hibernating %d, port_guid %I64x.\n", + p_bfi->whoami, + p_pdo_ext->cl_ext.vfptr_pnp_po->identity, + p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, p_pdo_ext->b_hibernating, p_iou_ext->guid ) ); } } else { - BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid %I64x .\n", - p_pnp_rec->pnp_rec.guid ) ); + BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid %I64x .\n", + p_bfi->whoami, p_pnp_rec->pnp_rec.guid ) ); status = IB_NOT_FOUND; } @@ -575,13 +699,48 @@ iou_mgr_iou_add( NTSTATUS status; DEVICE_OBJECT *p_pdo; bus_iou_ext_t *p_iou_ext; + bus_filter_t *p_bfi; + iou_mgr_t *gp_iou_mgr; + iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; BUS_ENTER( BUS_DBG_PNP ); - /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but + p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->ca_guid ); + if ( !p_bfi ) { + BUS_PRINT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n", + __FUNCTION__, p_pnp_rec->ca_guid ) ); + return IB_ERROR; + } + + if ( !p_ctx ) { + /* + * Allocate a PNP context for this object. pnp_rec.context is object + * unique. + */ + p_ctx = cl_zalloc( sizeof(*p_ctx) ); + if( !p_ctx ) + { + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) ca_guid 0x%I64x iou_guid(%I64x) " + "BAD alloc for PNP context\n", __FUNCTION__, + p_bfi->whoami, p_bfi->ca_guid, p_pnp_rec->guid )); + + return IB_ERROR; + } + p_ctx->p_bus_filter = p_bfi; + p_pnp_rec->pnp_rec.context = p_ctx; + + BUS_PRINT(BUS_DBG_PNP, + ("%s(%s) ca_guid %I64x iou_guid(%I64x) ALLOC p_ctx @ %p\n", + __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, + p_pnp_rec->guid,p_ctx)); + } + gp_iou_mgr = p_bfi->p_iou_mgr; + + /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but marks with a flag. So we first try to find an existing PDO for this port, - marked with this flag. If it was found, we turn off the flag and use this PDO */ - status = __iou_was_hibernated(p_pnp_rec); + marked with this flag. If it was found, we turn off the flag and use + this PDO */ + status = __iou_was_hibernated( p_pnp_rec, p_bfi ); if( status != IB_NOT_FOUND ) { BUS_EXIT( BUS_DBG_PNP ); @@ -590,9 +749,11 @@ iou_mgr_iou_add( /* Create the PDO for the new port device. */ status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_iou_ext_t), - NULL, FILE_DEVICE_CONTROLLER, - FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, &p_pdo ); + NULL, FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN | + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &p_pdo ); + if( !NT_SUCCESS( status ) ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, @@ -602,18 +763,19 @@ iou_mgr_iou_add( /* Initialize the device extension. */ cl_init_pnp_po_ext( p_pdo, NULL, p_pdo, bus_globals.dbg_lvl, - &vfptr_iou_pnp, &vfptr_iou_query_txt ); + &vfptr_iou_pnp, &vfptr_iou_query_txt ); /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */ p_pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; p_iou_ext = p_pdo->DeviceExtension; p_iou_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0; - p_iou_ext->pdo.p_parent_ext = bus_globals.p_bus_ext; + p_iou_ext->pdo.p_parent_ext = p_bfi->p_bus_ext; p_iou_ext->pdo.b_present = TRUE; p_iou_ext->pdo.b_reported_missing = FALSE; BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n", - 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 ) ); + 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 ) ); p_iou_ext->guid = p_pnp_rec->guid; p_iou_ext->chassis_guid = p_pnp_rec->chassis_guid; @@ -626,6 +788,7 @@ iou_mgr_iou_add( p_iou_ext->revision = cl_ntoh32( p_pnp_rec->revision ); cl_memcpy( p_iou_ext->desc, p_pnp_rec->desc, IB_NODE_DESCRIPTION_SIZE + 1 ); + p_iou_ext->n_ifc_ref = 0; /* Cache the CA GUID. */ p_iou_ext->pdo.ca_guid = p_pnp_rec->ca_guid; @@ -641,23 +804,26 @@ iou_mgr_iou_add( /* Store the device extension in the PDO list for future queries. */ cl_mutex_acquire( &gp_iou_mgr->pdo_mutex ); - cl_qlist_insert_tail( &gp_iou_mgr->iou_list, - &p_iou_ext->pdo.list_item ); + cl_qlist_insert_tail( &gp_iou_mgr->iou_list, &p_iou_ext->pdo.list_item ); cl_mutex_release( &gp_iou_mgr->pdo_mutex ); /* * Set the context of the PNP event. The context is passed in for future * events on the same port. */ - p_pnp_rec->pnp_rec.context = p_iou_ext; + /* if not set in iou_was_hibernated(), set now */ + if ( !p_ctx->p_pdo_ext ) + p_ctx->p_pdo_ext = p_iou_ext; /* Tell the PnP Manager to rescan for the HCA's bus relations. */ IoInvalidateDeviceRelations( - p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); + p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); +#if 0 // XXX /* Invalidate removal relations for the bus driver. */ IoInvalidateDeviceRelations( - bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations ); + p_bfi->p_bus_ext->cl_ext.p_pdo, RemovalRelations ); +#endif BUS_EXIT( BUS_DBG_PNP ); @@ -670,13 +836,50 @@ iou_mgr_iou_remove( IN ib_pnp_iou_rec_t* p_pnp_rec ) { bus_pdo_ext_t *p_ext; + iou_mgr_t *gp_iou_mgr; + bus_filter_t *p_bfi; + iou_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; BUS_ENTER( BUS_DBG_PNP ); - /* The PNP record's context is the port extension. */ - p_ext = p_pnp_rec->pnp_rec.context; + if ( !p_ctx ) { + BUS_EXIT( BUS_DBG_PNP ); + return; + } + + CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC ); + p_bfi = p_ctx->p_bus_filter; + CL_ASSERT( p_bfi ); + + BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x iou_mgr %p\n", + __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, p_bfi->p_iou_mgr)); + + /* fdo_release_resources() has destroyed the IOU mgr, all that needs to be + * done is cleanup the PNP IOU context; one per port. + */ + if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_iou_mgr ) { + cl_free( p_ctx ); + p_pnp_rec->pnp_rec.context = NULL; + BUS_EXIT( BUS_DBG_PNP ); + return; + } + + gp_iou_mgr = p_bfi->p_iou_mgr; + + /* Within the Bus fabric instance is the port extension; see + * was_hibernated(). + */ + p_ext = p_ctx->p_pdo_ext; CL_ASSERT( p_ext ); + if (p_bfi != p_ext->p_parent_ext->bus_filter) { + BUS_PRINT(BUS_DBG_PNP, + ("%s() p_bfi(%p) != p_ext->bus_filter(%p) line %d file %s\n", + __FUNCTION__,p_bfi,p_ext->p_parent_ext->bus_filter, + __LINE__,__FILE__)); + CL_ASSERT (p_bfi == p_ext->p_parent_ext->bus_filter); + } + /* * Flag the port PDO as no longer being present. We have to wait until * the PnP manager removes it to clean up. However, we do release the @@ -684,31 +887,48 @@ iou_mgr_iou_remove( * to proceed should it occur before the port's PDO is cleaned up. */ cl_mutex_acquire( &gp_iou_mgr->pdo_mutex ); - CL_ASSERT( p_ext->h_ca ); + if ( !p_ext->h_ca ) + { + BUS_TRACE( BUS_DBG_PNP, ("%s() NULL h_ca? p_ext %p\n", + __FUNCTION__, p_ext ) ); + return; + } if( p_ext->b_hibernating ) { - BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n", - p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, + BUS_TRACE( BUS_DBG_PNP, ("%s Skip port removing for %s: PDO %p ext %p " + "present %d missing %d hibernating %d\n", + p_bfi->whoami, + 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, p_ext->b_hibernating ) ); goto hca_deref; } p_ext->b_present = FALSE; - BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n", - p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) ); + p_ext->b_reported_missing = TRUE; + + BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d .\n", + p_bfi->whoami, + p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, + p_ext->b_reported_missing ) ); +#if 0 // XXX /* Invalidate removal relations for the bus driver. */ - IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo, - RemovalRelations ); + IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo, + RemovalRelations ); +#endif /* Invalidate bus relations for the HCA. */ IoInvalidateDeviceRelations( p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); + /* free PNP context */ + cl_free( p_ctx ); + p_pnp_rec->pnp_rec.context = NULL; + hca_deref: deref_al_obj( &p_ext->h_ca->obj ); - p_ext->h_ca = NULL; cl_mutex_release( &gp_iou_mgr->pdo_mutex ); BUS_EXIT( BUS_DBG_PNP ); @@ -778,10 +998,12 @@ iou_release_resources( { bus_iou_ext_t *p_ext; POWER_STATE po_state; + iou_mgr_t *gp_iou_mgr; BUS_ENTER( BUS_DBG_PNP ); p_ext = p_dev_obj->DeviceExtension; + gp_iou_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_iou_mgr; /* Remove this PDO from its list. */ cl_mutex_acquire( &gp_iou_mgr->pdo_mutex ); diff --git a/branches/winverbs/core/bus/kernel/bus_iou_mgr.h b/branches/winverbs/core/bus/kernel/bus_iou_mgr.h index 2199be46..bfe420f7 100644 --- a/branches/winverbs/core/bus/kernel/bus_iou_mgr.h +++ b/branches/winverbs/core/bus/kernel/bus_iou_mgr.h @@ -43,7 +43,6 @@ typedef struct _iou_mgr { cl_obj_t obj; - ib_pnp_handle_t h_pnp; /* Handle for iou PnP events */ /* Mutex protects both pointer vectors. */ cl_mutex_t pdo_mutex; @@ -54,9 +53,12 @@ typedef struct _iou_mgr } iou_mgr_t; +struct _bus_filter_instance; + ib_api_status_t create_iou_mgr( - OUT iou_mgr_t** const pp_iou_mgr ); + IN struct _bus_filter_instance* p_bfi, + OUT iou_mgr_t** const pp_iou_mgr ); NTSTATUS diff --git a/branches/winverbs/core/bus/kernel/bus_pnp.c b/branches/winverbs/core/bus/kernel/bus_pnp.c index e0188c53..8c2d61b7 100644 --- a/branches/winverbs/core/bus/kernel/bus_pnp.c +++ b/branches/winverbs/core/bus/kernel/bus_pnp.c @@ -36,7 +36,6 @@ * Implemenation of all PnP functionality for FDO (power policy owners). */ - #include "bus_pnp.h" #include "al_ca.h" #include "al_init.h" @@ -48,6 +47,17 @@ #include "iba/ib_ci_ifc.h" +/* Interface names are generated by IoRegisterDeviceInterface. */ +static UNICODE_STRING al_ifc_name; +static UNICODE_STRING ci_ifc_name; + +FAST_MUTEX ControlMutex; +ULONG bfi_InstanceCount; +bus_filter_t bus_filters[MAX_BUS_FILTERS]; + +extern ib_al_handle_t gh_al; // NULL if AL needs init. + + static NTSTATUS fdo_start( IN DEVICE_OBJECT* const p_dev_obj, @@ -71,7 +81,7 @@ fdo_query_capabilities( OUT cl_irp_action_t* const p_action ); static NTSTATUS -fdo_query_remove_relations( +fdo_query_bus_relations( IN DEVICE_OBJECT* const p_dev_obj, IN IRP* const p_irp, OUT cl_irp_action_t* const p_action ); @@ -117,7 +127,7 @@ __fdo_set_power( #pragma alloc_text (PAGE, fdo_query_remove) #pragma alloc_text (PAGE, fdo_release_resources) #pragma alloc_text (PAGE, fdo_query_capabilities) -#pragma alloc_text (PAGE, fdo_query_remove_relations) +#pragma alloc_text (PAGE, fdo_query_bus_relations) #pragma alloc_text (PAGE, __query_al_ifc) #pragma alloc_text (PAGE, __query_ci_ifc) #pragma alloc_text (PAGE, __get_relations) @@ -143,9 +153,9 @@ static const cl_vfptr_pnp_po_t vfptr_fdo_pnp = { cl_irp_skip, cl_irp_skip, cl_do_sync_pnp, + fdo_query_bus_relations /*cl_irp_ignore*/ , cl_irp_ignore, - cl_irp_ignore, - fdo_query_remove_relations, + cl_irp_skip /*fdo_query_remove_relations now _bus_relations */ , cl_irp_ignore, cl_irp_ignore, cl_irp_ignore, @@ -170,58 +180,90 @@ bus_add_device( { NTSTATUS status; DEVICE_OBJECT *p_dev_obj, *p_next_do; - bus_fdo_ext_t *p_ext; + bus_fdo_ext_t *p_ext=NULL; UNICODE_STRING dev_name, dos_name; + bus_filter_t *p_bfi; + int ic; BUS_ENTER( BUS_DBG_PNP ); - if( bus_globals.p_bus_ext ) + /* allocate a Bus Filter Instance */ + p_bfi = alloc_bfi( p_driver_obj, &ic ); + if ( !p_bfi ) { - BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("Bus root already exists. Only one bus root allowed.\n") ); - return STATUS_NO_SUCH_DEVICE; + BUS_PRINT( BUS_DBG_PNP, + ("%s() Err - Exceeded MAX_BUS_FILTERS(%d)\n",MAX_BUS_FILTERS)); + return STATUS_UNSUCCESSFUL; } - RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME ); - RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" ); - /* Create the FDO device object to attach to the stack. */ - status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t), - &dev_name, FILE_DEVICE_BUS_EXTENDER, - FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj ); - if( !NT_SUCCESS(status) ) + + /* if 1st Bus Filter Instance, then create device names for user ioctl */ + if ( ic == 1 ) { - BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("Failed to create bus root FDO device.\n") ); - return status; + RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME ); + RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" ); + + status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t), + &dev_name, FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj ); + if( !NT_SUCCESS(status) ) + { + BUS_TRACE_EXIT( BUS_DBG_ERROR, + ("Failed to create ControlDeviceObject, status %x.\n",status) ); + goto bail; + } + IoDeleteSymbolicLink( &dos_name ); + status = IoCreateSymbolicLink( &dos_name, &dev_name ); + if( !NT_SUCCESS(status) ) + { + IoDeleteDevice( p_dev_obj ); + BUS_TRACE_EXIT( BUS_DBG_ERROR, + ("Failed to create symlink for dos name.\n") ); + goto bail; + } + } + else { + status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t), + NULL, FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj ); } - IoDeleteSymbolicLink( &dos_name ); - status = IoCreateSymbolicLink( &dos_name, &dev_name ); if( !NT_SUCCESS(status) ) { - IoDeleteDevice( p_dev_obj ); - BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("Failed to create symlink for dos name.\n") ); - return status; + BUS_TRACE_EXIT( BUS_DBG_ERROR, + ("Failed to create bus root FDO device.\n") ); + goto bail; } p_ext = p_dev_obj->DeviceExtension; + p_ext->n_al_ifc_ref = 0; + p_ext->n_ci_ifc_ref = 0; p_next_do = IoAttachDeviceToDeviceStack( p_dev_obj, p_pdo ); if( !p_next_do ) { IoDeleteDevice( p_dev_obj ); BUS_TRACE_EXIT( BUS_DBG_ERROR, ("IoAttachToDeviceStack failed.\n") ); - return STATUS_NO_SUCH_DEVICE; + status = STATUS_NO_SUCH_DEVICE; + goto bail; } cl_init_pnp_po_ext( p_dev_obj, p_next_do, p_pdo, bus_globals.dbg_lvl, - &vfptr_fdo_pnp, NULL ); + &vfptr_fdo_pnp, NULL ); + + p_bfi->p_bus_ext = p_ext; + p_ext->bus_filter = p_bfi; + + /* + * if not 1st Bus Filter Instance, then finished... + */ + if ( ic > 1 ) + goto adxit; /* Register the upper interface (the one used by clients). */ - status = IoRegisterDeviceInterface( p_pdo, - &GUID_IB_AL_INTERFACE, NULL, &p_ext->al_ifc_name ); + status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_AL_INTERFACE, NULL, + &al_ifc_name ); if( !NT_SUCCESS( status ) ) { IoDetachDevice( p_ext->cl_ext.p_next_do ); @@ -229,27 +271,43 @@ bus_add_device( BUS_TRACE_EXIT( BUS_DBG_ERROR, ("IoRegisterDeviceInterface for upper interface returned %08x\n", status) ); - return STATUS_NO_SUCH_DEVICE; + status = STATUS_NO_SUCH_DEVICE; + goto bail; } - /* Register the lower interface (the one used by HCA VPDs). */ - status = IoRegisterDeviceInterface( p_pdo, - &GUID_IB_CI_INTERFACE, NULL, &p_ext->ci_ifc_name ); + /* Register the lower (CI) interface (the one used by HCA VPDs). */ + status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_CI_INTERFACE, NULL, + &ci_ifc_name ); if( !NT_SUCCESS( status ) ) { - RtlFreeUnicodeString( &p_ext->al_ifc_name ); IoDetachDevice( p_ext->cl_ext.p_next_do ); IoDeleteDevice( p_dev_obj ); BUS_TRACE_EXIT( BUS_DBG_ERROR, ("IoRegisterDeviceInterface for lower interface returned %08x\n", status) ); - return STATUS_NO_SUCH_DEVICE; + status = STATUS_NO_SUCH_DEVICE; + goto bail; } - bus_globals.p_bus_ext = p_ext; +adxit: + BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status 0\n", + __FUNCTION__, p_bfi->whoami) ); BUS_EXIT( BUS_DBG_PNP ); return STATUS_SUCCESS; + +bail: + BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status %d\n", + __FUNCTION__,p_bfi->whoami,status) ); + ic = free_bfi(p_bfi); + /* if last Bus filter, then cleanup */ + if ( ic == 0 ) + { + IoDeleteSymbolicLink( &dos_name ); + RtlFreeUnicodeString( &al_ifc_name ); + } + BUS_EXIT( BUS_DBG_PNP ); + return status; } @@ -262,10 +320,13 @@ fdo_start( NTSTATUS status; bus_fdo_ext_t *p_ext; ib_api_status_t ib_status; + bus_filter_t *p_bfi; + boolean_t AL_init_here = FALSE; BUS_ENTER( BUS_DBG_PNP ); p_ext = p_dev_obj->DeviceExtension; + p_bfi = p_ext->bus_filter; /* Handled on the way up. */ status = cl_do_sync_pnp( p_dev_obj, p_irp, p_action ); @@ -276,18 +337,24 @@ fdo_start( return status; } - /* Initialize AL */ - ib_status = al_initialize(); - if( ib_status != IB_SUCCESS ) - { - al_cleanup(); - BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n", - ib_get_err_str(ib_status)) ); - return STATUS_UNSUCCESSFUL; + ExAcquireFastMutexUnsafe(&ControlMutex); + if ( !gh_al ) { + /* Initialize AL */ + ib_status = al_initialize(); + if( ib_status != IB_SUCCESS ) + { + al_cleanup(); + BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n", + ib_get_err_str(ib_status)) ); + ExReleaseFastMutexUnsafe(&ControlMutex); + return STATUS_UNSUCCESSFUL; + } + AL_init_here = TRUE; } + ExReleaseFastMutexUnsafe(&ControlMutex); /* Initialize the port manager. */ - ib_status = create_port_mgr( &p_ext->p_port_mgr ); + ib_status = create_port_mgr( p_ext->bus_filter, &p_ext->p_port_mgr ); if( ib_status != IB_SUCCESS ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_port_mgr returned %s.\n", @@ -296,7 +363,7 @@ fdo_start( } /* Initialize the IOU manager. */ - ib_status = create_iou_mgr( &p_ext->p_iou_mgr ); + ib_status = create_iou_mgr( p_ext->bus_filter, &p_ext->p_iou_mgr ); if( ib_status != IB_SUCCESS ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_iou_mgr returned %s.\n", @@ -304,13 +371,18 @@ fdo_start( return STATUS_UNSUCCESSFUL; } - status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, TRUE ); - ASSERT( NT_SUCCESS( status ) ); + if ( AL_init_here ) { + status = IoSetDeviceInterfaceState( &al_ifc_name, TRUE ); + ASSERT( NT_SUCCESS( status ) ); - status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, TRUE ); - ASSERT( NT_SUCCESS( status ) ); + status = IoSetDeviceInterfaceState( &ci_ifc_name, TRUE ); + ASSERT( NT_SUCCESS( status ) ); + } + BUS_PRINT(BUS_DBG_PNP, + ("%s() %s exit %x\n",__FUNCTION__,p_bfi->whoami,status)); BUS_EXIT( BUS_DBG_PNP ); + return status; } @@ -327,6 +399,11 @@ fdo_query_remove( p_ext = p_dev_obj->DeviceExtension; + BUS_PRINT( BUS_DBG_PNP, + ("%s() IRP_MN_QUERY_REMOVE_DEVICE %s @ %p refs CI %d AL %d\n", + __FUNCTION__, p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, + p_ext->n_ci_ifc_ref,p_ext->n_al_ifc_ref ) ); // XXX + if( p_ext->n_ci_ifc_ref ) { /* @@ -363,30 +440,52 @@ fdo_release_resources( { bus_fdo_ext_t *p_ext; NTSTATUS status; + bus_filter_t *p_bfi; + int ic; BUS_ENTER( BUS_DBG_PNP ); p_ext = p_dev_obj->DeviceExtension; + ic = get_bfi_count(); //TODO: Fail outstanding I/O operations. + if (p_ext->p_port_mgr) + cl_obj_destroy( &p_ext->p_port_mgr->obj ); + + if (p_ext->p_iou_mgr) + cl_obj_destroy( &p_ext->p_iou_mgr->obj ); + + p_bfi = p_ext->bus_filter; + CL_ASSERT( p_bfi ); + BUS_PRINT( BUS_DBG_PNP, ("%s() Releasing BusFilter %s\n", + __FUNCTION__, p_bfi->whoami )); + if (p_bfi) { + p_ext->bus_filter = NULL; + p_bfi->p_bus_ext = NULL; + } + + ic = free_bfi( p_bfi ); + + /* if not last Buf Filter Instance, then exit, otherwise cleanup/shutdown */ + if ( ic > 0 ) { + BUS_PRINT( BUS_DBG_PNP, ("%s() %d remaining BusFilters\n", + __FUNCTION__, ic )); + return; + } + /* Disable any exported interfaces. */ - status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, FALSE ); + status = IoSetDeviceInterfaceState( &al_ifc_name, FALSE ); ASSERT( NT_SUCCESS( status ) ); - status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, FALSE ); + status = IoSetDeviceInterfaceState( &ci_ifc_name, FALSE ); ASSERT( NT_SUCCESS( status ) ); /* Release the memory allocated for the interface symbolic names. */ - RtlFreeUnicodeString( &p_ext->ci_ifc_name ); - RtlFreeUnicodeString( &p_ext->al_ifc_name ); - - cl_obj_destroy( &p_ext->p_port_mgr->obj ); - cl_obj_destroy( &p_ext->p_iou_mgr->obj ); + RtlFreeUnicodeString( &ci_ifc_name ); + RtlFreeUnicodeString( &al_ifc_name ); al_cleanup(); - bus_globals.p_bus_ext = NULL; - BUS_EXIT( BUS_DBG_PNP ); } @@ -431,18 +530,19 @@ fdo_query_capabilities( } +#if 0 // XXX + static NTSTATUS -fdo_query_remove_relations( +fdo_query_removal_relations( IN DEVICE_OBJECT* const p_dev_obj, IN IRP* const p_irp, OUT cl_irp_action_t* const p_action ) { NTSTATUS status; + UNUSED_PARAM( p_dev_obj ); BUS_ENTER( BUS_DBG_PNP ); - UNUSED_PARAM( p_dev_obj ); - status = port_mgr_get_bus_relations( 0, p_irp ); if( status == STATUS_SUCCESS || status == STATUS_NO_SUCH_DEVICE ) @@ -471,6 +571,67 @@ fdo_query_remove_relations( BUS_EXIT( BUS_DBG_PNP ); return status; } +#endif + + +static NTSTATUS +fdo_query_bus_relations( + IN DEVICE_OBJECT* const p_dev_obj, + IN IRP* const p_irp, + OUT cl_irp_action_t* const p_action ) +{ + NTSTATUS status; + bus_fdo_ext_t *p_ext; + bus_filter_t *p_bfi; + + BUS_ENTER( BUS_DBG_PNP ); + + p_ext = p_dev_obj->DeviceExtension; + CL_ASSERT( p_ext->bus_filter ); + p_bfi = p_ext->bus_filter; + CL_ASSERT( p_bfi->magic == BFI_MAGIC ); + + BUS_PRINT( BUS_DBG_PNP, ("%s(%s) ca_guid %I64x\n", + __FUNCTION__,p_bfi->whoami, p_bfi->ca_guid) ); + + if ( p_bfi->ca_guid == 0ULL ) + { + /* HCA not yet bound to a BFI slot (no PNP ADD event seen), no bus + * relations yet. + */ + status = STATUS_SUCCESS; + } + else + { + status = port_mgr_get_bus_relations( p_bfi->ca_guid, p_irp ); + if( status == STATUS_SUCCESS || + status == STATUS_NO_SUCH_DEVICE ) + { + status = iou_mgr_get_bus_relations( p_bfi->ca_guid, p_irp ); + } + if( status == STATUS_NO_SUCH_DEVICE ) + status = STATUS_SUCCESS; + } + + switch( status ) + { + case STATUS_NO_SUCH_DEVICE: + *p_action = IrpSkip; + status = STATUS_SUCCESS; + break; + + case STATUS_SUCCESS: + *p_action = IrpPassDown; + break; + + default: + *p_action = IrpComplete; + break; + } + + BUS_EXIT( BUS_DBG_PNP ); + return status; +} void @@ -486,6 +647,8 @@ al_ref_ifc( cl_atomic_inc( &p_ext->n_al_ifc_ref ); ObReferenceObject( p_dev_obj ); + BUS_PRINT( BUS_DBG_PNP, (" %p->n_al_ifc_ref %d\n", + p_ext,p_ext->n_al_ifc_ref )); // XXX BUS_EXIT( BUS_DBG_PNP ); } @@ -503,6 +666,8 @@ al_deref_ifc( cl_atomic_dec( &p_ext->n_al_ifc_ref ); ObDereferenceObject( p_dev_obj ); + BUS_PRINT( BUS_DBG_PNP, (" %p->n_al_ifc_ref %d\n", + p_ext,p_ext->n_al_ifc_ref )); // XXX BUS_EXIT( BUS_DBG_PNP ); } @@ -520,6 +685,8 @@ al_ref_ci_ifc( cl_atomic_inc( &p_ext->n_ci_ifc_ref ); ObReferenceObject( p_dev_obj ); + BUS_PRINT( BUS_DBG_PNP, (" %p->n_ci_ifc_ref %d\n", + p_ext,p_ext->n_ci_ifc_ref )); // XXX BUS_EXIT( BUS_DBG_PNP ); } @@ -537,6 +704,8 @@ al_deref_ci_ifc( cl_atomic_dec( &p_ext->n_ci_ifc_ref ); ObDereferenceObject( p_dev_obj ); + BUS_PRINT( BUS_DBG_PNP, (" %p->n_ci_ifc_ref %d\n", + p_ext,p_ext->n_ci_ifc_ref )); // XXX BUS_EXIT( BUS_DBG_PNP ); } @@ -777,9 +946,7 @@ fdo_query_interface( BUS_ENTER( BUS_DBG_PNP ); -#pragma warning( push, 3 ) PAGED_CODE(); -#pragma warning( pop ) p_io_stack = IoGetCurrentIrpStackLocation( p_irp ); @@ -971,7 +1138,8 @@ __fdo_set_power( BUS_TRACE( BUS_DBG_POWER, ("SET_POWER for FDO %p (ext %p): type %s, state %d, action %d \n", p_dev_obj, p_ext, - (p_io_stack->Parameters.Power.Type) ? "DevicePowerState" : "SystemPowerState", + (p_io_stack->Parameters.Power.Type) + ? "DevicePowerState" : "SystemPowerState", p_io_stack->Parameters.Power.State.DeviceState, p_io_stack->Parameters.Power.ShutdownType )); @@ -1073,16 +1241,18 @@ bus_get_relations( * the PDO will get cleaned up. */ p_pdo_ext->b_reported_missing = TRUE; - BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, present %d, missing %d .\n", - p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, - p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing ) ); + BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, " + "present %d, missing %d .\n", + p_pdo_ext->cl_ext.vfptr_pnp_po->identity, + p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present, + p_pdo_ext->b_reported_missing ) ); continue; } if( ca_guid && p_pdo_ext->ca_guid != ca_guid ) continue; - BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p.\n", + BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p\n", p_pdo_ext->cl_ext.p_self_do, p_pdo_ext->cl_ext.p_pdo, p_pdo_ext )); p_rel->Objects[p_rel->Count] = p_pdo_ext->cl_ext.p_pdo; @@ -1092,3 +1262,256 @@ bus_get_relations( BUS_EXIT( BUS_DBG_PNP ); return STATUS_SUCCESS; } + + +/* + * find a bus filter instance (p_bfi) given an *cl_obj: port_mgr or iou_mgr. + */ + +bus_filter_t * +get_bfi_by_obj(IN int obj_type, IN cl_obj_t *p_obj ) +{ + bus_filter_t *p_bfi; + bus_filter_t *matched=NULL; + + CL_ASSERT((obj_type == BFI_PORT_MGR_OBJ) || (obj_type == BFI_IOU_MGR_OBJ)); + + ExAcquireFastMutexUnsafe(&ControlMutex); + + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) { + + if ( !p_bfi->p_bus_ext ) + continue; + + if ( obj_type == BFI_PORT_MGR_OBJ ) { + if ( p_obj == p_bfi->p_port_mgr_obj ) { + matched = p_bfi; + break; + } + } + else { + if ( p_obj == p_bfi->p_iou_mgr_obj ) { + matched = p_bfi; + break; + } + } + } + ExReleaseFastMutexUnsafe(&ControlMutex); + + BUS_PRINT( BUS_DBG_PNP, + ("%s() cl_obj %p type %s_MGR_OBJ --> bfi[%d] %p\n", + __FUNCTION__,p_obj, + (obj_type == BFI_PORT_MGR_OBJ ? "PORT": "IOU"), + (matched ? (matched - bus_filters) : (-1)), matched ) ); + + return matched; +} + +/* + * find a bus filter instance given an HCA guid. + */ + +bus_filter_t * +get_bfi_by_ca_guid( IN net64_t ca_guid ) +{ + bus_filter_t *p_bfi; + bus_filter_t *matched=NULL; + + if ( ca_guid == 0ULL ) + { + matched = bus_filters; + BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid %I64x -> bfi[0] %p\n", + __FUNCTION__, ca_guid, matched) ); + CL_ASSERT( ca_guid ); // XXX + return matched; + } + + ExAcquireFastMutexUnsafe(&ControlMutex); + + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) + { + if ( !p_bfi->p_bus_ext ) + continue; + + if ( ca_guid == p_bfi->ca_guid ) + { + matched = p_bfi; + break; + } + } + ExReleaseFastMutexUnsafe(&ControlMutex); + + BUS_PRINT( BUS_DBG_PNP, + ("%s() guid 0x%I64x -> bfi[%d] %p\n", + __FUNCTION__, ca_guid, + (matched ? (matched - bus_filters) : (-1)), matched ) ); + + return matched; +} + + +/* + * find/bind the specified ca_guid to a bus filter instance. + * Called from PORT_ADD or IOU_ADD pnp callback routines with the ca_guid from + * the pnp event record. + * Assumption is a BFI slot has been allocated in add_device() although the + * ca_guid was not known at that time; hence !ca_bound. When PNP generates an + * 'ADD' event, the port_mgr/iou_mgr pnp callback routine calls here to match + * the input ca_guid which caused the PNP event to the BFI instance by ca_guid. + * In the 1st call after add_device() the BFI slot is allocated but not yet + * bound to a CA guid. If the input ca_guid is not matched, then the 1st + * allocated but not bound BFI slot is then 'bound' by setting + * bfi->ca_guid = input ca_guid. + */ + +bus_filter_t * +get_set_bfi_by_ca_guid( IN net64_t ca_guid ) +{ + bus_filter_t *p_bfi; + bus_filter_t *matched=NULL; + boolean_t ca_bound = FALSE; + + if ( ca_guid == 0ULL ) + { + matched = bus_filters; + BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid 0x%I64x -> bfi[0] %p\n", + __FUNCTION__, ca_guid, matched) ); + CL_ASSERT( ca_guid ); // XXX + return matched; + } + + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) + { + if ( !p_bfi->p_bus_ext ) + continue; + + if ( ca_guid == p_bfi->ca_guid ) + { + matched = p_bfi; + break; + } + } + + /* + * if no match, find an 'allocated' bfi slot which does not have a bound CA. + * Bound == ca_guid != 0ULL. + */ + if ( !matched ) + { + ExAcquireFastMutexUnsafe(&ControlMutex); + + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) + { + if ( !p_bfi->p_bus_ext ) + continue; // not allocated. + + if ( p_bfi->ca_guid == 0ULL ) + { + ca_bound = TRUE; + p_bfi->ca_guid = ca_guid; // bind CA & this BFI slot; RTU. + matched = p_bfi; + break; + } + } + ExReleaseFastMutexUnsafe(&ControlMutex); + } + + BUS_PRINT( BUS_DBG_PNP, + ("%s()%sguid 0x%I64x @ bfi[%d] %p \n", + __FUNCTION__, (ca_bound ? "SET ":" "), ca_guid, + (matched ? (matched - bus_filters) : (-1)), matched ) ); + + return matched; +} + + +bus_filter_t * +alloc_bfi( IN DRIVER_OBJECT *p_driver_obj, OUT int *p_instance_count ) +{ + bus_filter_t *p_bfi; + bus_filter_t *matched=NULL; + + // Using unsafe function so that the IRQL remains at PASSIVE_LEVEL. + // IoCreateDeviceSecure & IoCreateSymbolicLink must be called at + // PASSIVE_LEVEL. + + ExAcquireFastMutexUnsafe(&ControlMutex); + + // find 1st unused bfi slot. + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) + { + if ( !p_bfi->p_bus_ext ) + { + /* temp setting until 'real' p_bus_ext is alloc; see bus_add_device. + * If p_bus_ext is ! 0, then bfi slot is allocated, although it + * may not yet have a bound CA guid; set set_get_ + */ + p_bfi->p_bus_ext = (bus_fdo_ext_t*)p_driver_obj; + matched = p_bfi; + *p_instance_count = ++bfi_InstanceCount; // record in-use + break; + } + } + ExReleaseFastMutexUnsafe(&ControlMutex); + +#if DBG + RtlStringCbPrintfA ( p_bfi->whoami, + sizeof(p_bfi->whoami), + "bfi-%d", + (bfi_InstanceCount - 1) ); + + p_bfi->magic = BFI_MAGIC; // XXX debug +#endif + + BUS_PRINT( BUS_DBG_PNP, ("%s() %s %p\n", + __FUNCTION__, (matched ? matched->whoami:"Nobody"), matched) ); + + return matched; +} + + +int +free_bfi( IN bus_filter_t *p_bfi ) +{ + int remaining; + + ExAcquireFastMutexUnsafe(&ControlMutex); + p_bfi->p_bus_ext = NULL; + p_bfi->ca_guid = 0ULL; + remaining = --bfi_InstanceCount; // one less bfi in-use + ExReleaseFastMutexUnsafe(&ControlMutex); + + return remaining; +} + +int +get_bfi_count( void ) +{ + int ic; + + ExAcquireFastMutexUnsafe(&ControlMutex); + ic = bfi_InstanceCount; + ExReleaseFastMutexUnsafe(&ControlMutex); + + return ic; +} + +#if DBG +char *get_obj_state_str(cl_state_t state) +{ + switch( state ) { + case CL_UNINITIALIZED: + return "UNINITIALIZED"; + case CL_INITIALIZED: + return "INITIALIZED"; + case CL_DESTROYING: + return "DESTROYING"; + case CL_DESTROYED: + return "DESTROYED"; + default: + break; + } + return "Err - Bad obj state"; +} +#endif + diff --git a/branches/winverbs/core/bus/kernel/bus_port_mgr.c b/branches/winverbs/core/bus/kernel/bus_port_mgr.c index 8d79576f..31837284 100644 --- a/branches/winverbs/core/bus/kernel/bus_port_mgr.c +++ b/branches/winverbs/core/bus/kernel/bus_port_mgr.c @@ -71,7 +71,14 @@ typedef struct _bus_port_ext } bus_port_ext_t; -port_mgr_t* gp_port_mgr = NULL; +typedef struct _port_pnp_context +{ + bus_filter_t *p_bus_filter; + void *p_pdo_ext; + int port_num; + +} port_pnp_ctx_t; + extern pkey_array_t g_pkeys; @@ -88,7 +95,8 @@ free_port_mgr( IN cl_obj_t* p_obj ); ib_api_status_t -bus_reg_port_pnp( void ); +bus_reg_port_pnp( + IN bus_filter_t* p_bfi ); ib_api_status_t port_mgr_pnp_cb( @@ -274,14 +282,16 @@ static const cl_vfptr_query_txt_t vfptr_port_query_txt = { */ ib_api_status_t create_port_mgr( + IN bus_filter_t* p_bfi, OUT port_mgr_t** const pp_port_mgr ) { ib_api_status_t status; cl_status_t cl_status; + port_mgr_t *gp_port_mgr; BUS_ENTER( BUS_DBG_PNP ); - CL_ASSERT( !gp_port_mgr ); + CL_ASSERT( p_bfi->p_port_mgr == NULL ); gp_port_mgr = cl_zalloc( sizeof( port_mgr_t ) ); if( !gp_port_mgr ) @@ -290,9 +300,11 @@ create_port_mgr( ("Failed to allocate port manager.\n") ); return IB_INSUFFICIENT_MEMORY; } + p_bfi->p_port_mgr = gp_port_mgr; /* Construct the load service. */ cl_obj_construct( &gp_port_mgr->obj, AL_OBJ_TYPE_LOADER ); + p_bfi->p_port_mgr_obj = &gp_port_mgr->obj; cl_mutex_construct( &gp_port_mgr->pdo_mutex ); cl_qlist_init( &gp_port_mgr->port_list ); @@ -307,7 +319,8 @@ create_port_mgr( /* Initialize the load service object. */ cl_status = cl_obj_init( &gp_port_mgr->obj, CL_DESTROY_SYNC, - destroying_port_mgr, NULL, free_port_mgr ); + destroying_port_mgr, NULL, free_port_mgr ); + if( cl_status != CL_SUCCESS ) { free_port_mgr( &gp_port_mgr->obj ); @@ -316,13 +329,13 @@ create_port_mgr( return ib_convert_cl_status( cl_status ); } - /* Register for port PnP events. */ - status = bus_reg_port_pnp(); + /* Register for port PnP events */ + status = bus_reg_port_pnp(p_bfi); if( status != IB_SUCCESS ) { - cl_obj_destroy( &gp_port_mgr->obj ); BUS_TRACE_EXIT( BUS_DBG_ERROR, ("bus_reg_port_pnp returned %s.\n", ib_get_err_str(status)) ); + free_port_mgr( &gp_port_mgr->obj ); return status; } @@ -341,20 +354,35 @@ destroying_port_mgr( IN cl_obj_t* p_obj ) { ib_api_status_t status; + bus_filter_t *p_bfi; + port_mgr_t *gp_port_mgr; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_obj ); + p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj); + if (p_bfi == NULL) { + BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n", + __FUNCTION__,p_obj)); + return; + } + gp_port_mgr = p_bfi->p_port_mgr; + + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n", + __FUNCTION__,p_bfi->whoami,p_obj,gp_port_mgr, + p_bfi->p_port_mgr_obj) ); + + CL_ASSERT( (void*)p_bfi->p_port_mgr == (void*)p_bfi->p_port_mgr_obj ); CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) ); - UNUSED_PARAM( p_obj ); - /* Deregister for port PnP events. */ - if( gp_port_mgr->h_pnp ) - { - status = ib_dereg_pnp( gp_port_mgr->h_pnp, - (ib_pfn_destroy_cb_t)cl_obj_deref ); + /* Deregister for port PnP events if this is the last Port manager. */ + if ( get_bfi_count() == 1 && bus_globals.h_pnp_port ) { + status = ib_dereg_pnp( bus_globals.h_pnp_port, NULL ); + bus_globals.h_pnp_port = NULL; CL_ASSERT( status == IB_SUCCESS ); } + cl_obj_deref( p_bfi->p_port_mgr_obj ); + BUS_EXIT( BUS_DBG_PNP ); } @@ -368,12 +396,32 @@ free_port_mgr( { bus_pdo_ext_t *p_ext; cl_list_item_t *p_list_item; + bus_filter_t *p_bfi; + port_mgr_t *gp_port_mgr; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_obj ); + p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj); + if (p_bfi == NULL) { + BUS_PRINT(BUS_DBG_PNP, ("%s: unable to get p_bfi for port obj %p?\n", + __FUNCTION__,p_obj)); + return; + } + gp_port_mgr = p_bfi->p_port_mgr; + if ( !gp_port_mgr ) { + // if create fails & then free is called, p_bfi->p_port_mgr == NULL + return; + } CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) ); + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n", + __FUNCTION__, p_bfi->whoami, p_obj,gp_port_mgr, + p_bfi->p_port_mgr_obj) ); + + BUS_PRINT( BUS_DBG_PNP, + ("%s(%s) Mark all IPoIB PDOs as no longer present\n", + __FUNCTION__, p_bfi->whoami)); /* * Mark all IPoIB PDOs as no longer present. This will cause them * to be removed when they process the IRP_MN_REMOVE_DEVICE. @@ -387,8 +435,11 @@ free_port_mgr( { CL_ASSERT( !p_ext->b_present ); p_ext->b_reported_missing = TRUE; - BUS_TRACE( BUS_DBG_PNP, ("%s: PDO %p, ext %p, present %d, missing %d .\n", - 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 ) ); + BUS_TRACE( BUS_DBG_PNP, + ("%s %s: PDO %p, ext %p, present %d, missing %d .\n", + p_bfi->whoami, + 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 ) ); continue; } if( p_ext->h_ca ) @@ -400,15 +451,26 @@ free_port_mgr( /* Release the reference on the CA object. */ deref_al_obj( &p_ext->h_ca->obj ); } - BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p, ext %p\n", - p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext ) ); + + BUS_TRACE( BUS_DBG_PNP, ("%s Deleted device %s: PDO %p, ext %p\n", + p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity, + p_ext->cl_ext.p_self_do, p_ext ) ); + + BUS_TRACE( BUS_DBG_PNP,("%s(%s) h_ca->obj.state %s refs %d\n", + __FUNCTION__, p_bfi->whoami, + get_obj_state_str(p_ext->h_ca->obj.state), + p_ext->h_ca->obj.ref_cnt)); // XXX + IoDeleteDevice( p_ext->cl_ext.p_self_do ); } cl_mutex_destroy( &gp_port_mgr->pdo_mutex ); cl_obj_deinit( p_obj ); cl_free( gp_port_mgr ); - gp_port_mgr = NULL; + + p_bfi->p_port_mgr = NULL; + p_bfi->p_port_mgr_obj = NULL; + BUS_EXIT( BUS_DBG_PNP ); } @@ -417,22 +479,26 @@ free_port_mgr( * Register the load service for the given PnP class events. */ ib_api_status_t -bus_reg_port_pnp( void ) +bus_reg_port_pnp( IN bus_filter_t *p_bfi ) { ib_pnp_req_t pnp_req; - ib_api_status_t status; + ib_api_status_t status = IB_SUCCESS; - cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) ); - pnp_req.pnp_class = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC; - pnp_req.pnp_context = gp_port_mgr; - pnp_req.pfn_pnp_cb = port_mgr_pnp_cb; + /* only need to register for PNP once */ + ExAcquireFastMutexUnsafe(&ControlMutex); + if ( !bus_globals.h_pnp_port ) { + cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) ); + pnp_req.pnp_class = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC; + pnp_req.pnp_context = NULL; + pnp_req.pfn_pnp_cb = port_mgr_pnp_cb; - status = ib_reg_pnp( gh_al, &pnp_req, &gp_port_mgr->h_pnp ); + status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_port ); + } + ExReleaseFastMutexUnsafe(&ControlMutex); - if( status == IB_SUCCESS ) - { - /* Reference the load service on behalf of the ib_reg_pnp call. */ - cl_obj_ref( &gp_port_mgr->obj ); + if( status == IB_SUCCESS ) { + /* Reference this bus filter's port load service */ + cl_obj_ref( &p_bfi->p_port_mgr->obj ); } return status; @@ -446,12 +512,11 @@ ib_api_status_t port_mgr_pnp_cb( IN ib_pnp_rec_t* p_pnp_rec ) { - ib_api_status_t status; + ib_api_status_t status=IB_SUCCESS; BUS_ENTER( BUS_DBG_PNP ); CL_ASSERT( p_pnp_rec ); - CL_ASSERT( gp_port_mgr == p_pnp_rec->pnp_context ); switch( p_pnp_rec->pnp_event ) { @@ -461,12 +526,15 @@ port_mgr_pnp_cb( case IB_PNP_PORT_REMOVE: port_mgr_port_remove( (ib_pnp_port_rec_t*)p_pnp_rec ); + break; default: - status = IB_SUCCESS; + XBUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n", + __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) )); break; } BUS_EXIT( BUS_DBG_PNP ); + return status; } @@ -480,9 +548,50 @@ port_mgr_get_bus_relations( IN IRP* const p_irp ) { NTSTATUS status; + bus_filter_t *p_bfi; + port_mgr_t *gp_port_mgr; + DEVICE_RELATIONS *p_rel; BUS_ENTER( BUS_DBG_PNP ); + BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid)); + + /* special case guid == 0 - walk all bus filter instances */ + if ( ca_guid == 0ULL ) { + for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) { + gp_port_mgr = p_bfi->p_port_mgr; + if ( !gp_port_mgr ) + continue; + cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); + status = bus_get_relations( &gp_port_mgr->port_list, + ca_guid, + p_irp ); + cl_mutex_release( &gp_port_mgr->pdo_mutex ); + } + + p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information; + if ( p_rel ) { + BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n", + __FUNCTION__,p_rel->Count)); + } + BUS_EXIT( BUS_DBG_PNP ); + return STATUS_SUCCESS; + } + + p_bfi = get_bfi_by_ca_guid(ca_guid); + if (p_bfi == NULL) { + BUS_PRINT(BUS_DBG_PNP, + ("%s() Null *p_bfi from ca_guid %I64x\n",__FUNCTION__,ca_guid)); + BUS_EXIT( BUS_DBG_PNP ); + return STATUS_NO_SUCH_DEVICE; + } + gp_port_mgr = p_bfi->p_port_mgr; + + BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x port_mgr %p\n", + __FUNCTION__, p_bfi->whoami, ca_guid, gp_port_mgr) ); + if (!gp_port_mgr) + return STATUS_NO_SUCH_DEVICE; + cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); status = bus_get_relations( &gp_port_mgr->port_list, ca_guid, p_irp ); cl_mutex_release( &gp_port_mgr->pdo_mutex ); @@ -493,15 +602,19 @@ port_mgr_get_bus_relations( static ib_api_status_t __port_was_hibernated( - IN ib_pnp_port_rec_t* p_pnp_rec ) + IN ib_pnp_port_rec_t* p_pnp_rec, + IN bus_filter_t* p_bfi ) { NTSTATUS status; - cl_list_item_t *p_list_item; + cl_list_item_t *p_list_item; bus_port_ext_t *p_port_ext; bus_pdo_ext_t *p_pdo_ext = NULL; size_t n_devs = 0; + port_mgr_t *gp_port_mgr = p_bfi->p_port_mgr; cl_qlist_t* p_pdo_list = &gp_port_mgr->port_list; + port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; + BUS_ENTER( BUS_DBG_PNP ); cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); @@ -521,9 +634,11 @@ __port_was_hibernated( break; } - BUS_TRACE( BUS_DBG_PNP, - ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n", - p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, + BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, " + "present %d, missing %d, hibernating %d, port_guid %I64x.\n", + p_bfi->whoami, + p_pdo_ext->cl_ext.vfptr_pnp_po->identity, + p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) ); } @@ -534,27 +649,33 @@ __port_was_hibernated( p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid ); if( !p_pdo_ext->h_ca ) { - BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n", - p_pnp_rec->p_ca_attr->ca_guid ) ); + BUS_TRACE( BUS_DBG_ERROR, + ("%s acquire_ca failed to find CA by guid %I64x\n", + p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) ); status = IB_INVALID_GUID; } else { p_pdo_ext->b_hibernating = FALSE; - p_pnp_rec->pnp_rec.context = p_pdo_ext; + + CL_ASSERT( p_ctx ); + p_ctx->p_pdo_ext = p_pdo_ext; // save for port_mgr_port_remove + status = IB_SUCCESS; p_port_ext = (bus_port_ext_t*)p_pdo_ext; - BUS_TRACE( BUS_DBG_PNP, - ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n", - p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, + BUS_TRACE( BUS_DBG_PNP, ("%s Found PDO for %s: PDO %p, ext %p, " + "present %d, missing %d, hibernating %d, port_guid %I64x.\n", + p_bfi->whoami, + p_pdo_ext->cl_ext.vfptr_pnp_po->identity, + p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) ); } } else { - BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid %I64x .\n", - p_pnp_rec->p_ca_attr->ca_guid ) ); + BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid %I64x .\n", + p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) ); status = IB_NOT_FOUND; } @@ -564,6 +685,69 @@ __port_was_hibernated( return status; } + +void +dump_pnp_port_rec( ib_pnp_port_rec_t* pr ) +{ + BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_port_rec_t* @ %p\nib_pnp_rec_t*:\n", + __FUNCTION__,pr)); + + + BUS_PRINT( BUS_DBG_PNP, (" Event %s\n", + ib_get_pnp_event_str(pr->pnp_rec.pnp_event) )); + + BUS_PRINT( BUS_DBG_PNP, (" pnp_context %p\n",pr->pnp_rec.pnp_context)); + BUS_PRINT( BUS_DBG_PNP, (" context %p\n",pr->pnp_rec.context)); + BUS_PRINT( BUS_DBG_PNP, (" guid %I64x\n",pr->pnp_rec.guid)); + BUS_PRINT( BUS_DBG_PNP, (" ca_guid %I64x\n",pr->pnp_rec.ca_guid)); + + if ( !pr->p_ca_attr ) { + BUS_PRINT( BUS_DBG_PNP, (" NULL *p_ca_attr ?\n")); + } + else { + BUS_PRINT( BUS_DBG_PNP, ("*p_ca_attr\n")); + BUS_PRINT( BUS_DBG_PNP, (" ca_guid 0x%I64x\n", + pr->p_ca_attr->ca_guid ) ); + } + if ( !pr->p_port_attr ) { + BUS_PRINT( BUS_DBG_PNP, (" NULL *p_port_attr?\n")); + } + else { + BUS_PRINT( BUS_DBG_PNP, ("*p_port_attr:\n")); + BUS_PRINT( BUS_DBG_PNP, (" port_guid 0x%I64x port_num %d\n", + pr->p_port_attr->port_guid, + pr->p_port_attr->port_num )); + } +} + +void +dump_pnp_iou_rec( ib_pnp_iou_rec_t* pr ) +{ + BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_iou_rec_t* @ %p\nib_pnp_rec_t*:\n", + __FUNCTION__,pr)); + + + BUS_PRINT( BUS_DBG_PNP, (" Event %s\n", + ib_get_pnp_event_str(pr->pnp_rec.pnp_event) )); + + BUS_PRINT( BUS_DBG_PNP, (" pnp_context %p\n",pr->pnp_rec.pnp_context)); + BUS_PRINT( BUS_DBG_PNP, (" context %p\n",pr->pnp_rec.context)); + BUS_PRINT( BUS_DBG_PNP, (" guid %I64x\n",pr->pnp_rec.guid)); + BUS_PRINT( BUS_DBG_PNP, (" ca_guid %I64x\n",pr->pnp_rec.ca_guid)); + + BUS_PRINT( BUS_DBG_PNP, ("pnp_iou_rec_t:\n" )); + BUS_PRINT( BUS_DBG_PNP, + (" guid 0x%I64x\n ca_guid %I64x\n chassis_guid %I64x\n", + pr->guid, pr->ca_guid, pr->chassis_guid )); + BUS_PRINT( BUS_DBG_PNP, + (" slot 0x%x\n vend_id 0x%x\n dev_id 0x%x revision 0x%x\n", + pr->slot, pr->vend_id, pr->dev_id, pr->revision )); + if ( pr->desc[0] ) { + BUS_PRINT( BUS_DBG_PNP, (" Desc %s\n",pr->desc )); + } +} + + ib_api_status_t port_mgr_port_add( IN ib_pnp_port_rec_t* p_pnp_rec ) @@ -573,18 +757,56 @@ port_mgr_port_add( uint8_t num_pdo; bus_port_ext_t *p_port_ext; ib_net16_t pdo_cnt; + bus_filter_t *p_bfi; + port_mgr_t *gp_port_mgr; + port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; + BUS_ENTER( BUS_DBG_PNP ); + CL_ASSERT( p_pnp_rec->p_ca_attr->ca_guid ); + + p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->p_ca_attr->ca_guid ); + if ( !p_bfi ) { + BUS_PRINT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n", + __FUNCTION__, p_pnp_rec->p_ca_attr->ca_guid ) ); + return IB_ERROR; + } + + /* + * Allocate a PNP context for this object. pnp_rec.context is obj unique. + */ + if ( !p_ctx ) { + p_ctx = cl_zalloc( sizeof(*p_ctx) ); + if( !p_ctx ) + { + BUS_PRINT(BUS_DBG_PNP, + ("%s(%s) ca_guid %I64x port(%d) BAD alloc PNP context\n", + __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, + p_pnp_rec->p_port_attr->port_num)); + return IB_ERROR; + } + p_ctx->p_bus_filter = p_bfi; + p_ctx->port_num = p_pnp_rec->p_port_attr->port_num; + p_pnp_rec->pnp_rec.context = p_ctx; + + BUS_PRINT(BUS_DBG_PNP, + ("%s(%s) ca_guid %I64x port %d ALLOC p_ctx @ %p\n", + __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, + p_pnp_rec->p_port_attr->port_num,p_ctx)); + } + gp_port_mgr = p_bfi->p_port_mgr; + if( !bus_globals.b_report_port_nic ) { BUS_EXIT( BUS_DBG_PNP ); return IB_NOT_DONE; } - /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but + /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but marks with a flag. So we first try to find an existing PDO for this port, - marked with this flag. If it was found, we turn off the flag and use this PDO */ - status = __port_was_hibernated(p_pnp_rec); + marked with this flag. If it was found, we turn off the flag and use + this PDO */ + status = __port_was_hibernated( p_pnp_rec, p_bfi ); if( status != IB_NOT_FOUND ) { BUS_EXIT( BUS_DBG_PNP ); @@ -600,73 +822,82 @@ port_mgr_port_add( for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++) { - /* Create the PDO for the new port device. */ - status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t), - NULL, FILE_DEVICE_CONTROLLER, - FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, &p_pdo[num_pdo] ); - if( !NT_SUCCESS( status ) ) - { - BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("IoCreateDevice returned %08x.\n", status) ); - return IB_ERROR; - } + /* Create the PDO for the new port device. */ + status = IoCreateDevice( bus_globals.p_driver_obj, + sizeof(bus_port_ext_t), + NULL, FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN | + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &p_pdo[num_pdo] ); + if( !NT_SUCCESS( status ) ) + { + BUS_TRACE_EXIT( BUS_DBG_ERROR, + ("IoCreateDevice returned %08x.\n", status) ); + return IB_ERROR; + } - /* Initialize the device extension. */ - cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo], bus_globals.dbg_lvl, - &vfptr_port_pnp, &vfptr_port_query_txt ); + /* Initialize the device extension. */ + cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo], + bus_globals.dbg_lvl, &vfptr_port_pnp, + &vfptr_port_query_txt ); - /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */ + /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */ p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE; p_port_ext = p_pdo[num_pdo]->DeviceExtension; - p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0; - p_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext; - p_port_ext->pdo.b_present = TRUE; - p_port_ext->pdo.b_reported_missing = FALSE; - p_port_ext->pdo.b_hibernating = FALSE; - p_port_ext->pdo.p_po_work_item = NULL; - BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n", - p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo], p_port_ext, p_port_ext->pdo.b_present, - p_port_ext->pdo.b_reported_missing ) ); - - /* Cache the CA GUID. */ - p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid; - - /* Take a reference on the parent HCA. */ + p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0; + p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext; + p_port_ext->pdo.b_present = TRUE; + p_port_ext->pdo.b_reported_missing = FALSE; + p_port_ext->pdo.b_hibernating = FALSE; + p_port_ext->pdo.p_po_work_item = NULL; + BUS_TRACE( BUS_DBG_PNP, + ("Created %s %s: PDO %p,ext %p, present %d, missing %d .\n", + p_bfi->whoami, + p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo], + p_port_ext, p_port_ext->pdo.b_present, + p_port_ext->pdo.b_reported_missing ) ); + + /* Cache the CA GUID. */ + p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid; + + /* Take a reference on the parent HCA. */ if(num_pdo > 0) { p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca; } else - p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid ); - if( !p_port_ext->pdo.h_ca ) - { + p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid ); + + if( !p_port_ext->pdo.h_ca ) + { BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo[num_pdo])); IoDeleteDevice( p_pdo[num_pdo]); - BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") ); - return IB_INVALID_GUID; - } + BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") ); + return IB_INVALID_GUID; + } p_port_ext->port_guid.guid = p_pnp_rec->p_port_attr->port_guid; - p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num; + p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num; p_port_ext->port_guid.pkey = IB_DEFAULT_PKEY; + p_port_ext->n_ifc_ref = 0; if(num_pdo > 0) { p_port_ext->port_guid.pkey = g_pkeys.pkey_array[num_pdo -1]; } - /* Store the device extension in the port vector for future queries. */ - cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); - cl_qlist_insert_tail( &gp_port_mgr->port_list, - &p_port_ext->pdo.list_item ); - cl_mutex_release( &gp_port_mgr->pdo_mutex ); - /* - * Set the context of the PNP event. The context is passed in for future - * events on the same port. - */ + /* Store the device extension in the port vector for future queries. */ + cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); + cl_qlist_insert_tail( &gp_port_mgr->port_list, + &p_port_ext->pdo.list_item ); + cl_mutex_release( &gp_port_mgr->pdo_mutex ); + + /* + * save the port_ext, as the context is passed in for future events on + * the same port. + */ if(num_pdo == 0) - p_pnp_rec->pnp_rec.context = p_port_ext; + p_ctx->p_pdo_ext = p_port_ext; } pkeys_enumerated = TRUE; @@ -674,9 +905,11 @@ port_mgr_port_add( IoInvalidateDeviceRelations( p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); +#if 0 // XXX /* Invalidate removal relations for the bus driver. */ - IoInvalidateDeviceRelations( - bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations ); + IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo, + RemovalRelations ); +#endif BUS_EXIT( BUS_DBG_PNP ); return IB_SUCCESS; @@ -697,10 +930,14 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) bus_port_ext_t *p_port_ext, *pkey_port_ext; DEVICE_OBJECT *p_pdo[MAX_NUM_PKEY]; bus_pdo_ext_t *p_pdo_ext = NULL; - cl_qlist_t* p_pdo_list = &gp_port_mgr->port_list; + cl_qlist_t* p_pdo_list; + bus_filter_t *p_bfi = &bus_filters[0];// pass in ca_guid? | all CA's? + port_mgr_t *gp_port_mgr; BUS_ENTER( BUS_DBG_PNP ); + gp_port_mgr = p_bfi->p_port_mgr; + p_pdo_list = &gp_port_mgr->port_list; p_port_ext = NULL; cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); @@ -720,18 +957,19 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) if (!p_port_ext) { BUS_TRACE_EXIT( BUS_DBG_ERROR, - ("No existed pdo found.\n") ); + ("No existing pdo found.\n") ); return CL_ERROR; } for (cnt = 0; cnt < pkeys->pkey_num; cnt++) { - /* Create the PDO for the new port device. */ - status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t), - NULL, FILE_DEVICE_CONTROLLER, - FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, &p_pdo[cnt] ); + status = IoCreateDevice( bus_globals.p_driver_obj, + sizeof(bus_port_ext_t), + NULL, FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN + | FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &p_pdo[cnt] ); if( !NT_SUCCESS( status ) ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, @@ -741,20 +979,22 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) /* Initialize the device extension. */ cl_init_pnp_po_ext( p_pdo[cnt], NULL, p_pdo[cnt], bus_globals.dbg_lvl, - &vfptr_port_pnp, &vfptr_port_query_txt ); + &vfptr_port_pnp, &vfptr_port_query_txt ); /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */ p_pdo[cnt]->Flags |= DO_BUS_ENUMERATED_DEVICE; pkey_port_ext = p_pdo[cnt]->DeviceExtension; pkey_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0; - pkey_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext; + pkey_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext; pkey_port_ext->pdo.b_present = TRUE; pkey_port_ext->pdo.b_reported_missing = FALSE; pkey_port_ext->pdo.b_hibernating = FALSE; pkey_port_ext->pdo.p_po_work_item = NULL; - BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n", - pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], pkey_port_ext, pkey_port_ext->pdo.b_present, + BUS_TRACE( BUS_DBG_PNP, + ("Created device for %s: PDO %p,ext %p, present %d, missing %d\n", + pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], + pkey_port_ext, pkey_port_ext->pdo.b_present, pkey_port_ext->pdo.b_reported_missing ) ); /* Cache the CA GUID. */ @@ -775,9 +1015,11 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) IoInvalidateDeviceRelations( p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); +#if 0 // XXX /* Invalidate removal relations for the bus driver. */ - IoInvalidateDeviceRelations( - bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations ); + IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo, + RemovalRelations ); +#endif BUS_EXIT( BUS_DBG_PNP ); return CL_SUCCESS; @@ -785,48 +1027,108 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) void port_mgr_port_remove( - IN ib_pnp_port_rec_t* p_pnp_rec ) + IN ib_pnp_port_rec_t* p_pnp_rec ) { bus_pdo_ext_t *p_ext; + port_mgr_t *gp_port_mgr; + bus_filter_t *p_bfi; + port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; BUS_ENTER( BUS_DBG_PNP ); - /* The PNP record's context is the port extension. */ - p_ext = p_pnp_rec->pnp_rec.context; + if ( !p_ctx ) { + BUS_EXIT( BUS_DBG_PNP ); + return; + } + + CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC ); + p_bfi = p_ctx->p_bus_filter; + CL_ASSERT( p_bfi ); + + BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x port_num %d port_mgr %p\n", + __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, + p_ctx->port_num, p_bfi->p_port_mgr)); + + /* in the process of device remove, port_mgr has been destroyed. + * cleanup allocated PNP port context; one per port. + * The issue is the PNP PORT_REMOVE event occurs after + * fdo_release_resources() completes. + */ + if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_port_mgr ) { + cl_free( p_ctx ); + p_pnp_rec->pnp_rec.context = NULL; + BUS_EXIT( BUS_DBG_PNP ); + return; + } + + gp_port_mgr = p_bfi->p_port_mgr; + + /* Within the PNP record's context is the port extension ptr; + * see port_was_hibernated(). + */ + p_ext = p_ctx->p_pdo_ext; CL_ASSERT( p_ext ); + CL_ASSERT(p_bfi == p_ext->p_parent_ext->bus_filter); +#if DBG // XXX + if (p_bfi != p_ext->p_parent_ext->bus_filter) { + BUS_PRINT(BUS_DBG_PNP, + ("%s() p_bfi(%p) != p_ext->bus_filter(%p) line %d file %s\n", + __FUNCTION__,p_bfi,p_ext->p_parent_ext->bus_filter, + __LINE__,__FILE__)); + } +#endif + /* * Flag the port PDO as no longer being present. We have to wait until * the PnP manager removes it to clean up. However, we do release the * reference on the CA object in order to allow the removal of the HCA * to proceed should it occur before the port's PDO is cleaned up. */ + if ( !p_ext->h_ca ) + { + BUS_TRACE( BUS_DBG_PNP, ("%s() %s NULL h_ca? p_ext %p\n", + __FUNCTION__, p_bfi->whoami, p_ext ) ); + return; + } + cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); CL_ASSERT( p_ext->h_ca ); if( p_ext->b_hibernating ) { - BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n", - 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, p_ext->b_hibernating ) ); + BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, " + "present %d, missing %d, hibernating %d .\n", + 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, + p_ext->b_hibernating ) ); goto hca_deref; } p_ext->b_present = FALSE; - BUS_TRACE( BUS_DBG_PNP, ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n", - 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 ) ); + p_ext->b_reported_missing = TRUE; + BUS_TRACE( BUS_DBG_PNP, + ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n", + 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 ) ); + +#if 0 // XXX /* Invalidate removal relations for the bus driver. */ - IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo, - RemovalRelations ); + IoInvalidateDeviceRelations( p_bfi->p_bus_ext->cl_ext.p_pdo, + RemovalRelations ); +#endif /* Invalidate bus relations for the HCA. */ IoInvalidateDeviceRelations( p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations ); + /* Free PNP context memory */ + cl_free( p_ctx ); + p_pnp_rec->pnp_rec.context = NULL; + hca_deref: deref_al_obj( &p_ext->h_ca->obj ); - p_ext->h_ca = NULL; cl_mutex_release( &gp_port_mgr->pdo_mutex ); BUS_EXIT( BUS_DBG_PNP ); @@ -850,7 +1152,9 @@ port_start( /* Notify the Power Manager that the device is started. */ PoSetPowerState( p_dev_obj, DevicePowerState, p_ext->dev_po_state ); *p_action = IrpComplete; + BUS_EXIT( BUS_DBG_PNP ); + return STATUS_SUCCESS; } @@ -869,6 +1173,9 @@ port_query_remove( p_ext = p_dev_obj->DeviceExtension; +BUS_PRINT( BUS_DBG_PNP, ("%s() %p->n_ifc_ref %d\n", + __FUNCTION__,p_ext,p_ext->n_ifc_ref )); + *p_action = IrpComplete; if( p_ext->n_ifc_ref ) { @@ -895,14 +1202,17 @@ port_release_resources( { bus_port_ext_t *p_ext; POWER_STATE po_state; + port_mgr_t *gp_port_mgr; BUS_ENTER( BUS_DBG_PNP ); p_ext = p_dev_obj->DeviceExtension; + gp_port_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_port_mgr; /* Remove this PDO from its list. */ cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); - BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n", p_dev_obj, p_ext) ); + BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n", + p_dev_obj, p_ext) ); cl_qlist_remove_item( &gp_port_mgr->port_list, &p_ext->pdo.list_item ); cl_mutex_release( &gp_port_mgr->pdo_mutex ); po_state.DeviceState = PowerDeviceD3; @@ -932,7 +1242,9 @@ port_remove( cl_set_pnp_state( &p_ext->pdo.cl_ext, NotStarted ); /* Don't delete the device. It may simply be disabled. */ *p_action = IrpComplete; - BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device still present: PDO %p, ext %p\n", p_dev_obj, p_ext) ); + BUS_TRACE_EXIT( BUS_DBG_PNP, + ("Device %s still present: PDO %p, ext %p\n", + p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_dev_obj, p_ext) ); return STATUS_SUCCESS; } @@ -941,7 +1253,10 @@ port_remove( /* Reset the state to RemovePending. Complib set it to Deleted. */ cl_rollback_pnp_state( &p_ext->pdo.cl_ext ); *p_action = IrpComplete; - BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device not reported missing yet: PDO %p, ext %p\n", p_dev_obj, p_ext) ); + BUS_TRACE_EXIT( BUS_DBG_PNP, + ("Device %s not reported missing yet: PDO %p, ext %p\n", + p_ext->pdo.cl_ext.vfptr_pnp_po->identity, + p_dev_obj, p_ext) ); return STATUS_SUCCESS; } @@ -955,8 +1270,9 @@ port_remove( p_irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest( p_irp, IO_NO_INCREMENT ); - BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n", - p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, p_dev_obj, p_ext ) ); + BUS_PRINT/*XXX TRACE*/( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n", + p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, + p_dev_obj, p_ext ) ); IoDeleteDevice( p_dev_obj ); *p_action = IrpDoNothing; @@ -1382,7 +1698,6 @@ port_query_ipoib_ifc( ipoib_ifc_data_t *p_ipoib_data; bus_port_ext_t *p_ext; const GUID *p_guid; - BUS_ENTER( BUS_DBG_PNP ); @@ -1455,6 +1770,9 @@ port_query_ipoib_ifc( p_ipoib_data->port_guid = p_ext->port_guid; p_ipoib_data->port_num = (uint8_t)p_ext->n_port; + BUS_TRACE_EXIT( BUS_DBG_PNP, + (" %p->n_ifc_ref %d\n",p_ext,p_ext->n_ifc_ref) ); //XXX + BUS_EXIT( BUS_DBG_PNP ); return STATUS_SUCCESS; } @@ -1472,9 +1790,7 @@ port_query_interface( BUS_ENTER( BUS_DBG_PNP ); -#pragma warning( push, 3 ) PAGED_CODE(); -#pragma warning( pop ) p_io_stack = IoGetCurrentIrpStackLocation( p_irp ); diff --git a/branches/winverbs/core/bus/kernel/bus_port_mgr.h b/branches/winverbs/core/bus/kernel/bus_port_mgr.h index 9bb70f00..1d0eb7f0 100644 --- a/branches/winverbs/core/bus/kernel/bus_port_mgr.h +++ b/branches/winverbs/core/bus/kernel/bus_port_mgr.h @@ -43,7 +43,6 @@ typedef struct _port_mgr { cl_obj_t obj; - ib_pnp_handle_t h_pnp; /* Handle for port PnP events */ /* Mutex protects both pointer vectors. */ cl_mutex_t pdo_mutex; @@ -54,8 +53,11 @@ typedef struct _port_mgr } port_mgr_t; +struct _bus_filter_instance; + ib_api_status_t create_port_mgr( + IN struct _bus_filter_instance *p_bfi, OUT port_mgr_t** const pp_port_mgr ); diff --git a/branches/winverbs/core/bus/kernel/etc/ib_iou.inf b/branches/winverbs/core/bus/kernel/etc/ib_iou.inf new file mode 100644 index 00000000..7ea47eda --- /dev/null +++ b/branches/winverbs/core/bus/kernel/etc/ib_iou.inf @@ -0,0 +1,127 @@ +; OpenIB InfiniBand Bus/IOU Driver. +; Copyright 2005 SilverStorm Technologies all Rights Reserved. +; Copyright 2006 Mellanox Technologies all Rights Reserved. + +[Version] +Signature="$Windows NT$" +Class=System +ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} +Provider=%OPENIB% +DriverVer=04/29/2008,1.1.0000.1085 + +; ================= Device Install section ===================== + +; 64-bit platforms also copy 32-bit user-mode binaries. +[DestinationDirs] +DefaultDestDir=%DIRID_DRIVERS% + +[SourceDisksNames.x86] +1=%DiskId%,,,"" + +[SourceDisksNames.amd64] +1=%DiskId%,,,"" + +[SourceDisksNames.ia64] +1=%DiskId%,,,"" + +[SourceDisksFiles.x86] +ibiou.sys=1 + +[SourceDisksFiles.amd64] +ibiou.sys=1 + +[SourceDisksFiles.ia64] +ibiou.sys=1 + +[Manufacturer] +%OPENIB% = GenIOU.DeviceSection,ntx86,ntamd64,ntia64 +%SST% = QLogicIOU.DeviceSection,ntx86,ntamd64,ntia64 + +[GenIOU.DeviceSection] +; empty since we don't support W9x/Me + +[GenIOU.DeviceSection.ntx86] +%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU + +[GenIOU.DeviceSection.ntamd64] +%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU + +[GenIOU.DeviceSection.ntia64] +%Iou.DeviceDesc% = Iou.DDInstall,IBA\IB_IOU + +[QLogicIOU.DeviceSection] +; empty since we don't support W9x/Me + +[QLogicIOU.DeviceSection.ntx86] +%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010 +%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058 +%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd +%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de +%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0 +%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1 + +[QLogicIOU.DeviceSection.ntamd64] +%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010 +%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058 +%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd +%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de +%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0 +%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1 + +[QLogicIOU.DeviceSection.ntia64] +%VFx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0060,IBA\V00066aP0010 +%VEx.DeviceDesc% = Iou.DDInstall,IBA\V00066aP0058 +%FVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00dd +%EVIC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00de +%BC2FC.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e0 +%BC2GE.DeviceDesc% = Iou.DDInstall,IBA\V00066aP00e1 + +[Iou.DDInstall.nt] +CopyFiles = Iou.CopyFiles + +[Iou.DDInstall.nt.Services] +AddService = ibiou,%SPSVCINST_ASSOCSERVICE%,Iou.ServiceInstall +;AddService = ibiou,,Iou.ServiceInstall + +[Iou.CopyFiles] +ibiou.sys + +; +; ============= Service Install section ============== +; + +[Iou.ServiceInstall] +DisplayName = %Iou.ServiceDesc% +ServiceType = %SERVICE_KERNEL_DRIVER% +StartType = %SERVICE_DEMAND_START% +ErrorControl = %SERVICE_ERROR_NORMAL% +ServiceBinary = %12%\ibiou.sys +AddReg = Iou.ParamsReg + +[Iou.ParamsReg] +HKR,"Parameters","DebugLevel",%REG_DWORD%,2 +HKR,"Parameters","DebugFlags",%REG_DWORD%,0x00ffffff + +[Strings] +OPENIB = "OpenFabrics Alliance" +SST = "SilverStorm Technologies" +VFx.DeviceDesc = "SilverStorm VFx" +VEx.DeviceDesc = "SilverStorm VEx" +FVIC.DeviceDesc = "SilverStorm FVIC" +EVIC.DeviceDesc = "SilverStorm EVIC" +BC2FC.DeviceDesc = "QLogic InfiniBand Fibre Channel Bridge Module" +BC2GE.DeviceDesc = "QLogic InfiniBand Ethernet Bridge Module" + +Iou.DeviceDesc = "InfiniBand I/O Unit" +Iou.ServiceDesc = "OpenIB InfiniBand I/O Unit Driver" +DiskId = "OpenIB InfiniBand Access Layer installation disk" +SPSVCINST_NULL = 0x0 +SPSVCINST_ASSOCSERVICE = 0x00000002 +SERVICE_KERNEL_DRIVER = 1 +SERVICE_DEMAND_START = 3 +SERVICE_ERROR_NORMAL = 1 +REG_DWORD = 0x00010001 +REG_DWORD_NO_CLOBBER = 0x00010003 +DIRID_SYSTEM = 11 +DIRID_DRIVERS = 12 +DIRID_SYSTEM_X86 = 16425 diff --git a/branches/winverbs/core/bus/kernel/etc/mthca.cdf b/branches/winverbs/core/bus/kernel/etc/mthca.cdf new file mode 100644 index 00000000..c7003df0 --- /dev/null +++ b/branches/winverbs/core/bus/kernel/etc/mthca.cdf @@ -0,0 +1,22 @@ +[CatalogHeader] +Name=mthca.cat +PublicVersion=0x0000001 +EncodingType=0x00010001 +CATATTR1=0x10010001:OSAttr:2:6.0 +[CatalogFiles] +mthca.inf=mthca.inf +mthca.sys=mthca.sys +mthcau.dll=mthcau.dll +mthcaud.dll=mthcaud.dll +mthca32.dll=mthca32.dll +mthca32d.dll=mthca32d.dll +ibal.dll=ibal.dll +ibald.dll=ibald.dll +complib.dll=complib.dll +complibd.dll=complibd.dll +cl32.dll=cl32.dll +cl32d.dll=cl32d.dll +ibal32.dll=ibal32.dll +ibal32d.dll=ibal32d.dll +ibbus.sys=ibbus.sys + diff --git a/branches/winverbs/core/bus/kernel/etc/mthca.inx b/branches/winverbs/core/bus/kernel/etc/mthca.inx new file mode 100644 index 00000000..c47375fe --- /dev/null +++ b/branches/winverbs/core/bus/kernel/etc/mthca.inx @@ -0,0 +1,318 @@ +; Mellanox Technologies InfiniBand HCAs. +; Copyright 2005 Mellanox Technologies all Rights Reserved. + +[Version] +Signature="$Windows NT$" +Class=InfiniBandController +ClassGUID={58517E00-D3CF-40c9-A679-CEE5752F4491} +Provider=%OFA% +; must be synchronized with MTHCA_DEV.H +DriverVer=05/19/2008,2.0.0000.1177 +CatalogFile=mthca.cat + +; ================= Destination directory section ===================== + +[DestinationDirs] +DefaultDestDir=%DIRID_DRIVERS% +MTHCA.UMCopyFiles=%DIRID_SYSTEM% +MTHCA.WOW64CopyFiles=%DIRID_SYSTEM_X86% +Ibal.UMCopyFiles=%DIRID_SYSTEM% +Ibal.WOW64CopyFiles=%DIRID_SYSTEM_X86% + +; ================= Class Install section ===================== + +[ClassInstall32] +AddReg=ClassAddReg + +[ClassAddReg] +HKR,,,0,"RDMA Channel Adapters" +HKR,,Icon,,-5 +HKR,,SilentInstall,,0 +HKR,,"UpperFilters",0x00010000,"ibbus" ; enable IBBUS/AL Filter driver loading. + + +; ================= Device Install section ===================== + +[SourceDisksNames.x86] +1=%DiskId%,,,"" + +[SourceDisksNames.amd64] +1=%DiskId%,,,"" + +[SourceDisksNames.ia64] +1=%DiskId%,,,"" + +[SourceDisksFiles] +mthca.sys=1,, +mthcau.dll=1,, +mthcaud.dll=1,, +ibal.dll=1,, +complib.dll=1,, +ibald.dll=1,, +complibd.dll=1,, +ibbus.sys=1,, + +[SourceDisksFiles.amd64] +mthca.sys=1,, +mthcau.dll=1,, +mthcaud.dll=1,, +mthca32.dll=1,, +mthca32d.dll=1,, +ibal.dll=1,, +ibald.dll=1,, +complib.dll=1,, +complibd.dll=1,, +cl32.dll=1,, +cl32d.dll=1,, +ibal32.dll=1,, +ibal32d.dll=1,, +ibbus.sys=1,, + +[SourceDisksFiles.ia64] +mthca.sys=1,, +mthcau.dll=1,, +mthcaud.dll=1,, +mthca32.dll=1,, +mthca32d.dll=1,, +ibal.dll=1,, +ibald.dll=1,, +complib.dll=1,, +complibd.dll=1,, +cl32.dll=1,, +cl32d.dll=1,, +ibal32.dll=1,, +ibal32d.dll=1,, +ibbus.sys=1,, + +[Manufacturer] +%MTL% = HCA.DeviceSection,ntx86,ntamd64,ntia64 + +[HCA.DeviceSection] +; empty since we don't support W9x/Me + +[HCA.DeviceSection.ntx86] +%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44 +%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45 +%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278 +%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279 +%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282 +%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C +%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D +%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274 +%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275 + +[HCA.DeviceSection.ntamd64] +%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44 +%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45 +%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278 +%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279 +%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282 +%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C +%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D +%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274 +%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275 + +[HCA.DeviceSection.ntia64] +%MT23108.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A44 +%MT23109.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5A45 +%MT25208.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6278 +%MT25209.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6279 +%MT25218.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6282 +%MT24204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8C +%MT24205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_5E8D +%MT25204.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6274 +%MT25205.DeviceDesc%=MTHCA.DDInstall, PCI\VEN_15B3&DEV_6275 + +[MTHCA.DDInstall.ntx86] +CopyFiles = MTHCA.CopyFiles +CopyFiles = MTHCA.UMCopyFiles +CopyFiles = Ibal.UMCopyFiles +CopyFiles = Ibbus.CopyFiles + +[MTHCA.DDInstall.ntamd64] +CopyFiles = MTHCA.CopyFiles +CopyFiles = MTHCA.UMCopyFiles +CopyFiles = MTHCA.WOW64CopyFiles +CopyFiles = Ibal.UMCopyFiles +CopyFiles = Ibal.WOW64CopyFiles +CopyFiles = Ibbus.CopyFiles + +[MTHCA.DDInstall.ntia64] +CopyFiles = MTHCA.CopyFiles +CopyFiles = MTHCA.UMCopyFiles +CopyFiles = MTHCA.WOW64CopyFiles +CopyFiles = Ibal.UMCopyFiles +CopyFiles = Ibal.WOW64CopyFiles +CopyFiles = Ibbus.CopyFiles + + +; ============== Services ============== + +[MTHCA.DDInstall.ntx86.Services] +AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog +AddService = ibbus,,Ibbus.ServiceInstall + +[MTHCA.DDInstall.ntamd64.Services] +AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog +AddService = ibbus,,Ibbus.ServiceInstall + +[MTHCA.DDInstall.ntia64.Services] +AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog +AddService = ibbus,,Ibbus.ServiceInstall + + +; ============= File Copy ============== + +[MTHCA.CopyFiles] +mthca.sys + +[MTHCA.UMCopyFiles] +mthcau.dll,,,2 +mthcaud.dll,,,2 + +[MTHCA.WOW64CopyFiles] +mthcau.dll,mthca32.dll,,2 +mthcaud.dll,mthca32d.dll,,2 + +[Ibal.UMCopyFiles] +ibal.dll,,,2 +ibald.dll,,,2 +complib.dll,,,2 +complibd.dll,,,2 + +[Ibal.WOW64CopyFiles] +ibal.dll,ibal32.dll,,2 +ibald.dll,ibal32d.dll,,2 +complib.dll,cl32.dll,,2 +complibd.dll,cl32d.dll,,2 + +[Ibbus.CopyFiles] +ibbus.sys + + +; +; ============= MTHCA Service Install section ============== +; + +[MTHCA.ServiceInstall] +DisplayName = %MTHCA.ServiceDesc% +ServiceType = %SERVICE_KERNEL_DRIVER% +StartType = %SERVICE_DEMAND_START% +ErrorControl = %SERVICE_ERROR_NORMAL% +ServiceBinary = %12%\mthca.sys +LoadOrderGroup = extended base +AddReg = MTHCA.ParamsReg + + +[MTHCA.EventLog] +AddReg = MTHCA.AddEventLogReg + +[MTHCA.AddEventLogReg] +HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\mthca.sys" +HKR, , TypesSupported, 0x00010001, 7 + +[MTHCA.ParamsReg] +HKR,"Parameters","DebugLevel",%REG_DWORD%,0x00000003 +HKR,"Parameters","DebugFlags",%REG_DWORD%,0x0000ffff +HKR,"Parameters","SkipTavorReset",%REG_DWORD%,0 +HKR,"Parameters","DisableTavorResetOnFailure",%REG_DWORD%,1 +HKR,"Parameters","TunePci",%REG_DWORD%,0 +HKR,"Parameters","ProcessorAffinity",%REG_DWORD%,0 +HKR,"Parameters","MaxDpcTimeUs",%REG_DWORD%,10000 +HKR,"Parameters","ProfileQpNum",%REG_DWORD%,0 +HKR,"Parameters","ProfileRdOut",%REG_DWORD%,0xffffffff +HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Flags",%REG_DWORD%,0xffff +HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Level",%REG_DWORD%,0x3 + + +; ============= IBBUS/AL Service Install section ============== +; + +[Ibbus.ServiceInstall] +DisplayName = %Ibbus.ServiceDesc% +ServiceType = %SERVICE_KERNEL_DRIVER% +StartType = %SERVICE_DEMAND_START% +ErrorControl = %SERVICE_ERROR_NORMAL% +ServiceBinary = %12%\ibbus.sys +LoadOrderGroup = PnP Filter +AddReg = Ibbus.ParamsReg +Dependencies = mthca + +[Ibbus.ParamsReg] +HKR,"Parameters","IbalDebugLevel",%REG_DWORD%,2 +HKR,"Parameters","IbalDebugFlags",%REG_DWORD%,0x00ffffff +HKR,"Parameters","SmiPollInterval",%REG_DWORD_NO_CLOBBER%,20000 +HKR,"Parameters","IocQueryTimeout",%REG_DWORD_NO_CLOBBER%,250 +HKR,"Parameters","IocQueryRetries",%REG_DWORD_NO_CLOBBER%,4 +HKR,"Parameters","IocPollInterval",%REG_DWORD_NO_CLOBBER%,30000 +HKR,"Parameters","DebugFlags",%REG_DWORD%,0x80000000 +HKR,"Parameters","ReportPortNIC",%REG_DWORD%,1 + + +; ============= Uninstall Section ============= + +[DefaultUninstall.ntx86] +DelFiles = MTHCA.CopyFiles +DelFiles = MTHCA.UMCopyFiles +DelReg = MTHCA.ParamsReg +DelReg = MTHCA.AddEventLogReg +DelReg = ClassAddReg +DelFiles = Ibal.UMCopyFiles + + +[DefaultUninstall.ntamd64] +DelFiles = MTHCA.CopyFiles +DelFiles = MTHCA.UMCopyFiles +DelFiles = MTHCA.WOW64CopyFiles +DelReg = MTHCA.ParamsReg +DelReg = MTHCA.AddEventLogReg +DelReg = ClassAddReg +DelFiles = Ibal.UMCopyFiles +DelFiles = Ibal.WOW64CopyFiles + + +[DefaultUninstall.ntia64] +DelFiles = MTHCA.CopyFiles +DelFiles = MTHCA.UMCopyFiles +DelFiles = MTHCA.WOW64CopyFiles +DelReg = MTHCA.ParamsReg +DelReg = MTHCA.AddEventLogReg +DelReg = ClassAddReg +DelFiles = Ibal.UMCopyFiles +DelFiles = Ibal.WOW64CopyFiles + + +[DefaultUninstall.Services] +DelService = Ibbus,%SPSVCINST_STOPSERVICE% +DelService = mthca,%SPSVCINST_STOPSERVICE% + + +[Strings] +IBClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}" +OFA = "OpenFabrics Alliance" +MTL="Mellanox Technologies Ltd." +MTHCA.ServiceDesc = "Driver for Mellanox InfiniHost Devices" +MT23108.DeviceDesc="InfiniHost (MT23108) - Mellanox InfiniBand HCA" +MT23109.DeviceDesc="InfiniHost (MT23109) - Mellanox InfiniBand HCA (burner device)" +MT25208.DeviceDesc="InfiniHost (MT25208) - Mellanox InfiniBand HCA for PCI Express" +MT25209.DeviceDesc="InfiniHost (MT25209) - Mellanox InfiniBand HCA for PCI Express (burner device)" +MT25218.DeviceDesc="InfiniHost III Ex (MT25218) - Mellanox InfiniBand HCA for PCI Express" +MT24204.DeviceDesc="InfiniHost III Lx (MT24204) - Mellanox InfiniBand HCA for PCI Express" +MT24205.DeviceDesc="InfiniHost III Lx (MT24205) - Mellanox InfiniBand HCA for PCI Express (burner device)" +MT25204.DeviceDesc="InfiniHost III Lx (MT25204) - Mellanox InfiniBand HCA for PCI Express" +MT25205.DeviceDesc="InfiniHost III Lx (MT25205) - Mellanox InfiniBand HCA for PCI Express (burner device)" +DiskId = "Mellanox InfiniBand HCA installation disk" +Ibbus.ServiceDesc = "InfiniBand Bus/Fabric/AL (Filter Driver)" +SPSVCINST_NULL = 0x0 +SPSVCINST_ASSOCSERVICE = 0x00000002 +SPSVCINST_STOPSERVICE = 0x00000200 +SERVICE_KERNEL_DRIVER = 1 +SERVICE_DEMAND_START = 3 +SERVICE_ERROR_NORMAL = 1 +REG_DWORD = 0x00010001 +REG_DWORD_NO_CLOBBER = 0x00010003 +REG_MULTI_SZ_APPEND = 0x00010008 +DIRID_SYSTEM = 11 +DIRID_DRIVERS = 12 +DIRID_SYSTEM_X86 = 16425 +