[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