Ok,
I’ll admit it: you guys are pretty smart. Michael had it just about
right (below). The problem was in the PM handling of the power state
transition.
As I mentioned, I am using Walter Oney’s sample code pretty much
out-of-the-box. The problem was in the following function:
////////////////////////////////////////////////////////////////////////
// GetLowestDevicePowerState returns the lowest device power state
// that is consistent with a given system power state and the current
// wakeup state of the device.
DEVICE_POWER_STATE GetLowestDevicePowerState(PDEVICE_EXTENSION pdx,
SYSTEM_POWER_STATE sysstate)
{
DEVICE_POWER_STATE maxstate = pdx->devcaps.DeviceState[sysstate];
DEVICE_POWER_STATE minstate = PowerDeviceD3;
DEVICE_POWER_STATE dstate = minstate > maxstate ?
minstate : maxstate;
// TODO choose a different dstate here if you want to
return dstate;
}
A system resume transitions to system state PowerSystemWorking, in which
case maxstate is PowerDeviceD0 (value: 1) and minstate is PowerDeviceD3
(value: 4). The sample code above will always return PowerDeviceD3,
since 4 is the highest-valued device power state. In my driver, then,
the post-resume device state was PowerDeviceD3 (same as before) and so
the power IRP processing was short-circuited.
I don’t know if I’m interpreting the code correctly, but I imagine the
“minstate” variable is a global override for the devcaps setting. So I
changed the code to:
DEVICE_POWER_STATE dstate = maxstate > minstate ?
minstate : maxstate;
So if set minstate to PowerDeviceD2 (value: 3), I’m saying that the
lowest power state I want to go to (regardless of system state) is D2.
If the devcap value (maxstate) is D3, then the minstate value of D2 will
be used instead as the new state value.
Anyway, now that all the PowerUp processing is actually happening the
hardware is working fine. Thanks to everybody for their help on this
problem.
What Doran said earlier now seems more compelling:
Obligatory plug: if you are going through the effort of rewriting the
driver, you should really consider KMDF (kernel mode driver framework).
It will remove the complexity from your code with respect to how/when to
power up your device.
My OSR book pre-order is already in …
– David
Eschmann, Michael K wrote:
I’m no PCMCIA expert, but your problem does look familiar.
When you get a resume S-IRP (S0) are you requesting and then passing a
D0 IRP down the stack? You must then wait for the bus driver to
complete the D-IRP, and only then re-initializing your device after the
bus driver has turned on the device? I’d bet the remove, then add is
working because the PNP path is acceptably implemented, but the PM side
is not.
MKE.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David Lavo
Sent: Wednesday, November 09, 2005 4:07 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] PCMCIA card and resume from suspend
I think my question was badly phrased, since I didn’t mean to imply that
my START_DEVICE handler could fix up the hardware. My START_DEVICE code
is pretty simple - parse the assigned resources, save them off and map
the memory space.
My *guess* is that the hardware is getting into an invalid state when it
returns from suspend. By disabling and re-enabling the device, I
imagine that the bus is going through the normal re-initialization and
querying of the hardware and that is enough to reset it to a valid
state. Since I don’t (yet) have any docs about the hardware at all, I
don’t know if this a valid guess, but what else does a disable/enable
cycle do?
Thanks …
Tim Roberts wrote:
>David Lavo wrote:
>
>
>>I understand what you’re saying - the correct place to do this reinit
>>is at these power state transition points. But I don’t know how to
>>actually do the reinit: I don’t have enough information about the
>>hardware itself to do so directly, but it seems that having the bus
>>reinitialize the device works just fine.
>>
>>So how do I either generate a STOP[START]_DEVICE myself, or force the
>>bus to restart/reassign the device?
>
>
>I’d like to expand just a bit on Doron’s reply to emphasize the
>disconnect here.
>
>STOP_DEVICE and START_DEVICE are not commands to the hardware or to
the
>bus. Rather, they are simply messages that tell you that something
>happened. If your device gets fixed up during START_DEVICE
processing,
>that means that YOUR DRIVER fixed it up in its START_DEVICE handler.
>That suggests that you need to run your START_DEVICE handler when you
>come out of suspend.
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@intel.com
To unsubscribe send a blank email to xxxxx@lists.osr.com