HwScsiStartIo never called on resume from hibernate

I’ve noticed something strange which I think is relevant. I think this
is related to this thread
http://www.osronline.com/ShowThread.cfm?link=150915 from a few years
ago.

On hibernate, I see the following IRP_MN_SET_POWER IRP’s on my bus
driver:
PDO: Type = DevicePowerState, State = PowerDeviceD3, ShutdownType =
Hibernate
PDO: Type = SystemPowerState, State = PowerSystemHibernate
FDO: Type = SystemPowerState, State = PowerSystemHibernate
FDO: Type = DevicePowerState, State = PowerDeviceD3, ShutdownType =
Hibernate

That is pretty much as expected, but as per the thread in the above
link, WDF doesn’t behave correctly when it gets the power IRP’s in
Device-then-System order, it relies on getting them in
System-then-Device order. I can work around that though.

On resume however, I see:
FDO: Type = SystemPowerState, State = PowerSystemWorking
PDO: Type = DevicePowerState, State = PowerDeviceD0
FDO: Type = DevicePowerState, State = PowerDeviceD0

The SystemPowerState IRP never arrives on the PDO to set the state to
PowerSystemWorking. WDF isn’t going to like that based on what I know
about its internal state machine(s). The first and second hibernation
resumes seem to be okay without receiving the SystemPowerState, but on
the third resume it gets stuck. What I’ve seen before when I looked at
the power IRP that is ‘stuck’ on resume from hibernation is this:

d> !irp 81f94ad0
Irp is active with 5 stacks 1 is current (= 0x81f94b40)
No Mdl: No System Buffer: Thread 00000000: Irp stack trace. Pending
has been returned
cmd flg cl Device File Completion-Context

[f, 0] 0 e1 820bf880 00000000 f889fa4c-81f864fc Success Error
Cancel pending
\Driver\XenVbd IrpSys
Args: 81e4ade4 00000000 00000000 00000000
[16, 2] 0 e1 81e4aab8 00000000 f8727554-00000000 Success Error
Cancel pending
\Driver\Disk PartMgr!PmPowerCompletion
Args: 00000003 00000001 00000001 00000003
[16, 2] 0 e1 81feae08 00000000 80522f24-ba5bf80a Success Error
Cancel pending
\Driver\PartMgr nt!PopCompleteRequestIrp
Args: 00000003 00000001 00000001 00000003
[0, 0] 0 0 81feae08 00000000 00000000-00000000
\Driver\PartMgr
Args: 820bf880 00000002 00000001 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 80559ce0 80559ce0 81f94ad0 00000000

Somewhere along the way the IRP_MN_SET_POWER IRP gets changed to a
IRP_MJ_SCSI IRP with a START_STOP_UNIT CDB. When pci.sys is the PDO I
guess it doesn’t much care, but my WDF bus driver isn’t happy.

Now this is Windows XP and scsiport, both of which are essentially
retired, so I’m pretty much looking for any sort of hack to sort this
out. Is it possible to inject a PowerSystemWorking IRP somewhere and
restore WDF’s state to what it should be? Would WDF’s self-managed-io
help anything along here?

Thanks

James

I believe KMDF should not care much about system power IRPs on the PDO which is not power policy owner. Make sure it’s not. Normally it’s the FDO which owns the power policy, and it sends the device power IRP to its stack. System power IRP should also proceed down. If you don’t see the system power IRP in the PDO, something is wrong. One reason is IoStartNextPowerIrp might not be called for the previous system power IRP.

ALso, check ALL device objects in your PDO and FDO stack for DO_POWER_PAGABLE. That’s what I means in the previous message. ALL device objects. If your bus driver has other PDOs, check them also.

If the devobj is not the PPO (and the pdo is not by default), system power irps are ignored by kmdf’s power and power policy state machines.

d

debt from my phone

-----Original Message-----
From: xxxxx@broadcom.com
Sent: Friday, April 22, 2011 7:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] HwScsiStartIo never called on resume from hibernate

I believe KMDF should not care much about system power IRPs on the PDO which is not power policy owner. Make sure it’s not. Normally it’s the FDO which owns the power policy, and it sends the device power IRP to its stack. System power IRP should also proceed down. If you don’t see the system power IRP in the PDO, something is wrong. One reason is IoStartNextPowerIrp might not be called for the previous system power IRP.

ALso, check ALL device objects in your PDO and FDO stack for DO_POWER_PAGABLE. That’s what I means in the previous message. ALL device objects. If your bus driver has other PDOs, check them also.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

>

I believe KMDF should not care much about system power IRPs on the PDO
which
is not power policy owner. Make sure it’s not. Normally it’s the FDO
which
owns the power policy, and it sends the device power IRP to its stack.
System
power IRP should also proceed down. If you don’t see the system power
IRP in
the PDO, something is wrong. One reason is IoStartNextPowerIrp might
not be
called for the previous system power IRP.

I’m pretty sure that’s a bug in scsiport that I’ll just have to deal
with. The system power IRP never makes it to my PDO. I actually tried
injecting the system power IRP to see if it makes a difference, and
while WDF seemed happier and the state of the devices seemed more
consistent, it didn’t actually fix the problem.

ALso, check ALL device objects in your PDO and FDO stack for
DO_POWER_PAGABLE.
That’s what I means in the previous message. ALL device objects. If
your bus
driver has other PDOs, check them also.

I went through all device stacks enumerated by by bus and the only thing
marked as DO_POWER_PAGABLE is xennet (NDIS driver), which is the FDO for
another PDO enumerated by my bus driver. That PDO is not marked as
DO_POWER_PAGABLE though. Should that matter? If I consider the PCI bus,
every FDO that attaches to its PDO’s doesn’t have to be not
DO_POWER_PAGABLE does it?

James

Check that PoStartNextPowerIrp is properly called for system power IRPs. If it’s not called, your driver may work OK under Vista+ guest, but fail under earlier OS (XP, 2003).

KMDF will do that for you, unless you have some non-standard processing for power IRPs.

>

Check that PoStartNextPowerIrp is properly called for system power
IRPs. If
it’s not called, your driver may work OK under Vista+ guest, but fail
under
earlier OS (XP, 2003).

KMDF will do that for you, unless you have some non-standard
processing for
power IRPs.

Hmmm… that sounds plausible. No non-standard power processing in my
driver… I wonder if scsiport is forgetting to call that somewhere
along the way. It’s strange that it’s consistently on the 3nd hibernate
resume though. I already know it’s doing something wrong:

Sat Apr 23 23:19:28.013 2011 (GMT+10): POSTPONED WDM DRIVER BUG:
Sat Apr 23 23:19:28.310 2011 (GMT+10): [SCSIPORT.SYS @ 0xBA5BA44C]
Sat Apr 23 23:19:28.607 2011 (GMT+10): Caller has completed
Sat Apr 23 23:19:28.982 2011 (GMT+10): successful IRP_MJ_POWER instead
of passing it down
Sat Apr 23 23:19:29.216 2011 (GMT+10): (Irp =
812230B8 ).
Sat Apr 23 23:19:29.513 2011 (GMT+10): IRP_MJ_POWER.
Sat Apr 23 23:19:29.591 2011 (GMT+10): IRP_MN_SET_POWER
Sat Apr 23 23:19:29.638 2011 (GMT+10): (
Sat Apr 23 23:19:29.919 2011 (GMT+10): PowerSystemWorking.S0
Sat Apr 23 23:19:29.982 2011 (GMT+10): .PowerActionSleep
Sat Apr 23 23:19:30.045 2011 (GMT+10): )
Sat Apr 23 23:19:30.326 2011 (GMT+10): [ DevObj=81685708,
FileObject=00000000, Parameters=00000000 00000000 00000001 00000002 ]
Sat Apr 23 23:19:30.623 2011 (GMT+10):
http://www.microsoft.com/hwdq/bc/default.asp?os=5.1.2600&major=0xc9&mino
r=0x231&lang=0x9

Strange that this error is shown as “Fatal Error” in the docs for 0xc9
but the verifier just keeps on going… Microsoft would have noticed
scsiport’s misbehaviour a long time ago if it had crashed like its
documentation says it should

James

We have filed several scsiport bugs which is very annoying to me and required some ugly hacks in the mini port. They are acknowledged (support credit refund), but I was told there is no “business case” to fix it.

Tentative at the moment but I think I’ve resolved the problem. I found
that on the 3rd resume from hibernation, which is when it hangs, the
first SRB (SCSIOP_START_STOP_UNIT) makes it as far as
AllocateAdapterChannel but the AdapterControl (which would call my
StartIo) never gets called. This is inside the
BUS_INTERFACE_STANDARD/DMA_ADAPTER that I pass through from pci.sys, so
I’m not exactly sure why this happens, but the mistake on my part was
setting Master in my scsiport PORT_CONFIGURATION_DATA when I don’t
actually need DMA logical addresses at all anyway.

So there’s a whole lot of time I’ll never get back!!!

James