[ofw] ibbus filter driver patch 5/18 - bus_pnp.c
Smith, Stan
stan.smith at intel.com
Mon Aug 18 14:43:44 PDT 2008
Signed-off by: Stan Smith (stan.smith at intel.com)
Having problems with Intel mailer, hence formatting of patch is incorrect, see attached patch file.
diff -Naur --exclude-from=./SKIP kernel-svn/bus_pnp.c kernel/bus_pnp.c
--- kernel-svn/bus_pnp.c 2008-08-06 14:09:36.000000000 -0700
+++ kernel/bus_pnp.c 2008-08-18 09:53:18.289812500 -0700
@@ -27,7 +27,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
- * $Id: bus_pnp.c 744 2007-07-31 19:04:15Z leonidk $
+ * $Id: bus_pnp.c 1484 2008-08-18 15:49:36Z stansmith $
*/
@@ -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 @@
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 @@
#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 @@
cl_irp_skip,
cl_irp_skip,
cl_do_sync_pnp,
+ fdo_query_bus_relations,
cl_irp_ignore,
- cl_irp_ignore,
- fdo_query_remove_relations,
+ cl_irp_skip,
cl_irp_ignore,
cl_irp_ignore,
cl_irp_ignore,
@@ -170,86 +180,133 @@
{
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_TRACE_EXIT( 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) )
- {
- BUS_TRACE_EXIT( BUS_DBG_ERROR,
- ("Failed to create bus root FDO device.\n") );
- return status;
- }
- IoDeleteSymbolicLink( &dos_name );
- status = IoCreateSymbolicLink( &dos_name, &dev_name );
- if( !NT_SUCCESS(status) )
+ /* if 1st Bus Filter Instance, then create device names for user ioctl */
+ if ( ic == 1 )
{
- IoDeleteDevice( p_dev_obj );
- BUS_TRACE_EXIT( BUS_DBG_ERROR,
- ("Failed to create symlink for dos name.\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_PRINT( 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_PRINT( 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 );
+ if( !NT_SUCCESS(status) )
+ {
+ BUS_PRINT( 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;
+ BUS_PRINT( BUS_DBG_ERROR, ("IoAttachToDeviceStack failed.\n") );
+ 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 );
IoDeleteDevice( p_dev_obj );
- BUS_TRACE_EXIT( BUS_DBG_ERROR,
+ BUS_PRINT( 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,
+ BUS_PRINT( 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 0x%x\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 +319,13 @@
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 +336,24 @@
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 +362,7 @@
}
/* 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 +370,18 @@
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;
}
@@ -322,11 +393,17 @@
OUT cl_irp_action_t* const p_action )
{
bus_fdo_ext_t *p_ext;
+ bus_filter_t *p_bfi;
BUS_ENTER( BUS_DBG_PNP );
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 ) );
+
if( p_ext->n_ci_ifc_ref )
{
/*
@@ -344,9 +421,23 @@
return STATUS_UNSUCCESSFUL;
}
+ /* remove port & iou managers */
+ p_bfi = p_ext->bus_filter;
+ CL_ASSERT( p_bfi );
+
+ //TODO: Fail outstanding I/O operations.
+
+ if ( p_ext->p_port_mgr && p_bfi->p_port_mgr )
+ cl_obj_destroy( &p_ext->p_port_mgr->obj );
+
+ if ( p_ext->p_iou_mgr && p_bfi->p_iou_mgr )
+ cl_obj_destroy( &p_ext->p_iou_mgr->obj );
+
+
*p_action = IrpSkip;
/* The FDO driver must set the status even when passing down. */
p_irp->IoStatus.Status = STATUS_SUCCESS;
+
BUS_EXIT( BUS_DBG_PNP );
return STATUS_SUCCESS;
}
@@ -363,30 +454,53 @@
{
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();
+
+ p_bfi = p_ext->bus_filter;
+ CL_ASSERT( p_bfi );
//TODO: Fail outstanding I/O operations.
+ if ( p_ext->p_port_mgr && p_bfi->p_port_mgr )
+ cl_obj_destroy( &p_ext->p_port_mgr->obj );
+
+ if ( p_ext->p_iou_mgr && p_bfi->p_iou_mgr )
+ cl_obj_destroy( &p_ext->p_iou_mgr->obj );
+
+ 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 );
}
@@ -432,25 +546,48 @@
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 )
{
NTSTATUS status;
+ bus_fdo_ext_t *p_ext;
+ bus_filter_t *p_bfi;
BUS_ENTER( BUS_DBG_PNP );
- UNUSED_PARAM( p_dev_obj );
+ p_ext = p_dev_obj->DeviceExtension;
- status = port_mgr_get_bus_relations( 0, p_irp );
- if( status == STATUS_SUCCESS ||
- status == STATUS_NO_SUCH_DEVICE )
+ if ( !p_ext->bus_filter )
{
- status = iou_mgr_get_bus_relations( 0, p_irp );
+ /* BFI has already been released */
+ *p_action = IrpComplete;
+ BUS_TRACE_EXIT( BUS_DBG_PNP, ("%s() NULL BFI\n", __FUNCTION__) );
+ return STATUS_SUCCESS;
}
- if( status == STATUS_NO_SUCH_DEVICE )
+
+ p_bfi = p_ext->bus_filter;
+ CL_ASSERT( p_bfi->magic == BFI_MAGIC );
+
+ 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 )
{
@@ -700,22 +837,18 @@
IN const net64_t ca_guid,
IN IRP* const p_irp )
{
- NTSTATUS status;
-
BUS_ENTER( BUS_DBG_PNP );
+ UNUSED_PARAM( ca_guid );
+ UNUSED_PARAM( p_irp );
- /* TODO: For IOUs, filter relations based on multi-HCA support. */
- status = port_mgr_get_bus_relations( ca_guid, p_irp );
- if( status == STATUS_SUCCESS ||
- status == STATUS_NO_SUCH_DEVICE )
- {
- status = iou_mgr_get_bus_relations( ca_guid, p_irp );
- }
- if( status == STATUS_NO_SUCH_DEVICE )
- status = STATUS_SUCCESS;
+ /*
+ * Now that ibbus is in the same device stack as the HCA driver, skip
+ * returning relations here as ibbus has already done the deed.
+ * This interface remains to minimize changes to HCA drivers for now.
+ */
BUS_EXIT( BUS_DBG_PNP );
- return status;
+ return STATUS_SUCCESS;
}
@@ -777,9 +910,7 @@
BUS_ENTER( BUS_DBG_PNP );
-#pragma warning( push, 3 )
PAGED_CODE();
-#pragma warning( pop )
p_io_stack = IoGetCurrentIrpStackLocation( p_irp );
@@ -971,7 +1102,8 @@
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 +1205,18 @@
* 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 +1226,256 @@
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 );
+ 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 );
+ 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;
+#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
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bus_pnp.c.pat
Type: application/octet-stream
Size: 22543 bytes
Desc: bus_pnp.c.pat
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/4a963370/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bus_pnp.c
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/4a963370/attachment.c>
More information about the ofw
mailing list