[ofw] ibbus filter driver patch 3/18 - bus_iou_mgr.c

Smith, Stan stan.smith at intel.com
Mon Aug 18 14:43:25 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_iou_mgr.c kernel/bus_iou_mgr.c
--- kernel-svn/bus_iou_mgr.c    2008-07-08 12:01:36.000000000 -0700
+++ kernel/bus_iou_mgr.c        2008-08-18 09:43:05.861086700 -0700
@@ -27,7 +27,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: bus_iou_mgr.c 931 2008-01-31 09:20:41Z leonidk $
+ * $Id: bus_iou_mgr.c 1484 2008-08-18 15:49:36Z stansmith $
  */


@@ -83,7 +83,12 @@
 }      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 @@
        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 @@
  */
 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 @@

        /* 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 @@
                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;
@@ -345,20 +356,34 @@
        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 +397,30 @@
 {
        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 +432,10 @@
                {
                        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 +447,25 @@
                        /* 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));
+
                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 +474,26 @@
  * 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 IOU PNP events once */
+       ExAcquireFastMutexUnsafe(&ControlMutex);
+       if ( !bus_globals.h_pnp_iou ) {
+               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 );
+       }
+       ExReleaseFastMutexUnsafe(&ControlMutex);

-       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 +507,11 @@
 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 +521,11 @@

        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 +542,47 @@
        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 +594,17 @@

 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;
-       cl_qlist_t*             p_pdo_list = &gp_iou_mgr->iou_list;
+       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 +626,11 @@
                        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 ) );
        }
@@ -538,27 +641,31 @@
                p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->ca_guid );
                if( !p_pdo_ext->h_ca )
                {
-                       BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n",
+                       BUS_TRACE( BUS_DBG_ERROR,
+                               ("acquire_ca failed to find CA by guid %I64x\n",
                                p_pnp_rec->ca_guid ) );
                        status = IB_INVALID_GUID;
                }
                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 +682,48 @@
        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_TRACE_EXIT( 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_TRACE_EXIT(BUS_DBG_PNP, ("%s(%s) ca_guid %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 +732,11 @@

        /* 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 +746,19 @@

        /* 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 +771,7 @@
        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 +787,20 @@

        /* 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 );
-
-       /* Invalidate removal relations for the bus driver. */
-       IoInvalidateDeviceRelations(
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );
+                       p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );

        BUS_EXIT( BUS_DBG_PNP );

@@ -670,13 +813,50 @@
        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 PNP record's context is the IOU 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 +864,42 @@
         * 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_EXIT( 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;

-       /* Invalidate removal relations for the bus driver. */
-       IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,
-               RemovalRelations );
+       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 ) );

        /* 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 +969,12 @@
 {
        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 );
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bus_iou_mgr.c.pat
Type: application/octet-stream
Size: 20489 bytes
Desc: bus_iou_mgr.c.pat
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/37931720/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bus_iou_mgr.c
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/37931720/attachment.c>


More information about the ofw mailing list