[IBBUS] workaround for some problems with WHQL PnP test over IPoIB. [mlnx: 3535]
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 27 Nov 2008 13:37:02 +0000 (13:37 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 27 Nov 2008 13:37:02 +0000 (13:37 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1774 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

core/bus/kernel/bus_pnp.c
core/bus/kernel/bus_port_mgr.c
core/complib/kernel/cl_pnp_po.c

index c5cb437..e6b3875 100644 (file)
@@ -1174,7 +1174,20 @@ bus_get_relations(
                p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
 \r
                if( !p_pdo_ext->b_present )\r
+               {\r
+                       // mark it missing to be removed in port_remove\r
+                       p_pdo_ext->b_reported_missing = TRUE;\r
+                       /*\r
+                        * We don't report a PDO that is no longer present.  This is how\r
+                        * the PDO will get cleaned up.\r
+                        */\r
+                       BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, "\r
+                               "present %d, missing %d .\n",\r
+                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+                               p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present,\r
+                               p_pdo_ext->b_reported_missing ) );\r
                        continue;\r
+               }\r
                \r
                if( ca_guid && p_pdo_ext->ca_guid != ca_guid )\r
                        continue;\r
@@ -1208,19 +1221,7 @@ bus_get_relations(
                p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
 \r
                if( !p_pdo_ext->b_present )\r
-               {\r
-                       /*\r
-                        * We don't report a PDO that is no longer present.  This is how\r
-                        * the PDO will get cleaned up.\r
-                        */\r
-                       p_pdo_ext->b_reported_missing = TRUE;\r
-                       BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, "\r
-                               "present %d, missing %d .\n",\r
-                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
-                               p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present,\r
-                               p_pdo_ext->b_reported_missing ) );\r
                        continue;\r
-               }\r
 \r
                if( ca_guid && p_pdo_ext->ca_guid != ca_guid )\r
                        continue;\r
index b3c7026..3742f71 100644 (file)
@@ -864,6 +864,10 @@ port_mgr_port_add(
                        return IB_ERROR;\r
                }\r
 \r
+               /* clean the extension (must be before initializing) */\r
+               p_port_ext = p_pdo[num_pdo]->DeviceExtension;\r
+               memset( p_port_ext, 0, sizeof(bus_port_ext_t) );\r
+\r
                /* Initialize the device extension. */\r
                cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo],\r
                                                        bus_globals.dbg_lvl, &vfptr_port_pnp,\r
@@ -872,7 +876,6 @@ port_mgr_port_add(
                /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
                p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
 \r
-               p_port_ext = p_pdo[num_pdo]->DeviceExtension;\r
                p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
                p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
                p_port_ext->pdo.b_present = TRUE;\r
@@ -923,7 +926,7 @@ port_mgr_port_add(
                 * Set the context of the PNP event. The context is passed in for future\r
                 * events on the same port.\r
                 */\r
-               if(num_pdo == 0)\r
+               if(num_pdo == 0) \r
                        p_ctx->p_pdo_ext = p_port_ext;\r
        }\r
 \r
@@ -1237,8 +1240,6 @@ port_mgr_port_remove(
        }\r
 \r
        p_ext->b_present = FALSE;\r
-       p_ext->b_reported_missing = TRUE;\r
-\r
        BUS_TRACE( BUS_DBG_PNP,\r
                ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",\r
                p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext,\r
@@ -1346,6 +1347,13 @@ port_release_resources(
        p_ext = p_dev_obj->DeviceExtension;\r
        p_port_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_port_mgr;\r
 \r
+       /* skip releasing resources if PDO has not been yet reported missing */\r
+       if (!p_ext->pdo.b_reported_missing) {\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP, ("PDO is not yet reported missing - skip the removing port from vector: PDO %p, ext %p\n",\r
+                       p_dev_obj, p_ext) );\r
+               return;\r
+       }\r
+\r
        /* Remove this PDO from its list. */\r
        cl_mutex_acquire( &p_port_mgr->pdo_mutex );\r
        BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n",\r
@@ -1432,8 +1440,20 @@ port_surprise_remove(
        UNUSED_PARAM( p_irp );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
-       p_ext->pdo.b_present = FALSE;\r
-       p_ext->pdo.b_reported_missing = TRUE;\r
+       //\r
+       // Setting 2 folloeing flags seems like the right behaviour\r
+       // according to DDK, but it causes \r
+       // WHQL PnP SurpriseRemoval test to fail\r
+       // So, as a work around, they are disabled for now.\r
+       // The best solution is to rewrite all the drivers\r
+       // to WDF model, hoping it will handle right all PnP/Power issues\r
+       //\r
+//     p_ext->pdo.b_present = FALSE;\r
+//     p_ext->pdo.b_reported_missing = TRUE;\r
+       if (!p_ext->pdo.b_reported_missing) {\r
+               // we have not yet reported the device absence \r
+               cl_rollback_pnp_state( &p_ext->pdo.cl_ext );\r
+       }\r
        BUS_TRACE( BUS_DBG_PNP, ("%s: PDO %p, ext %p, present %d, missing %d .\n",\r
                p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, \r
                p_ext, p_ext->pdo.b_present, p_ext->pdo.b_reported_missing ) );\r
index 972937b..17302f7 100644 (file)
@@ -213,6 +213,9 @@ cl_pnp(
        {\r
                CL_TRACE_EXIT( CL_DBG_ERROR, p_ext->dbg_lvl, \r
                        ("IoAcquireRemoveLock returned %08x.\n", status) );\r
+               p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, \r
+                       ("Minor function %x for %s\n", p_io_stack->MinorFunction, p_ext->vfptr_pnp_po->identity) );\r
                p_irp->IoStatus.Status = status;\r
                IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
                return status;\r
@@ -243,7 +246,7 @@ cl_pnp(
 \r
        case IRP_MN_CANCEL_STOP_DEVICE:\r
                CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, \r
-                       ("IRP_MN_START_DEVICE for %s\n", p_ext->vfptr_pnp_po->identity) );\r
+                       ("IRP_MN_CANCEL_STOP_DEVICE for %s\n", p_ext->vfptr_pnp_po->identity) );\r
                status = __cancel_stop( p_dev_obj, p_irp, &action );\r
                break;\r
 \r
@@ -394,6 +397,8 @@ cl_pnp(
        {\r
        case IrpPassDown:\r
                p_irp->IoStatus.Status = status;\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IrpPassDown: passing down to PDO %p, ext %p, status %#x\n",\r
+                       p_ext->p_next_do, p_ext, p_irp->IoStatus.Status) );\r
                IoCopyCurrentIrpStackLocationToNext( p_irp );\r
                status = IoCallDriver( p_ext->p_next_do, p_irp );\r
                break;\r
@@ -402,23 +407,28 @@ cl_pnp(
                p_irp->IoStatus.Status = status;\r
 \r
        case IrpIgnore:\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IrpSkip/IrpIgnore: skipping down to PDO %p, ext %p, status %#x\n",\r
+                       p_ext->p_next_do, p_ext, p_irp->IoStatus.Status) );\r
                IoSkipCurrentIrpStackLocation( p_irp );\r
                status = IoCallDriver( p_ext->p_next_do, p_irp );\r
                break;\r
 \r
        case IrpComplete:\r
                p_irp->IoStatus.Status = status;\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IrpComplete: complete IRP with status %#x\n",\r
+                       p_irp->IoStatus.Status) );\r
                IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
                break;\r
 \r
        case IrpDoNothing:\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IrpDoNothing: do nothing\n") );\r
                break;\r
        }\r
 \r
        if( action != IrpDoNothing )\r
                IoReleaseRemoveLock( &p_ext->remove_lock, p_irp );\r
 \r
-       CL_EXIT( CL_DBG_PNP, p_ext->dbg_lvl );\r
+       CL_TRACE_EXIT( CL_DBG_PNP, p_ext->dbg_lvl, ("returned with status %#x\n", status) );\r
        return status;\r
 }\r
 \r
@@ -444,8 +454,10 @@ __start(
         * If we get the start request when we're already started, don't \r
         * re-initialize the stop lock.\r
         */\r
-       if( p_ext->last_pnp_state != Started )\r
+       if( p_ext->last_pnp_state != Started ) {\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IoInitializeRemoveLock: stop_lock %p[\n", &p_ext->stop_lock));\r
                IoInitializeRemoveLock( &p_ext->stop_lock, 'dtci', 0, 1000 );\r
+       }\r
 \r
        CL_EXIT( CL_DBG_PNP, p_ext->dbg_lvl );\r
        return status;\r
@@ -493,7 +505,12 @@ __query_stop(
        if( p_ext->last_pnp_state == Started )\r
        {\r
                /* Acquire the lock so we can release and wait. */\r
-               IoAcquireRemoveLock( &p_ext->stop_lock, p_irp );\r
+               status = IoAcquireRemoveLock( &p_ext->stop_lock, p_irp );\r
+               if( !NT_SUCCESS( status ) )\r
+               {\r
+                       CL_TRACE( CL_DBG_ERROR, p_ext->dbg_lvl, \r
+                               ("IoAcquireRemoveLock returned %08x. Continue anyway ...\n", status) );\r
+               }\r
                /* Wait for all IO operations to complete. */\r
                IoReleaseRemoveLockAndWait( &p_ext->stop_lock, p_irp );\r
        }\r
@@ -563,14 +580,28 @@ __cancel_stop(
        if( p_ext->last_pnp_state == Started )\r
        {\r
                /*\r
-                * Re-initialize the remove lock before rolling back the PnP\r
+                * Re-initialize the stop lock before rolling back the PnP\r
                 * state so that there's no contention while it's uninitialized.\r
                 */\r
+               CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IoInitializeRemoveLock: stop_lock %p[\n", &p_ext->stop_lock));\r
                IoInitializeRemoveLock( &p_ext->stop_lock, 'dtci', 0, 1000 );\r
+#if 0          \r
+               // leo: it seems like a bug, because it can never get released\r
+               {\r
                /* \r
                 * Acquire the stop lock to allow releasing and waiting when stopping.\r
                 */\r
-               IoAcquireRemoveLock( &p_ext->stop_lock, NULL );\r
+                       NTSTATUS                        status1;\r
+                       CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IoAcquireRemoveLock: stop_lock %p[\n", &p_ext->stop_lock));\r
+                       status1 = IoAcquireRemoveLock( &p_ext->stop_lock, NULL );\r
+                       if( !NT_SUCCESS( status1 ) )\r
+                       {\r
+                               CL_TRACE( CL_DBG_ERROR, p_ext->dbg_lvl, \r
+                                       ("IoAcquireRemoveLock returned %08x. Continue anyway ...\n", status) );\r
+                       }\r
+                       CL_TRACE( CL_DBG_PNP, p_ext->dbg_lvl, ("IoAcquireRemoveLock: stop_lock ]\n"));\r
+               }\r
+#endif         \r
        }\r
 \r
        /* Return to the previous PnP state. */\r
@@ -653,7 +684,10 @@ __remove(
        ASSERT( p_ext->pnp_state == NotStarted ||\r
                p_ext->pnp_state == Started ||\r
                p_ext->pnp_state == RemovePending ||\r
-               p_ext->pnp_state == SurpriseRemoved );\r
+               p_ext->pnp_state == SurpriseRemoved ||\r
+               // it can be on this state if IRP_MN_START_DEVICE failed\r
+               // pnpdtest /rebalance FailRestart creates this situation\r
+               p_ext->pnp_state == Stopped);\r
 \r
        /* Set the device state. */\r
        cl_set_pnp_state( p_ext, Deleted );\r