PCIe device bring up question

The ability of a PCIe endpoint to issue memory, and I/O Read/Write Requests, and
the ability of a Root or Switch Port to forward Memory and I/O
Read/Write Requests in the Upstream direction depends on someone setting bit 2 in the Command Register. This is the Bus Master Enable bit.

On an x86-based computing running Windows 7, who is responsible for setting this bit?

Here’s some hardware layout details:
CPU PCI Bridge ----> root bridge at Bus0:Dev30 -----> root port at Bus0:Dev28 ----->my card at Bus5:Dev0

Here’s the device stack:
\Driver\myDriver
\Driver\mf

On say resume from D3, does the pci.sys driver enumerate the bus and set the Bus Master Enable Bit? Is it the responsibility of mf.sys in this case? As far as my WDF driver is concerned it simply gets it’s D0Entry function called.

I’m running into the case where this is called BEFORE the Bus Master Enable Bit is set. Who’s to blame?

After your driver forwards IRP_MN_START_DEVICE to PCI.SYS, and it completes, the device is guaranteed to have the BARs enabled.

I don’t know if you need to call IoAllocateDmaAdapter to have bus master bit set, but try that.

The essential part I failed to mention was WHEN I’m observing that the BARs aren’t enabled. I’m breaking first thing in D0Entry.

Do you have all the mandatory power management descriptors in your config space?

As far as I know. Anything specifically you think I should look at?

It’s my understanding that in Apple systems it’s the responsibility of the PCI host controller to configure the controller in such a way that the rest of the PCI subsystem can talk
to devices behind it. This means interrupt assignment, address range assignment and configuring the devices on the bus (which includes setting the Bus Master Enable bit). I assume this is pretty much the standard procedure in Windows too.

I’m able to see that the interrupt and address range has been assigned appropriately, but that bus master enable is not yet set. This is happening on a resume from sleep/hibernate.

I “COULD” go set it myself, but I’m more concerned about why it isn’t enabled by the time my D0Entry is called. Remember this is in a PCIe endpoint device. I have to believe that typically BAR I/O is enabled BEFORE KMDF calls a device’s D0Entry. There are few different ways I can see this working. (1) BIOS brings up all the devices on wake from sleep/hibernate (2) The root port enables the devices on the bus that it services (3) Windows PCI.sys restores the devices to their previous working (4) The process of re-enabling goes PCI->MF.sys->my device and MF.sys isn’t enabling in a timely manner.

Alex also asked about the power management capabilities. Looks like PwrMgmtCap = 0003 (Version=3), PwrMgmtCtrl =0000. These values are the same in both the working and non-working state.