- Questions on PCI config space when ressetting a PCI board
- Posted by User1964 on February 27th, 2004
Hi,
I'm developing a wdm driver under Win2K for a proprietary PCI board.
Unfortunately, the board's PCI interface logic is part of a FPGA that can
only be fully reset by reconfiguring the FPGA. We foresee that we need to
reset our board on certain occasions and we do not want to power-cycle our
system for this.
Therfor, I'm implementing the following reset sequence in my driver:
Because the reconfiguration of the FPGA resets the PCI config space, I start
with saving this data (after having disabled the boards PCI interface). I
then call PoRequestPowerIrp to force the board to go to device state D3. In
the IoCompletion routine, PoRequestPowerIrp is called again to force the
board to go back to device state D0 (this actually resets our FPGA and the
PCI config space). In the IoCompletion routine of the second
PoRequestPowerIrp, I restore the PCI config space data and reenable the PCI
interface.
When, in the above scheme, I use the sequence
IoBuildAsynchronousFsdRequest() - IoSetCompletionRoutine() - IoCallDriver()
to read or write the PCI configuration space, this completion routine is
called with DeviceObject = NULL. I solve this by passing the DeviceObject
via the 'context' of the completion routine. Is this normal or could I be
doing something wrong here?
Apart from the above problem the sequence seems to work, but I am not sure
wether I should also save and restore the power management registers of the
PCI config space. Or should I leave this to the pci.sys bus driver who does
the actual D0/D3/D0 switching ?
Also, I'm not sure that the above will work under all circumstances so I
would appreciate it if anybody knows where to find some more info on stuff
like this.
Thanks in advance,
Koen
- Posted by Calvin Guan on February 27th, 2004
Getting DeviceObject==NULL is normal in this case. To get around this, you
can use IoAllocateIrp to allocate 1 more stack space.
Sound like a nice idea but not sure if MS would like it.
I would try to call IoInvalidateDeviceState and response to a subsequent
IRP_MN_QUERY_PNP_DEVICE_STATE with PNP_RESOURCE_REQUIREMENTS_CHANGED. By
doing this, the PnP manager should send the driver a MN_START_DEVICE, then
you pass this to pci.sys. PCI.sys would power up you device and re-config
the PCI config space for you. But I think the best thing is to get the H/W
fixed.
Good luck!
-
Calvin Guan Software Engineer
ATI Technologies Inc. www.ati.com
- Posted by Maxim S. Shatskih on February 28th, 2004
In order for DeviceObject != NULL in the IRP completion routine, you must
allocate the IRP with 1 more stack location then necessary, and call
IoSetNextIrpStackLocation on it just after allocation. Then fill
IoGetCurrentIrpStackLocation(Irp)->DeviceObject manually.
'Context' is always passed though.
The 'DeviceObject' parameter for the completion routine is intended for drivers
who pass down the IRPs received from the upper edge, and not for the drivers
who create their own IRPs. Use 'Context' instead.
Yes, leave it to the bus driver.
Can work. At least - it can. The technology you use is very similar to idle
detection, and so, it can work, provided you will deal with races between your
"power management" and global system standby/resume sequences.
I dunno whether the motherboard will be capable of powering down the PCI slot.
Also IIRC - PCI does not support powering down 1 slot. So, the power will
probably remain. And this means - there will possibly be some ways of pinging
your FPGA to reset, by means of config space I think.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
- Posted by User1964 on March 1st, 2004
"Calvin Guan" <cguan@pleasenospam.ati.com> wrote in message
news:upt0f$U$DHA.3452@TK2MSFTNGP11.phx.gbl...
Calvin,
Thanks for your reply. I like the suggestion to use IoInvalidateDeviceState,
I'll give it a try later this week.
Fixing the HW however isn't an option since this would increase the cost of
our board too much.
Best regards,
Koen
- Posted by Calvin Guan on March 1st, 2004
"Maxim S. Shatskih" <maxim@storagecraft.com> wrote in message
news:%23OIkkMl$DHA.2576@tk2msftngp13.phx.gbl...
That was what I've observed.
Instead, the PCI.SYS can command the PCI device to certain Dx state by
writing to the PM_CAP in pci cfg space for certain device classes. For
instance, a non-bridge class PCI device will be powered down then up in such
way before you regain control from MN_START_DEVICE. All PM capable device
should response to those PM command correctly.
Calvin
-
Calvin Guan Software Engineer
ATI Technologies Inc. www.ati.com
- Posted by Maxim S. Shatskih on March 3rd, 2004
OK, then the solution is - to send the power IRP to itself - the same way as
idle detection works - and then immediately send a power-up IRP.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com