<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.3243" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT size=2><FONT size=1>
<P><FONT face=Arial><FONT size=2>[IBBUS] workaround for some problems with WHQL 
PnP test over IPoIB.<SPAN class=970004018-23112008> [mlnx: 
3535]</SPAN></FONT></FONT></P>
<P><FONT face=Arial size=2>This fix succeeds SurpriseRemoval and 3 of 4 
Rebalance tests for ConnectX.</FONT></P>
<P><FONT face=Arial size=2>Rebalance(FailRestart) still fails.</FONT></P>
<P></FONT></FONT><FONT face=Arial size=2></FONT> </P>
<P><FONT face=Arial size=2>Index: 
bus/kernel/bus_pnp.c<BR>===================================================================<BR>--- 
bus/kernel/bus_pnp.c (revision 1765)<BR>+++ 
bus/kernel/bus_pnp.c (working copy)<BR>@@ -1174,7 +1174,20 
@@<BR>   p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, 
list_item );<BR> <BR>   if( !p_pdo_ext->b_present 
)<BR>+  {<BR>+   // mark it missing to be removed in 
port_remove<BR>+   p_pdo_ext->b_reported_missing = 
TRUE;<BR>+   /*<BR>+    * We don't report a PDO 
that is no longer present.  This is how<BR>+    * the PDO 
will get cleaned up.<BR>+    */<BR>+   BUS_TRACE( 
BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, 
"<BR>+    "present %d, missing %d 
.\n",<BR>+    p_pdo_ext->cl_ext.vfptr_pnp_po->identity,<BR>+    p_pdo_ext->cl_ext.p_self_do, 
p_pdo_ext, 
p_pdo_ext->b_present,<BR>+    p_pdo_ext->b_reported_missing 

);<BR>    continue;<BR>+  }<BR>   <BR>   if( 
ca_guid && p_pdo_ext->ca_guid != ca_guid 
)<BR>    continue;<BR>@@ -1208,19 +1221,7 
@@<BR>   p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, 
list_item );<BR> <BR>   if( !p_pdo_ext->b_present 
)<BR>-  {<BR>-   /*<BR>-    * We don't 
report a PDO that is no longer present.  This is how<BR>-    
* the PDO will get cleaned up.<BR>-    
*/<BR>-   p_pdo_ext->b_reported_missing = 
TRUE;<BR>-   BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO 
%p, ext %p, "<BR>-    "present %d, missing %d 
.\n",<BR>-    p_pdo_ext->cl_ext.vfptr_pnp_po->identity,<BR>-    p_pdo_ext->cl_ext.p_self_do, 
p_pdo_ext, 
p_pdo_ext->b_present,<BR>-    p_pdo_ext->b_reported_missing 

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