<!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.5512" name=GENERATOR></HEAD>
<BODY>
<DIV><SPAN class=335570213-06092009><FONT size=2>
<P><FONT face=Arial size=1>Mellanox HW doesn't support neither S<SPAN
class=940575800-07092009>t</SPAN>andby nor hibernation.</FONT></P>
<P><FONT face=Arial size=1>To simulate such support, low-level driver resets HCA
on power down and starts it up on power up.</FONT></P>
<P><FONT face=Arial size=1>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>