<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.18812"></HEAD>
<BODY>
<DIV dir=ltr align=left><SPAN class=364404415-14092009><FONT color=#0000ff 
size=2 face=Arial>Hello Leonid?</FONT></SPAN></DIV><BR>
<DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
<HR tabIndex=-1>
<FONT size=2 face=Tahoma><B>From:</B> Smith, Stan <BR><B>Sent:</B> Tuesday, 
September 08, 2009 12:08 PM<BR><B>To:</B> 'Leonid Keller'; 
ofw@lists.openfabrics.org<BR><B>Subject:</B> RE: [ofw] patch: [ibbus,hw] add 
power down support for IBBUS<BR></FONT><BR></DIV>
<DIV></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>Hello,</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>  To what degree and what types of testing has this patch 
under gone?</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>The '#if 0' blocks should be cleaned up. </FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>I'd like to include this in WinOF 2.1 as on occasion there are 
BSOD during shutdown which I have been able to attribute to IBAL accessing the 
HCA driver after HCA has powered down.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT face=Arial><FONT 
color=#0000ff><FONT size=2>Is this patch close to being ready for 2.1 ?<SPAN 
class=364404415-14092009> </SPAN></FONT></FONT></FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT face=Arial><FONT 
color=#0000ff><FONT size=2><SPAN 
class=364404415-14092009> </SPAN></FONT></FONT></FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>Your thoughts?</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>thanks,</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=556440419-08092009><FONT color=#0000ff 
size=2 face=Arial>stan.</FONT></SPAN></DIV><BR>
<DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
<HR tabIndex=-1>
<FONT size=2 face=Tahoma><B>From:</B> ofw-bounces@lists.openfabrics.org 
[mailto:ofw-bounces@lists.openfabrics.org] <B>On Behalf Of </B>Leonid 
Keller<BR><B>Sent:</B> Sunday, September 06, 2009 6:04 PM<BR><B>To:</B> 
ofw@lists.openfabrics.org<BR><B>Subject:</B> [ofw] patch: [ibbus,hw] add power 
down support for IBBUS<BR></FONT><BR></DIV>
<DIV></DIV>
<DIV><SPAN class=335570213-06092009><FONT size=2>
<P><FONT size=1 face=Arial>Mellanox HW doesn't support neither S<SPAN 
class=940575800-07092009>t</SPAN>andby nor hibernation.</FONT></P>
<P><FONT size=1 face=Arial>To simulate such support, low-level driver resets HCA 
on power down and starts it up on power up.</FONT></P>
<P><FONT size=1 face=Arial>IBBUS, continuing to work with HCA, produces 
BSOD<SPAN class=940575800-07092009>s</SPAN>.</FONT></P>
<P><FONT face=Arial><FONT size=1>This patch deregisters HCA from IBAL on power 
down and re-registers it on power up<SPAN class=940575800-07092009>, thus 
preventing crashes on power down.</SPAN></FONT></FONT></P></FONT></SPAN></DIV>
<DIV><SPAN class=335570213-06092009><FONT size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=335570213-06092009><FONT size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=335570213-06092009><FONT size=2>Index: 
core/bus/kernel/bus_driver.h<BR>===================================================================<BR>--- 
core/bus/kernel/bus_driver.h (revision 2421)<BR>+++ 
core/bus/kernel/bus_driver.h (working copy)<BR>@@ -125,6 +125,17 
@@<BR> <BR>  struct _bus_filter_instance 
*bus_filter;<BR> <BR>+ /* flag, indicating that FDO resources have 
been released 
*/<BR>+ boolean_t    ca_registered;<BR>+ /* 
current device power state 
*/<BR>+ DEVICE_POWER_STATE  device_power_state;<BR>+ /* 
current system  power state 
*/<BR>+ SYSTEM_POWER_STATE  system_power_state;<BR>+ /* work 
item for power operations 
*/<BR>+ PIO_WORKITEM   p_po_work_item;<BR>+ /* current 
PnP state */<BR>+ PNP_DEVICE_STATE  pnp_state; /* state for PnP 
Manager */<BR>+<BR> } bus_fdo_ext_t;<BR> <BR> <BR>Index: 
core/bus/kernel/bus_iou_mgr.c<BR>===================================================================<BR>--- 
core/bus/kernel/bus_iou_mgr.c (revision 2421)<BR>+++ 
core/bus/kernel/bus_iou_mgr.c (working copy)<BR>@@ -1658,7 +1658,9 
@@<BR> <BR>  if ((p_io_stack->Parameters.Power.Type == 
SystemPowerState) 
&&<BR>   (p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemHibernate 
||<BR>-  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping1 
))<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping1 || 
<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping2 || 
<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping3 ))<BR>  {<BR>   BUS_TRACE( 
BUS_DBG_POWER, ("Setting b_hibernating flag for PDO %p \n", 
p_dev_obj));<BR>   p_ext->b_hibernating = TRUE;<BR>Index: 
core/bus/kernel/bus_pnp.c<BR>===================================================================<BR>--- 
core/bus/kernel/bus_pnp.c (revision 2421)<BR>+++ 
core/bus/kernel/bus_pnp.c (working copy)<BR>@@ -49,6 +49,7 
@@<BR> #include "iba/ib_cm_ifc.h"<BR> #include 
"al_cm_cep.h"<BR> #include "al_mgr.h"<BR>+#include 
"bus_ev_log.h"<BR> <BR> <BR> /* Interface names are generated by 
IoRegisterDeviceInterface. */<BR>@@ -113,6 +114,13 
@@<BR>  IN    IO_STACK_LOCATION* 
const p_io_stack );<BR> <BR> static 
NTSTATUS<BR>+fdo_query_pnp_state(<BR>+ IN    DEVICE_OBJECT* 
const  p_dev_obj,<BR>+ IN    IRP* 
const     p_irp, 
<BR>+  OUT   cl_irp_action_t* const  p_action 
);<BR>+<BR>+<BR>+static 
NTSTATUS<BR> fdo_query_interface(<BR>  IN    DEVICE_OBJECT* 
const  p_dev_obj,<BR>  IN    IRP* 
const     p_irp, <BR>@@ -150,8 +158,8 
@@<BR>  cl_do_sync_pnp,<BR>  cl_irp_skip,<BR>  fdo_query_capabilities,<BR>+ fdo_query_pnp_state,<BR>  cl_irp_skip,<BR>- cl_irp_skip,<BR>  cl_do_sync_pnp,<BR>  fdo_query_bus_relations,<BR>  cl_irp_ignore,<BR>@@ 
-245,8 +253,7 @@<BR>  }<BR> <BR>  p_ext = 
p_dev_obj->DeviceExtension;<BR>- p_ext->n_al_ifc_ref = 
0;<BR>- p_ext->n_ci_ifc_ref = 0;<BR>+ cl_memclr( p_ext, 
sizeof(bus_fdo_ext_t) );<BR> <BR>  p_next_do = 
IoAttachDeviceToDeviceStack( p_dev_obj, p_pdo );<BR>  if( !p_next_do 
)<BR>@@ -383,7 +390,54 @@<BR>  return 
status;<BR> }<BR> <BR>+<BR> static 
NTSTATUS<BR>+__register_ca(<BR>+ IN     DEVICE_OBJECT* 
const p_dev_obj<BR>+ )<BR>+{<BR>+ NTSTATUS  status;<BR>+ bus_fdo_ext_t *p_ext;<BR>+ ib_api_status_t ib_status;<BR>+ bus_filter_t *p_bfi;<BR>+<BR>+ BUS_ENTER( 
BUS_DBG_PNP );<BR>+<BR>+ p_ext = 
p_dev_obj->DeviceExtension;<BR>+ p_bfi = 
p_ext->bus_filter;<BR>+<BR>+ /* get HCA verbs interface 
*/<BR>+ status = __get_ifc( p_dev_obj, 
&GUID_RDMA_INTERFACE_VERBS,<BR>+      sizeof(RDMA_INTERFACE_VERBS), 
<BR>+      VerbsVersion(VERBS_MAJOR_VER, 
VERBS_MINOR_VER), <BR>+      p_ext, 
(PINTERFACE)&p_ext->hca_ifc );<BR>+ if( !NT_SUCCESS( status ) ) 
<BR>+ {<BR>+  BUS_TRACE_EXIT(BUS_DBG_PNP,<BR>+   ("Getting 
MLX4 BUS interface failed: status=0x%x\n", status));<BR>+  return 
STATUS_UNSUCCESSFUL;<BR>+ }<BR>+ p_ext->hca_ifc_taken = 
TRUE;<BR>+<BR>+ /* bind BFI to HCA by CA GUID. Have to be before 
ib_register_ca */<BR>+ p_bfi->ca_guid = 
p_ext->hca_ifc.Verbs.guid;<BR>+<BR>+ /* register HCA 
*/<BR>+ ib_status = ib_register_ca( &p_ext->hca_ifc.Verbs, 
p_ext->cl_ext.p_pdo, p_dev_obj );<BR>+ if( ib_status != IB_SUCCESS 
)<BR>+ {<BR>+  BUS_TRACE_EXIT( BUS_DBG_ERROR, ("ib_register_ca 
returned %s.\n",<BR>+   ib_get_err_str(ib_status)) 
);<BR>+  return 
STATUS_UNSUCCESSFUL;<BR>+ }<BR>+ BUS_TRACE_EXIT(BUS_DBG_PNP, ("%s 
bound to CA guid 
%I64x\n",<BR>+  p_bfi->whoami,p_bfi->ca_guid));<BR>+<BR>+ p_ext->ca_registered 
= TRUE;<BR>+ return status;<BR>+}<BR>+<BR>+static 
NTSTATUS<BR> fdo_start(<BR>  IN     DEVICE_OBJECT* 
const p_dev_obj,<BR>  IN     IRP* 
const    p_irp, <BR>@@ -399,6 +453,7 
@@<BR> <BR>  p_ext = 
p_dev_obj->DeviceExtension;<BR>  p_bfi = 
p_ext->bus_filter;<BR>+ ASSERT( !p_ext->ca_registered 
);<BR> <BR>  /* Handled on the way up. */<BR>  status = 
cl_do_sync_pnp( p_dev_obj, p_irp, p_action );<BR>@@ -408,6 +463,7 
@@<BR>    ("Lower drivers failed IRP_MN_START_DEVICE.\n") 
);<BR>   return 
status;<BR>  }<BR>+ p_ext->device_power_state = 
PowerDeviceD0;<BR> <BR>  lock_control_event();<BR>  if 
( !gp_async_proc_mgr ) {<BR>@@ -444,6 +500,11 @@<BR>   return 
STATUS_UNSUCCESSFUL;<BR>  }<BR> <BR>+ /* start IBAL 
*/<BR>+ status = __register_ca( p_dev_obj );<BR>+ if( !NT_SUCCESS( 
status ) )<BR>+  return status;<BR>+<BR>  if ( AL_init_here 
) {<BR>   status = IoSetDeviceInterfaceState( &al_ifc_name, 
TRUE );<BR>   ASSERT( NT_SUCCESS( status ) );<BR>@@ -455,33 
+516,9 @@<BR>   ASSERT( NT_SUCCESS( status ) 
);<BR>  }<BR> <BR>- /* get HCA verbs interface 
*/<BR>- status = __get_ifc( p_dev_obj, 
&GUID_RDMA_INTERFACE_VERBS,<BR>-      sizeof(RDMA_INTERFACE_VERBS), 
<BR>-      VerbsVersion(VERBS_MAJOR_VER, 
VERBS_MINOR_VER), <BR>-      p_ext, 
(PINTERFACE)&p_ext->hca_ifc );<BR>- if( !NT_SUCCESS( status ) ) 
<BR>- {<BR>-  BUS_TRACE_EXIT(BUS_DBG_PNP,<BR>-   ("Getting 
MLX4 BUS interface failed: status=0x%x\n", status));<BR>-  return 
STATUS_UNSUCCESSFUL;<BR>- }<BR>- p_ext->hca_ifc_taken = 
TRUE;<BR>+ CL_PRINT_TO_EVENT_LOG( p_dev_obj, 
EVENT_IBBUS_ANY_INFO,<BR>+  ("IBBUS started \n" 
));<BR> <BR>- /* bind BFI to HCA by CA GUID. Have to be before 
ib_register_ca */<BR>- p_bfi->ca_guid = 
p_ext->hca_ifc.Verbs.guid;<BR>-<BR>- /* register HCA 
*/<BR>- ib_status = ib_register_ca( &p_ext->hca_ifc.Verbs, 
p_ext->cl_ext.p_pdo, p_dev_obj );<BR>- if( ib_status != IB_SUCCESS 
)<BR>- {<BR>-  BUS_TRACE_EXIT( BUS_DBG_ERROR, ("ib_register_ca 
returned %s.\n",<BR>-   ib_get_err_str(ib_status)) 
);<BR>-  return 
STATUS_UNSUCCESSFUL;<BR>- }<BR>-<BR>- BUS_TRACE_EXIT(BUS_DBG_PNP, ("%s 
bound to CA guid 
%I64x\n",<BR>-         p_bfi->whoami,p_bfi->ca_guid));<BR>  return 
status;<BR> }<BR> <BR>@@ -537,6 +574,40 
@@<BR> }<BR> <BR> <BR>+static 
void<BR>+__deregister_ca(<BR>+ IN     DEVICE_OBJECT* 
const p_dev_obj 
)<BR>+{<BR>+ bus_fdo_ext_t *p_ext;<BR>+ bus_filter_t *p_bfi;<BR>+ ib_api_status_t ib_status;<BR>+<BR>+ BUS_ENTER( 
BUS_DBG_PNP );<BR>+<BR>+ p_ext = 
p_dev_obj->DeviceExtension;<BR>+ p_bfi = 
p_ext->bus_filter;<BR>+<BR>+ if ( !p_ext->ca_registered 
)<BR>+  return;<BR>+ p_ext->ca_registered = 
FALSE;<BR>+<BR>+ //TODO: Fail outstanding I/O 
operations.<BR>+<BR>+ ib_status = ib_deregister_ca( 
p_ext->hca_ifc.Verbs.guid );<BR>+ if( ib_status != IB_SUCCESS ) 
{<BR>+  BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned 
%s.\n",<BR>+   ib_get_err_str(ib_status)) 
);<BR>+ }<BR>+<BR>+ if ( p_ext->hca_ifc_taken ) 
{<BR>+  p_ext->hca_ifc.InterfaceHeader.InterfaceDereference(<BR>+   p_ext->hca_ifc.InterfaceHeader.Context);<BR>+  p_ext->hca_ifc_taken 
= FALSE;<BR>+ }<BR>+<BR>+ BUS_EXIT( BUS_DBG_PNP 
);<BR>+}<BR>+<BR> /*<BR>  * This function gets called after releasing 
the remove lock and waiting<BR>  * for all other threads to release the 
lock.  No more modifications will<BR>@@ -550,7 +621,6 
@@<BR>  NTSTATUS  status;<BR>  bus_filter_t *p_bfi;<BR>  int    ic;<BR>- ib_api_status_t ib_status;<BR> <BR>  BUS_ENTER( 
BUS_DBG_PNP );<BR> <BR>@@ -560,20 +630,17 @@<BR>  p_bfi = 
p_ext->bus_filter;<BR>  CL_ASSERT( p_bfi 
);<BR> <BR>- //TODO: Fail outstanding I/O 
operations.<BR>+ __deregister_ca( p_dev_obj 
);<BR> <BR>- ib_status = ib_deregister_ca( 
p_ext->hca_ifc.Verbs.guid );<BR>- if( ib_status != IB_SUCCESS ) 
{<BR>-  BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned 
%s.\n",<BR>-   ib_get_err_str(ib_status)) 
);<BR>- }<BR>-<BR>  if ( p_bfi->p_port_mgr 
)<BR>   cl_obj_destroy( p_bfi->p_port_mgr_obj 
);<BR> <BR>  if ( p_bfi->p_iou_mgr )<BR>   
 cl_obj_destroy( p_bfi->p_iou_mgr_obj );<BR> <BR>+#if 
0<BR>+ // IBAL has no right to work with CA after it 
deregister.<BR>+ // So there is no need to release interface only after 
IBAL cleanup<BR> <BR>  /* if not last HCA then release IFC 
reference, otherwise release IFC after<BR>   * IBAL has shutdown; keep 
the HCA present until IBAL is terminated.<BR>@@ -583,6 +650,7 
@@<BR>    p_ext->hca_ifc.InterfaceHeader.Context);<BR>   p_ext->hca_ifc_taken 
= FALSE;<BR>  }<BR>+#endif <BR> <BR>  BUS_TRACE( 
BUS_DBG_PNP, ("Releasing BusFilter %s\n", p_bfi->whoami ));<BR>  if 
(p_bfi) {<BR>@@ -623,6 +691,10 @@<BR> <BR>  CL_ASSERT( 
!gp_async_proc_mgr && !gp_async_pnp_mgr && !gp_al_mgr 
);<BR> <BR>+#if 0<BR>+  // IBAL has no right to work with CA 
after it deregister.<BR>+  // So there is no need to release interface 
only after IBAL cleanup<BR>+ <BR>  /* AL needs the HCA to stick 
around until AL cleanup has completed.<BR>   * Now that it's done, let 
the HCA fade away.<BR>   */<BR>@@ -631,6 +703,7 
@@<BR>    p_ext->hca_ifc.InterfaceHeader.Context);<BR>   p_ext->hca_ifc_taken 
= FALSE;<BR>  }<BR>+#endif <BR> <BR>  BUS_EXIT( 
BUS_DBG_PNP );<BR> }<BR>@@ -1082,7 +1155,27 @@<BR>  return 
STATUS_SUCCESS;<BR> }<BR> <BR>+static 
NTSTATUS<BR>+fdo_query_pnp_state(<BR>+ IN    DEVICE_OBJECT* 
const  p_dev_obj,<BR>+ IN    IRP* 
const     p_irp, 
<BR>+  OUT   cl_irp_action_t* const  p_action 
)<BR>+{<BR>+ bus_fdo_ext_t  *p_ext;<BR> <BR>+ BUS_ENTER( 
BUS_DBG_PNP );<BR>+<BR>+ p_ext = 
(bus_fdo_ext_t*)p_dev_obj->DeviceExtension;<BR>+<BR>+ p_irp->IoStatus.Information 
|= p_ext->pnp_state;<BR>+<BR>+ *p_action = 
IrpSkip;<BR>+<BR>+ BUS_EXIT( BUS_DBG_PNP );<BR>+ return 
STATUS_SUCCESS;;<BR>+}<BR>+<BR>+<BR> static 
NTSTATUS<BR> fdo_query_interface(<BR>  IN     DEVICE_OBJECT* 
const p_dev_obj,<BR>@@ -1153,7 +1246,9 @@<BR>   switch( 
p_io_stack->Parameters.Power.State.SystemState 
)<BR>   {<BR>    case 
PowerSystemHibernate:<BR>-   case PowerSystemSleeping1:  // 
STANDBY support<BR>+   case PowerSystemSleeping1: // STANDBY 
support<BR>+   case PowerSystemSleeping2: // STANDBY 
support<BR>+   case PowerSystemSleeping3: // STANDBY 
support<BR>    case 
PowerSystemWorking:<BR>    case 
PowerSystemShutdown:<BR>      break;<BR>@@ -1188,91 
+1283,187 @@<BR> }<BR> <BR> <BR>+<BR>+/* Work item callback to 
handle DevicePowerD0 IRPs at passive level. */<BR>+<BR> static 
void<BR>-__request_power_completion(<BR>- IN    DEVICE_OBJECT    *p_dev_obj,<BR>- IN    UCHAR      minor_function,<BR>- IN    POWER_STATE     power_state,<BR>- IN    void      *context,<BR>- IN    IO_STATUS_BLOCK    *p_io_status 
)<BR>+__device_power_up_completion_workItem(<BR>+ IN    DEVICE_OBJECT*    p_dev_obj,<BR>+ IN    void*      context 
)<BR> {<BR>+ NTSTATUS   status;<BR>+ IO_STACK_LOCATION *p_io_stack;<BR>+ bus_fdo_ext_t  *p_ext;<BR>  IRP     *p_irp;<BR>- cl_pnp_po_ext_t  *p_ext;<BR>+ POWER_STATE   power_state;<BR> <BR>- BUS_ENTER( 
BUS_DBG_PNP );<BR>+ BUS_ENTER( BUS_DBG_POWER 
);<BR> <BR>- UNUSED_PARAM( minor_function );<BR>- UNUSED_PARAM( 
power_state );<BR>-<BR>+ p_ext = 
(bus_fdo_ext_t*)p_dev_obj->DeviceExtension;<BR>  p_irp = 
(IRP*)context;<BR>- p_ext = 
p_dev_obj->DeviceExtension;<BR>+ p_io_stack = 
IoGetCurrentIrpStackLocation( p_irp );<BR> <BR>- /* Propagate the 
device IRP status to the system IRP status. 
*/<BR>- p_irp->IoStatus.Status = 
p_io_status->Status;<BR>+ IoFreeWorkItem( p_ext->p_po_work_item 
);<BR>+ p_ext->p_po_work_item = NULL;<BR> <BR>- /* Continue 
Power IRP processing. */<BR>+ /* re-register CA */<BR>+ BUS_PRINT( 
BUS_DBG_POWER, <BR>+  ("***** re-register CA, IRQL %d\n", 
KeGetCurrentIrql()));<BR>+<BR>+ status = __register_ca( p_dev_obj 
);<BR>+ if( !NT_SUCCESS( status ) ) {<BR>+  BUS_PRINT( 
BUS_DBG_POWER, <BR>+   ("!!! __register_ca failed (%#x) \n", 
status));<BR>+  goto 
err_fdo_start;<BR>+ }<BR>+<BR>+ p_ext->device_power_state = 
p_io_stack->Parameters.Power.State.DeviceState;<BR>+ power_state = 
PoSetPowerState( p_dev_obj, 
DevicePowerState,<BR>+  p_io_stack->Parameters.Power.State 
);<BR>+<BR>+ BUS_PRINT( BUS_DBG_POWER, <BR>+  ("PoSetPowerState: 
old state %d, new state to %d\n", <BR>+  power_state.DeviceState, 
p_ext->device_power_state ));<BR>+<BR>+ CL_PRINT_TO_EVENT_LOG( 
p_dev_obj, EVENT_IBBUS_ANY_WARN,<BR>+  ("Power increased to: device 
%d, system %d.\n",<BR>+  (int)p_ext->device_power_state, 
(int)p_ext->system_power_state));<BR>+<BR>+ goto 
exit;<BR>+<BR>+err_fdo_start:<BR>+ /* Flag device as having failed. 
*/<BR>+ p_ext->pnp_state |= 
PNP_DEVICE_FAILED;<BR>+ IoInvalidateDeviceState( p_ext->cl_ext.p_pdo 
);<BR>+exit:<BR>  PoStartNextPowerIrp( p_irp 
);<BR>  IoCompleteRequest( p_irp, IO_NO_INCREMENT 
);<BR>- IoReleaseRemoveLock( &p_ext->remove_lock, p_irp 
);<BR>- BUS_EXIT( BUS_DBG_PNP );<BR>+ IoReleaseRemoveLock( 
&p_ext->cl_ext.remove_lock, p_irp );<BR>+ BUS_EXIT( BUS_DBG_POWER 
);<BR> }<BR> <BR> <BR> /*NOTE: Completion routines must 
NEVER be pageable. */<BR> static 
NTSTATUS<BR>-__set_power_completion(<BR>+__device_power_up_completion(<BR>  IN    DEVICE_OBJECT    *p_dev_obj,<BR>  IN    IRP       *p_irp,<BR>  IN    void      *context 
)<BR> {<BR>- NTSTATUS   status;<BR>- POWER_STATE   state;<BR>+ NTSTATUS   status 

STATUS_SUCCESS;<BR>  bus_fdo_ext_t  *p_ext;<BR>  IO_STACK_LOCATION *p_io_stack;<BR> <BR>- BUS_ENTER( 
BUS_DBG_PNP );<BR>+ BUS_ENTER( BUS_DBG_POWER 
);<BR> <BR>  UNUSED_PARAM( context );<BR> <BR>- p_ext = 
p_dev_obj->DeviceExtension;<BR>+ p_ext = 
(bus_fdo_ext_t*)p_dev_obj->DeviceExtension;<BR>  p_io_stack = 
IoGetCurrentIrpStackLocation( p_irp );<BR> <BR>- if( !NT_SUCCESS( 
p_irp->IoStatus.Status ) )<BR>- {<BR>+ if( !NT_SUCCESS( 
p_irp->IoStatus.Status ) ) {<BR>+  BUS_PRINT( BUS_DBG_POWER, 
<BR>+   ("IRP_MN_SET_POWER for device failed by lower driver with 
%08x.\n",<BR>+   p_irp->IoStatus.Status));<BR>+  status 
=  STATUS_SUCCESS;<BR>   PoStartNextPowerIrp( p_irp 
);<BR>-  IoReleaseRemoveLock( &p_ext->cl_ext.remove_lock, p_irp 
);<BR>-  BUS_TRACE_EXIT( BUS_DBG_ERROR, 
<BR>-   ("IRP_MN_SET_POWER for system failed by lower driver with 
%08x.\n",<BR>-   p_irp->IoStatus.Status) 
);<BR>-  return STATUS_SUCCESS;<BR>+  goto 
release;<BR>  }<BR> <BR>- state.DeviceState = 
<BR>-  p_ext->po_state[p_io_stack->Parameters.Power.State.SystemState];<BR>-<BR>- /*<BR>-  
* Send a device power IRP to our devnode.  Using our device object 
will<BR>-  * only work on win2k and other NT based systems.<BR>-  
*/<BR>- status = PoRequestPowerIrp( p_dev_obj, IRP_MN_SET_POWER, 
state,<BR>-  __request_power_completion, p_irp, NULL 
);<BR>-<BR>- if( status != STATUS_PENDING )<BR>- {<BR>+ /* 
Process in a work item to allow blocking. */<BR>+ ASSERT( 
!p_ext->p_po_work_item );<BR>+ p_ext->p_po_work_item = 
IoAllocateWorkItem( p_dev_obj );<BR>+ if( !p_ext->p_po_work_item ) 
{<BR>+  BUS_PRINT( BUS_DBG_POWER, <BR>+   ("Failed to 
allocate work item.\n" ));<BR>+  status = 
STATUS_SUCCESS;<BR>+  p_ext->pnp_state |= 
PNP_DEVICE_FAILED;<BR>+  IoInvalidateDeviceState( 
p_ext->cl_ext.p_pdo );<BR>   PoStartNextPowerIrp( p_irp 
);<BR>-  /* Propagate the failure. 
*/<BR>-  p_irp->IoStatus.Status = 
status;<BR>-  IoCompleteRequest( p_irp, IO_NO_INCREMENT 
);<BR>-  IoReleaseRemoveLock( &p_ext->cl_ext.remove_lock, p_irp 
);<BR>-  BUS_TRACE( 
BUS_DBG_ERROR,<BR>-   ("PoRequestPowerIrp returned %08x.\n", 
status) );<BR>+  goto 
release;<BR>  }<BR> <BR>- BUS_EXIT( BUS_DBG_PNP 
);<BR>- return STATUS_MORE_PROCESSING_REQUIRED;<BR>+ /* Process in 
work item callback. */<BR>+ IoMarkIrpPending( p_irp 
);<BR>+ IoQueueWorkItem( p_ext->p_po_work_item, 
<BR>+  __device_power_up_completion_workItem, DelayedWorkQueue, p_irp 
);<BR>+ status = STATUS_MORE_PROCESSING_REQUIRED;<BR>+ goto 
exit;<BR>+<BR>+release: <BR>+ IoReleaseRemoveLock( 
&p_ext->cl_ext.remove_lock, p_irp );<BR>+exit: <BR>+ BUS_EXIT( 
BUS_DBG_POWER );<BR>+ return 
status;<BR> }<BR> <BR> <BR>+static NTSTATUS 
__device_power_down_workItem_completion(<BR>+ IN    DEVICE_OBJECT *p_dev_obj,<BR>+ IN    IRP    *p_irp,<BR>+ IN    void    *context 
)<BR>+{<BR>+ bus_fdo_ext_t  *p_ext = 
(bus_fdo_ext_t*)p_dev_obj->DeviceExtension;<BR>+ UNUSED_PARAM( context 
);<BR>+<BR>+ BUS_ENTER( BUS_DBG_POWER 
);<BR>+<BR>+ PoStartNextPowerIrp( p_irp );<BR>+ IoReleaseRemoveLock( 
&p_ext->cl_ext.remove_lock, p_irp );<BR>+<BR>+ BUS_EXIT( 
BUS_DBG_POWER );<BR>+ return STATUS_SUCCESS;<BR>+}<BR>+<BR>+/* Work item 
callback to handle DevicePowerD3 IRPs at passive level. */<BR>+static 
void<BR>+__device_power_down_workItem(<BR>+ IN    DEVICE_OBJECT*    p_dev_obj,<BR>+ IN    void*      context 
)<BR>+{<BR>+ IO_STACK_LOCATION *p_io_stack;<BR>+ bus_fdo_ext_t  *p_ext;<BR>+ IRP     *p_irp;<BR>+ POWER_STATE   power_state;<BR>+<BR>+ BUS_ENTER( 
BUS_DBG_POWER );<BR>+<BR>+ p_ext = 
(bus_fdo_ext_t*)p_dev_obj->DeviceExtension;<BR>+ p_irp = 
(IRP*)context;<BR>+ p_io_stack = IoGetCurrentIrpStackLocation( p_irp 
);<BR>+<BR>+ IoFreeWorkItem( p_ext->p_po_work_item 
);<BR>+ p_ext->p_po_work_item = 
NULL;<BR>+<BR>+ p_ext->device_power_state = 
p_io_stack->Parameters.Power.State.DeviceState;<BR>+ power_state = 
PoSetPowerState( p_dev_obj, 
DevicePowerState,<BR>+  p_io_stack->Parameters.Power.State 
);<BR>+<BR>+ BUS_PRINT( BUS_DBG_POWER, <BR>+  ("PoSetPowerState: 
old state %d, new state to %d, IRQL %d\n", 
<BR>+  power_state.DeviceState, p_ext->device_power_state, 
KeGetCurrentIrql() ));<BR>+<BR>+ CL_PRINT_TO_EVENT_LOG( p_dev_obj, 
EVENT_IBBUS_ANY_WARN,<BR>+  ("Power decreased to: device %d, system 
%d.\n",<BR>+  (int)p_ext->device_power_state, 
(int)p_ext->system_power_state));<BR>+<BR>+ BUS_PRINT( BUS_DBG_POWER, 
<BR>+  ("***** deregister CA \n"));<BR>+<BR>+ __deregister_ca( 
p_dev_obj );<BR>+<BR>+ IoCopyCurrentIrpStackLocationToNext( p_irp 
);<BR>+#pragma warning( push, 3 )<BR>+ IoSetCompletionRoutine( p_irp, 
__device_power_down_workItem_completion,<BR>+  NULL, TRUE, TRUE, TRUE 
);<BR>+#pragma warning( pop )<BR>+ PoCallDriver( 
p_ext->cl_ext.p_next_do, p_irp );<BR>+<BR>+ BUS_EXIT( BUS_DBG_POWER 
);<BR>+}<BR>+<BR>+<BR>+<BR> static 
NTSTATUS<BR> __fdo_set_power(<BR>  IN    DEVICE_OBJECT* 
const  p_dev_obj,<BR>@@ -1289,35 +1480,63 @@<BR>  p_io_stack 
= IoGetCurrentIrpStackLocation( p_irp );<BR> <BR>  BUS_TRACE( 
BUS_DBG_POWER, <BR>-  ("SET_POWER for FDO %p (ext %p): type %s, state 
%d, action %d \n",<BR>+  ("SET_POWER for FDO %p (ext %p): type %s, 
state %d, action %d, IRQL %d  \n",<BR>   p_dev_obj, 
p_ext,<BR>   (p_io_stack->Parameters.Power.Type)<BR>    ? 
"DevicePowerState" : 
"SystemPowerState",<BR>   p_io_stack->Parameters.Power.State.DeviceState, 
<BR>-  p_io_stack->Parameters.Power.ShutdownType 
));<BR>+  p_io_stack->Parameters.Power.ShutdownType, 
KeGetCurrentIrql() ));<BR> <BR>  switch( 
p_io_stack->Parameters.Power.Type )<BR>  {<BR>  case 
SystemPowerState:<BR>-#if 0<BR>-  /*<BR>-   * Process on the 
way up the stack.  We cannot block since the <BR>-   * power 
dispatch function can be called at elevated IRQL if the<BR>-   * 
device is in a paging/hibernation/crash dump path.<BR>-   
*/<BR>+  /* Pass down and let the PDO driver handle it. 
*/<BR>+  p_ext->system_power_state = 
p_io_stack->Parameters.Power.State.SystemState;<BR>+  *p_action = 
IrpIgnore;<BR>+  status = 
STATUS_SUCCESS;<BR>+  break;<BR>+<BR>+ case 
DevicePowerState:<BR>   IoMarkIrpPending( p_irp 
);<BR>-  IoCopyCurrentIrpStackLocationToNext( p_irp 
);<BR>+  if( p_io_stack->Parameters.Power.State.DeviceState == 
PowerDeviceD0 && <BR>+   p_ext->system_power_state == 
PowerSystemWorking)<BR>+  { /* power up */<BR>+   /* If 
we're already powered up, just pass down. */<BR>+   if( 
p_ext->device_power_state == PowerDeviceD0 
)<BR>+   {<BR>+    status = 
STATUS_SUCCESS;<BR>+    *p_action = 
IrpIgnore;<BR>+    break;<BR>+   }<BR>+<BR>+   /* 
Process in I/O completion callback. 
*/<BR>+   IoCopyCurrentIrpStackLocationToNext( p_irp 
);<BR> #pragma warning( push, 3 )<BR>-  IoSetCompletionRoutine( 
p_irp, __set_power_completion, NULL, <BR>-   TRUE, TRUE, TRUE 
);<BR>+   IoSetCompletionRoutine( p_irp, 
__device_power_up_completion, NULL, <BR>+    TRUE, TRUE, 
TRUE );<BR> #pragma warning( pop )<BR>-  PoCallDriver( 
p_ext->cl_ext.p_next_do, p_irp );<BR>+   PoCallDriver( 
p_ext->cl_ext.p_next_do, p_irp 
);<BR>+  }<BR>+  else<BR>+  { /* power down 
*/<BR> <BR>+   /* Process in a work item - deregister_ca and 
HcaDeinit block. */<BR>+   ASSERT( !p_ext->p_po_work_item 
);<BR>+   p_ext->p_po_work_item = IoAllocateWorkItem( 
p_dev_obj );<BR>+   if( !p_ext->p_po_work_item 
)<BR>+   {<BR>+    status = 
STATUS_INSUFFICIENT_RESOURCES;<BR>+    break;<BR>+   }<BR>+<BR>+   /* 
Process in work item callback. 
*/<BR>+   IoQueueWorkItem(<BR>+    p_ext->p_po_work_item, 
__device_power_down_workItem, DelayedWorkQueue, p_irp 
);<BR>+  }<BR>   *p_action = 
IrpDoNothing;<BR>   status = 
STATUS_PENDING;<BR>   break;<BR>-#endif<BR>- case 
DevicePowerState:<BR>+<BR>  default:<BR>   /* Pass down 
and let the PDO driver handle it. */<BR>   *p_action = 
IrpIgnore;<BR>@@ -1325,6 +1544,9 
@@<BR>   break;<BR>  }<BR> <BR>+ if( 
!NT_SUCCESS( status ) )<BR>+  *p_action = 
IrpComplete;<BR>+<BR>  BUS_EXIT( BUS_DBG_POWER 
);<BR>  return status;<BR> }<BR>Index: 
core/bus/kernel/bus_port_mgr.c<BR>===================================================================<BR>--- 
core/bus/kernel/bus_port_mgr.c (revision 2421)<BR>+++ 
core/bus/kernel/bus_port_mgr.c (working copy)<BR>@@ -2106,7 +2106,9 
@@<BR> <BR>  if ((p_io_stack->Parameters.Power.Type == 
SystemPowerState) 
&&<BR>   (p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemHibernate 
||<BR>-  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping1 
))<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping1 
||<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping2 
||<BR>+  p_io_stack->Parameters.Power.State.SystemState 
==PowerSystemSleeping3 ))<BR>  {<BR>   BUS_TRACE( 
BUS_DBG_POWER, ("Setting b_hibernating flag for PDO %p \n", 
p_dev_obj));<BR>   p_ext->b_hibernating = TRUE;<BR>Index: 
hw/mlx4/kernel/bus/drv/drv.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/drv.c (revision 2421)<BR>+++ 
hw/mlx4/kernel/bus/drv/drv.c (working copy)<BR>@@ -437,7 +437,7 
@@<BR> <BR>  MLX4_PRINT(TRACE_LEVEL_INFORMATION, MLX4_DBG_DRV, 
("PreviousState 0x%x\n", PreviousState));<BR> <BR>- // start card 
(needed after Hibernetion)<BR>+ // start card (needed after Hibernation or 
standby)<BR>  if (PreviousState > 
WdfPowerDeviceD0)<BR>   status = __start_card( Device, p_fdo 
);<BR>  if ( !NT_SUCCESS( status ) ) <BR>Index: 
hw/mlx4/kernel/hca/drv.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/hca/drv.c (revision 2421)<BR>+++ 
hw/mlx4/kernel/hca/drv.c (working copy)<BR>@@ -76,12 +76,6 
@@<BR> <BR> #ifndef USE_WDM_FRAMEWORK<BR> <BR>-//<BR>-// TODO: 
add support for Hibernate/Standby as in WDM version 
below<BR>-//<BR>-<BR>-<BR>-<BR> static 
ci_interface_t*<BR> __alloc_hca_ifc(<BR>  IN    PFDO_DEVICE_DATA 
const  p_fdo )<BR>@@ -197,10 +191,25 @@<BR>  IN 
WDF_POWER_DEVICE_STATE  
PreviousState<BR>  )<BR> {<BR>- UNUSED_PARAM(Device);<BR>- UNUSED_PARAM(PreviousState);<BR>+ NTSTATUS 
status;<BR>+ PFDO_DEVICE_DATA p_fdo = 
FdoGetData(Device);<BR>+<BR>  HCA_ENTER( HCA_DBG_PNP 
);<BR>  HCA_PRINT(TRACE_LEVEL_INFORMATION, HCA_DBG_PNP, 
("EvtDeviceD0Entry: PreviousState 0x%x\n", PreviousState));<BR>+ // start 
card (needed after Hibernation or standby)<BR>+ if (PreviousState > 
WdfPowerDeviceD0) {<BR>+  /* get MLX4_BUS IB interface 
*/<BR>+  if ( !p_fdo->bus_ib_ifc_taken ) 
{<BR>+   status = WdfFdoQueryForInterface( Device, 
&MLX4_BUS_IB_INTERFACE_GUID,<BR>+    (PINTERFACE)&p_fdo->bus_ib_ifc, 
sizeof(MLX4_BUS_IB_INTERFACE), MLX4_BUS_IB_INTERFACE_VERSION, NULL 
);<BR>+   if( !NT_SUCCESS( status ) ) 
{<BR>+    HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
("Getting MLX4 BUS interface failed: status=0x%x\n", 
status));<BR>+    return 
status;<BR>+   }<BR>+   p_fdo->bus_ib_ifc_taken 
= TRUE;<BR>+   p_fdo->bus_ib_ifc.p_ibdev->x.p_fdo = 
p_fdo;<BR>+  }<BR>+ }<BR>  HCA_EXIT( HCA_DBG_PNP 
);<BR>  return STATUS_SUCCESS;<BR> }<BR>@@ -220,6 +229,8 
@@<BR> <BR>  switch (TargetState) {<BR>  case 
WdfPowerDeviceD1: /* hopefully, it is STANDBY state */<BR>+ case 
WdfPowerDeviceD2: /* hopefully, it is STANDBY state */<BR>+ case 
WdfPowerDeviceD3: /* hopefully, it is STANDBY state */<BR>  case 
WdfPowerDevicePrepareForHibernation:<BR>   if 
(atomic_read(&p_fdo->usecnt)) {<BR>    status = 
STATUS_UNSUCCESSFUL;<BR>@@ -231,6 +242,14 
@@<BR>   break;<BR>  }<BR> <BR>+ if 
(TargetState > WdfPowerDeviceD0) 
{<BR>+  if(p_fdo->bus_ib_ifc_taken) 
{<BR>+   PINTERFACE p_ifc = 
(PINTERFACE)&p_fdo->bus_ib_ifc;<BR>+   p_ifc->InterfaceDereference( 
p_ifc->Context );<BR>+   p_fdo->bus_ib_ifc_taken = 
FALSE;<BR>+  }<BR>+ }<BR>+<BR>  HCA_EXIT( HCA_DBG_PNP 
);<BR>  return status;<BR> }<BR>@@ -268,14 +287,16 
@@<BR>  p_fdo->bus_pci_ifc_taken = 
TRUE;<BR>  <BR>  /* get MLX4_BUS IB interface 
*/<BR>- status = WdfFdoQueryForInterface( Device, 
&MLX4_BUS_IB_INTERFACE_GUID,<BR>-  (PINTERFACE)&p_fdo->bus_ib_ifc, 
sizeof(MLX4_BUS_IB_INTERFACE), MLX4_BUS_IB_INTERFACE_VERSION, NULL 
);<BR>- if( !NT_SUCCESS( status ) ) 
{<BR>-  HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Getting MLX4 BUS 
interface failed: status=0x%x\n", status));<BR>-  return 
status;<BR>+ if ( !p_fdo->bus_ib_ifc_taken ) {<BR>+  status = 
WdfFdoQueryForInterface( Device, 
&MLX4_BUS_IB_INTERFACE_GUID,<BR>+   (PINTERFACE)&p_fdo->bus_ib_ifc, 
sizeof(MLX4_BUS_IB_INTERFACE), MLX4_BUS_IB_INTERFACE_VERSION, NULL 
);<BR>+  if( !NT_SUCCESS( status ) ) 
{<BR>+   HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Getting MLX4 
BUS interface failed: status=0x%x\n", status));<BR>+   return 
status;<BR>+  }<BR>+  p_fdo->bus_ib_ifc_taken = 
TRUE;<BR>+  p_fdo->bus_ib_ifc.p_ibdev->x.p_fdo = 
p_fdo;<BR>  }<BR>- p_fdo->bus_ib_ifc_taken = 
TRUE;<BR>- p_fdo->bus_ib_ifc.p_ibdev->x.p_fdo = 
p_fdo;<BR> <BR>  InitializeListHead(&p_fdo->hca.event_list);<BR>  KeInitializeSpinLock(&p_fdo->hca.event_list_lock);<BR>@@ 
-1397,6 +1418,8 @@<BR>   switch( 
pIoStack->Parameters.Power.State.SystemState 
)<BR>   {<BR>    case 
PowerSystemSleeping1: // STANDBY support<BR>+   case 
PowerSystemSleeping2: // STANDBY support<BR>+   case 
PowerSystemSleeping3: // STANDBY support<BR>    case 
PowerSystemHibernate:<BR>    {<BR>     PFDO_DEVICE_DATA 
p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;<BR>Index: 
hw/mthca/kernel/hca_pnp.c<BR>===================================================================<BR>--- 
hw/mthca/kernel/hca_pnp.c (revision 2421)<BR>+++ 
hw/mthca/kernel/hca_pnp.c (working copy)<BR>@@ -981,6 +981,8 
@@<BR>   switch( pIoStack->Parameters.Power.State.SystemState 
)<BR>   {<BR>    case 
PowerSystemSleeping1: // STANDBY support<BR>+   case 
PowerSystemSleeping2: // STANDBY support<BR>+   case 
PowerSystemSleeping3: // STANDBY support<BR>    case 
PowerSystemHibernate:<BR>    {<BR>     hca_dev_ext_t*p_ext 
= (hca_dev_ext_t*)p_dev_obj->DeviceExtension;<BR><SPAN 
class=940575800-07092009>IB<BR>B<BR>US</SPAN></FONT></SPAN></DIV></BODY></HTML>