Tech Support > Microsoft Windows > Drivers > TOASTER busenum SAMPLE - DO_POWER_PAGABLE flag implications?
TOASTER busenum SAMPLE - DO_POWER_PAGABLE flag implications?
Posted by a!s on July 23rd, 2003


In W2K going to hybernation bugchecks with ...

Bug Check 0x9F: DRIVER_POWER_STATE_FAILURE

on !analyze -v more I got more info - "This signifies that the driver
is in an inconsistent or invalid power state"

on further debugging with !devobj i found

the DO flags DO_POWER_PAGABLE is SET for the FDO busenum creates, but
this flag is CLEARED for \Device\PnpManager device which sits beneath
and hence the bug check i understand.

so i simply cleared this flag in toaster\busenum sample code in PNP.C
and the problem is SOLVED and NO bugchecks

but my question is --- I can see that PoSetPowerState () being called
in the file POWER.C. My understanding is, if called at DISPATCH_LEVEL
for setting states other than D0 toaster\busenum shud crash. Is there
a test case for this? and if so how to gaurd power.c against this. I
tried hybernation & suspend but this code path at DISPATCH is not
executed, i think. So the system is happy and everything works fine.
any test scenarios ?

thx
alex

Posted by Eliyas Yakub [MSFT] on July 25th, 2003


If DO_POWER_PAGABLE bit is set, the power manager shouldn't send power IRPs
at DISPATCH_LEVEL. I know for sure, on XP, the power manager checks this bit
and queues a workitem if you happen to call PoCallDriver at DISPATCH_LEVEL.
May be this fix is not there on Win2K and hence the crash. I never ran into
this on Win2K myself.

Recently I discussed this issue with out power management team and they
suggested me to do as follows:

1) In the AddDevice device after you attach your deviceobject to the lower
one, check it's Flags to see if the DO_POWER_INRUSH is set. If it's set then
you should set that in your device object. ( I don't know when and why would
the driver below me decide to set this bit. It seems that ACPI driver for
some weird reasons may choose to set that). If the DO_POWER_INRUSH bit is
set in the lower deviceobject then you shouldn't set DO_POWER_PAGABLE in
yours because they are exclusive.

2) If the DO_POWER_INRUSH is not set then check to see if the
DO_POWER_PAGABLE bit is set. If it's set then set that in your deviceobject.

3) Finally if the DO_POWER_PAGABLE is not set in your deviceobject, lock
all your power management code in your driver. Either this or you should
just avoid marking all the Power management routines pageable altogether to
keep it simple.

Here is a code snippet from a sample:

//
// Bit Flag Macros
//

#define SET_FLAG(Flags, Bit) ((Flags) |= (Bit))
#define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit))
#define TEST_FLAG(Flags, Bit) (((Flags) & (Bit)) != 0)

//
// The DO_POWER_PAGABLE bit of a device object indicates to the
// kernel that the power-handling code of the corresponding
// driver is pageable, and so must be called at PASSIVE_LEVEL.
// Before we set it, we must check the deviceobject beneath
// us to see if the DO_POWER_INRUSH is set.
//
if (TEST_FLAG(fdoData->NextLowerDriver->Flags, DO_POWER_INRUSH)) {
//
// If we set DO_POWER_INRUSH, we shouldn't set DO_POWER_PAGABLE and
// make sure all our power-handling code is either locked or marked
// nonpageable because we can get power IRPs at DISPATCH_LEVEL.
//
SET_FLAG(deviceObject->Flags, DO_POWER_INRUSH);

} else if(TEST_FLAG(fdoData->NextLowerDriver->Flags, DO_POWER_PAGABLE)){

SET_FLAG(deviceObject->Flags, DO_POWER_PAGABLE);
}

//
// If the power pageable bit is not set, we will lock the code section
// that contains all the power handling code so that it can be safely
// called at IRQL>PASSIVE_LEVEL.
//
if(!TEST_FLAG(deviceObject->Flags, DO_POWER_PAGABLE))
{
fdoData->PowerCodeLockHandle = MmLockPagableCodeSection(
(PVOID)PciDrvDispatchPower);
}


// Don't forget to unlock the pages in Remove-Device handler.


--
-Eliyas
This posting is provided "AS IS" with no warranties, and confers no rights.
http://www.microsoft.com/whdc/hwdev/driver/kb-drv.mspx


Posted by Bill McKenzie on July 28th, 2003


What doesn't seem clear to me in the example and explanation below and which
seems a pretty important point to note, is that one must ALWAYS have power
code in one's WDM function driver that can handle being called at raised
IRQL. This code will be needed if the INRUSH flag is set in the PDO which a
driver can only find out at runtime. It would be interesting to find the
percentage of drivers that actually have this code in place today? But then
again, I guess if a driver doesn't fail it is correct, right?

--
Bill McKenzie
Compuware Corporation
Watch your IRPs/IRBs/URBs/SRBs/NDIS pkts with our free WDMSniffer tool:
http://frontline.compuware.com/nashu...es/utility.htm



"Eliyas Yakub [MSFT]" <eliyasy@online.microsoft.com> wrote in message
news:O8MQrQkUDHA.2004@TK2MSFTNGP10.phx.gbl...



Similar Posts