I do believe that KMDF decision is too aggressive.
I looked at the Sx->S0 logic and I oversimplified/misspoke for one case
If (idle not enabled or idle enabled and capable of S0 Wake) {
GotoD0()
}
Else {
// idle enabled, not wake capable
If (there is a power ref) {
GotoD0()
}
Else {
RemainInDx();
}
}
So, we remain Dx regardless of the device power state in the previous
S0 if you are idle capable (but not able to wake) and there is no reason
to put your device back into D0. Is this not respecting the idle
timeout? Yes. Is it wrong behavior? Not entirely. One of the design
points for KMDF was to aggressively turn off the device when not in use
and this could be considered one of those cases. Like I mentioned
before, a power managed queue or a call to WdfDeviceStopIdle will fix
this for you. I will file a bug to consider only keeping the device in
Dx in the idle enabled/not wake capable case if the device was
previously in Dx in the previous S0.
d
*From:* Guy Corem [mailto:xxxxx@aptocom.com]
*Sent:* Friday, June 22, 2007 5:39 PM
*To:* Doron Holan
*Cc:* Windows System Software Devs Interest List
*Subject:* Re: kmdf - powering down a device
No.
In all cases the device was in D0 before the Sx->S0 transition.
In all cases, I observe a call to D0Exit during the sleep transition.
Only in case 2, I don’t observe a call to D0Entry upon S0->Sx back
transition.
Guy
Doron Holan wrote:
Let’s see if I can condense this to one answer for all cases.
The only time you will remain in Dx after an Sx->S0 transition is if you
were idled out and in Dx when you were in S0 before the Sx occurred.
This means that if you never assign S0 idle settings, you will always be
in D0 upon Sx->S0 b/c you never told the framework the device could be
in Dx while in S0. This also means that when you set a tremendously
long timeout, the device is still in D0 when we go to Sx, so we put it
back into D0 when we come back b/c obviously the timer has not yet
expired.
Make a little more sense now?
D
-----Original Message-----
From: Guy Corem [mailto:xxxxx@aptocom.com]
Sent: Friday, June 22, 2007 5:20 PM
To: Doron Holan
Cc: Windows System Software Devs Interest List
Subject: Re: kmdf - powering down a device
Doron,
Thanks(!) for clarifying the issue around WdfDeviceStopIdle and
EvtDeviceAdd.
I’ve recoded according to your advice (using
EvtDeviceSelfManagedIoInit), and it worked like charm.
I’ve enjoyed very much to delete the IRP_MN_SET_POWER post-processing
code…
Just lost a day around this issue. I should have emailed as soon as I
observed the strange WdfDeviceStopIdle behavior.
Regarding “device remaining in Dx after resuming from Sx is by design”:
Just for completion, I suspect another bug. During my trials, I’ve
encountered the following (just verify it again now):
-
Using power managed default queue. No request in it.
-
Using secondary non power managed queue. One request pending in it.
-
WdfDeviceStopIdle wasn’t call at all
-
WdfDeviceAssignS0IdleSettings wasn’t call at all.
If I understood your reply, there is no outstanding power references.
Nevertheless, upon transition back to S0, the framework calls
/EvtDeviceD0Entry/
Starting from this “baseline”, I’ve started to modify:
- Switching to non-power managed default queue. The framework *does*
call /EvtDeviceD0Entry/ upon transition back to S0
- Adding a call to WdfDeviceAssignS0IdleSettings with MAXULONG timeout,
non-power managed default queue. The framework *doesn’t* call
/EvtDeviceD0Entry/ upon transition back to S0
- Switching back to power managed default queue, calling
WdfDeviceAssignS0IdleSettings with MAXULONG timeout. The framework
*does* call /EvtDeviceD0Entry/ upon transition back to S0
In all the above cases, there was no pending requests in the default
queue, and one pending request in the secondary non power managed queue.
If it’s “by design”, I really don’t understand the logic behind it.
Thanks again,
Guy
Doron Holan wrote:
WdfDeviceStop/ResumeIdle are what you want to use in your current
design. They are the manual way for you to change the idle state of
the
device.
Assigning the idle settting and then immediately calling
WdfDeviceStopIdle in AddDevice fails b/c the power idle state machine
is
not started, that would be a bug in KMDF that we don’t respect that
call
so early in device creation. To work around this issue, call
WdfDeviceStopIdle in EvtDeviceSelfManagedIoInit. By doing this in
SelfManagedInit, you can set the idle timeout to 1 ms during AddDevice
and never change the timeout value itself.
The power down will still be asynchronous. This is fine as long you
either handle STATUS_PENDING returned from WdfDeviceResumeIdle (if you
pass FALSE) or always call WdfDeviceResumeIdle with TRUE so it will
block until you return D0. Note that you will have to synchronize
your
manually managed power state with an Sx power down. Remember, for an
Sx
power down, the device’s idle settings do not have any effect, the
device is going to be powered down *now*. In a normal driver, the
power
managed queue waits for /acknowledges in flight requests to complete
before powering down, you will have to manually stop processing
requests
from your manual queue in EvtDeviceSelfManagedIoSuspend (probably by
stopping the queue, but I am not sure about that).
The device remaining in Dx after resuming from Sx is by design if
there
are no outstanding power references on the device (why put the device
back into a powered up state if nothing in the driver requires it have
power?). A request in a power managed is a reference, as is a call to
WdfDeviceStopIdle. As long as you have called WdfDeviceStopIdle
without
a matching WdfDeviceResumeIdle, your device will be powered on upon
returning to S0.
So that in a nutshell is how to do this in your current design. I
think
though that you can leverage power managed queues more then you are
today. Instead of having one non power managed manual queue for all
of
your IOCTLs, create a parallel non power managed queue as the top
level
dispatching queue for your IOCTLs. You then have different sub queues
which could be power managed or not. I would think you would have one
power managed manual queue and one non power managed manual queue.
You
then route the IOCTL requests from the top level parallel queue into
the
appropriate subqueue. For instance, the power own IOCTL is put into
the
power managed queue, as are the notifications for interrupts. The
power
down ioctl would be placed in the non power managed queue. You can
divvy it up as much as you like as you see fit…
d
-----Original Message-----
From: Guy Corem [mailto:xxxxx@aptocom.com]
Sent: Friday, June 22, 2007 3:05 PM
To: Doron Holan
Cc: Windows System Software Devs Interest List
Subject: Re: kmdf - powering down a device
Hi Doron,
First, A little bit about my driver.
I’ve implemented a user space I/O driver: A kernel driver that maps a
PCI card memory mapped ranges to a user mode client virtual address,
and
notify about interrupts and D0Entries / Exits via pending IOCTLs
(which
the driver store in non power managed, manual dispatch queue).
The driver is providing the following IOCTL interface: Get memory
mapped
ranges, query device property, indicate status (for pending
notifications), power down and power up.
Using power managed main queue will defeat my purposes. Consider the
following scenario:
- The application is sending an indicate status IOCTL, which the
driver
keeps (pend) in the secondary manual dispatch queue. The application
is
sending this IOCTL asynchronously (using overlapped structure) or from
a
dedicated notification thread.
- Later, the application is sending power down IOCTL. The driver will
transition to D3 using (indeed) 1 timeout value in the call to
WdfDeviceAssignS0IdleSettings.
-
The device D3Exit event will be called.
-
The D3Exit event will complete the pending notification IOCTL.
-
The application will send another notification IOCTL, and since the
default queue is power managed, the device will transition back to
D0…
After a lot of trials, I’ve settled on the following implementation:
(If you’ll suggest a better one, I’ll be happy to switch…)
-
I’m using a non power managed default queue.
-
Powering Up is setting MAXULONG as the timeout value
(WdfDeviceAssignS0IdleSettings ). This is *UGLY* since after ~49.7
days,
the device will power down automatically…
-
Powering Down is setting 1 as the timeout value
-
I don’t know why (bug?), but when resuming from hibernation, if the
device was in D0 before the hibernation and the default queue is not
power managed, the framework DOESN’T switch the device back to D0.
I’ve overcome this problem by post-process the IRP_MN_SET_POWER
transition to S0, and “powering up” the device back manually, as
described in 2.
During my trials, I’ve encountered also the following strange
behavior:
Despite a call to WdfDevieStopIdle (from DeviceAdd, after setting the
idle timeout value), the framework, nevertheless, transition the
device
to D3 when the timeout expire…
I’m testing on Vista64.
I’m compiling against KMDF 1.7 headers (WDK 6001), but linking against
KMDF 1.5 libraries (WDK 6000)
[My sources file contain the following lines:
KMDF_VERSION_MINOR=5
KMDF_LIB_PATH=KMDF1.5 libs path*]
Sorry for my long email, and thanks,
Guy
Doron Holan wrote:
By “just now” do you mean “right now at this very instant”? If that
is
what you mean, no KMDF does not support this model for idling out in
S0
(it does support this for powering off due to an Sx transition
though).
But like I said, you can get nearly now behavior by setting an
extremely
short timeout when assign s0 idle settings. Why would you need "off
right now" for S0 idle?
If you don’t want to reassign the idle timeout all the time, you
could
explicitly disable idle by calling WdfDeviceStopIdle and then calling
WdfDeviceResumeIdle. Usually you control this behavior by routing
i/o
through power managed queues instead of explicitly managing the idle
state with these DDIs.
d
-----Original Message-----
From: xxxxx@lists.osr.com mailto:xxxxx
>
> [mailto:xxxxx@lists.osr.com] On Behalf Of Maxim S.
>
> Shatskih
>
> Sent: Friday, June 22, 2007 7:38 AM
>
> To: Windows System Software Devs Interest List
>
> Subject: Re:[ntdev] kmdf - powering down a device
>
>
>
>
>
> Can KMDF’s PPO implementation be ordered to initiate power down
>
> “just now”?
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
></mailto:xxxxx>