Re: WDF: Zeroed CMD register in PCI config space

Sinnet del Reccos wrote:

…We have found that the failure on Windows 7 for that PCI-card is that it has zeroed Command register (CMD) in PCI config space. It is just 0x0000 after the driver starts, so we could not even read/write memory port of the device: read returns 0xFFFFFFFF in W7 x64 and 0x00000000 in W7 x32. However all the device resources claimed successfully with the sensible addresses (BAR, Memory I/O and IRQ). When we manually (by Jungo DriverWizard) reset the CMD to 0x0006 - our PCI-card works fine.

Does anybody know what driver routines makes the system zero the CMD register ? Or maybe there is something we missed in resource claiming under Windows 7 ?

Are you returning an error in any of your PnP handlers, like AddDevice
or StartDevice? Has your device passed any PCI compliance tests?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Every EvtXXX callback routine return success on driver start: EvtDeviceAdd, EvtDevicePrepareHardware, etc. Also we analyze return values after each corresponding function call - everything goes fine: NT_SUCCESS(status) eq TRUE.

We have not yet tested the device by WLK or any other hardware compliance tests. But if it could give us any tip on how to get rid of getting the CMD register zeroed we are on our way to make them…


Best regards,
Sinnet del Reccos

>Every EvtXXX callback routine return success on driver start: EvtDeviceAdd, >EvtDevicePrepareHardware, etc. Also we analyze return values after each corresponding function call >- everything goes fine: NT_SUCCESS(status) eq TRUE. We have not yet tested the device by WLK >or any other hardware compliance tests. But if it could give us any tip on how to get rid of getting >the CMD register zeroed we are on our way to make them…

It should not be difference between Win7 and early version of Windows how PCI register initialized.
In fact it should be done by BIOS but probably Windows doing something else. I would suggest to run the check build version version of PCI.sys with enabled debug output. You may get some additional information. If this would not help you should to use PCI bus analyzer and see where the register set up or clear up.

Igor Sharovar

xxxxx@mail2k.ru wrote:

We have not yet tested the device by WLK or any other hardware compliance tests. But if it could give us any tip on how to get rid of getting the CMD register zeroed we are on our way to make them…

What I’m suggesting is that there may be a problem in your PCI
configuration space or your PCI bus behavior that violates the PCI spec
in some way, a way that XP didn’t care about but Win 7 does.
Desk-checking of the config space would be a good plan, and Igor’s
suggestion to run a checked build is a good tip. Make sure the fields
that are supposed to be read-only really are.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

We have a KMDF driver for our PCI/PCIe cards that works on XP-32, Vista-32, W7-32 and W7/S8-64 all with the same source code using WdfRequestIsFrom32BitProcess() where necessary.

When a read gives 0xFFFFFFFF can mean a bus error. Have you run Verifier on your driver and pci.sys?
Have you stepped through the initialization/adddevice to see what your PCI Config Space looks like?

Larry C

> We have not yet tested the device by WLK or any other hardware compliance tests. But if it could give us any tip

on how to get rid of getting the CMD register zeroed we are on our way to make them…

Try running with a checked version of pci.sys (as also acpi.sys + HAL).

Probably your device violates the PCI spec, XP was more permissive, and Win7 is stricter.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Sinnet del Reccos wrote:

Dear NTDEV,

Does anybody know what driver routines makes the system zero the CMD
register ? Or maybe there is something we missed in resource claiming
under Windows 7 ?

I’ve seen a similar problem with this on some hardware which didn’t have
any support for PCI power management descriptors in the configuration
space. When stepping through the drive code for this device the CMD
register was correctly enabled right up until the START_DEVICE PNP
request was passed down to the PCI bus driver. This also only occurred
on Windows 7.

Since I was under time pressure to fix it I added code after the start
device IRP was completed by the lower driver to re-enable the
appropriate bits in the CMD register myself.

The device I was working on only used IO ports and didn’t need to be
interrupt driven (very low throughput) so Ive no idea if the same trick
will work for a device which requires interrupt processing.

Finding out if you have any PCI non-compliances is also a good idea. I’d
be interested to know if you do find out what is going on.

Mike


Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: xxxxx@mpcdata.com web: www.mpcdata.com
tel: +44 (0) 1225 710600 fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635

MPC Data Limited is a company registered in England and Wales with
company number 05507446
Registered Address: County Gate, County Way, Trowbridge, Wiltshire,
BA14 7FJ
VAT no: 850625238

The information in this email and in the attached documents is
confidential and may be legally privileged. Any unauthorized review,
copying, disclosure or distribution is prohibited and may be unlawful.
It is intended solely for the addressee. Access to this email by anyone
else is unauthorized. If you are not the intended recipient, please
contact the sender by reply email and destroy all copies of the original
message. When addressed to our clients any opinions or advice contained
in this email is subject to the terms and conditions expressed in the
governing contract.

Thank you all for the answers.

We still cant get the device to work properly in Windows 7 x32/x64.

Host W7 x64 WinDBG used with 1394 connection to target W7 x64 checked build system.
Two breakpoints set: 1) on EvtDeviceAdd and 2) on EvtDevicePrepareHardware. No more code between those two calls. At the target machine “!pci” command in WinDBG used to print out the PCI config space of the device.

So, the driver starts and at the first bp the CMD register is 0x06. It is still 0x06 at the end of EvtDeviceAdd - before “return STATUS_SUCCESS”. And at the beginning of EvtDevicePrepareHardware it is already 0x00 !

There is no (our) code to step between those two callbacks. No suspicious debug strings in output from checked system.

  1. We are also trying to find out some in compliance tests.
    We can ask the hardware developers to make some changes to the device but do not realize which of 'em.
  2. Probably manual reset CMD to 0x06 could be helpful a bit. But the write to PCI config CMD register using a) IRP_MJ_PNP, IRP_MN_WRITE_CONFIG or b) SetBusData is not working: the written value (0x06, 0xFF, 0xFFFF) then became at read to 0x00 on W7 x64, 0x02 - on W7 x32.

Dunno how Jungo WinDriver makes our CMD be 0x06 after the same PCI config writes.
Maybe that procedure should be executed at some special place ? (We’ve tried it in EvtDevicePrepareHardware, EvtDeviceD0Entry/Exit and by IOCTL from user space)


Best regards,
Sinnet del Reccos

Not sure on that one but Jungo breaks the rules elsewhere with the
attitude, “it will look like someone else’s bug”. I never go near that
product if I can help it, and then only to suggest the client get rid of
it.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@mail2k.ru” wrote in message
news:xxxxx@ntdev:

> Thank you all for the answers.
>
> We still cant get the device to work properly in Windows 7 x32/x64.
>
> Host W7 x64 WinDBG used with 1394 connection to target W7 x64 checked build system.
> Two breakpoints set: 1) on EvtDeviceAdd and 2) on EvtDevicePrepareHardware. No more code between those two calls. At the target machine “!pci” command in WinDBG used to print out the PCI config space of the device.
>
> So, the driver starts and at the first bp the CMD register is 0x06. It is still 0x06 at the end of EvtDeviceAdd - before “return STATUS_SUCCESS”. And at the beginning of EvtDevicePrepareHardware it is already 0x00 !
>
> There is no (our) code to step between those two callbacks. No suspicious debug strings in output from checked system.
>
> 1. We are also trying to find out some in compliance tests.
> We can ask the hardware developers to make some changes to the device but do not realize which of 'em.
> 2. Probably manual reset CMD to 0x06 could be helpful a bit. But the write to PCI config CMD register using a) IRP_MJ_PNP, IRP_MN_WRITE_CONFIG or b) SetBusData is not working: the written value (0x06, 0xFF, 0xFFFF) then became at read to 0x00 on W7 x64, 0x02 - on W7 x32.
>
> Dunno how Jungo WinDriver makes our CMD be 0x06 after the same PCI config writes.
> Maybe that procedure should be executed at some special place ? (We’ve tried it in EvtDevicePrepareHardware, EvtDeviceD0Entry/Exit and by IOCTL from user space)
>
> –
> Best regards,
> Sinnet del Reccos

wrote in message news:xxxxx@ntdev…


> Two breakpoints set: 1) on EvtDeviceAdd and 2) on
> EvtDevicePrepareHardware. No more code between those two calls. At the
> target machine “!pci” command in WinDBG used to print out the PCI config
> space of the device.
>
> So, the driver starts and at the first bp the CMD register is 0x06. It is
> still 0x06 at the end of EvtDeviceAdd - before “return STATUS_SUCCESS”.
> And at the beginning of EvtDevicePrepareHardware it is already 0x00 !
>
> There is no (our) code to step between those two callbacks. No suspicious
> debug strings in output from checked system.

Between EvtDeviceAdd and EvtDevicePrepareHardware the PCI bus driver could
do lot of things.

> …
> But the write to PCI config CMD register using a) IRP_MJ_PNP,
> IRP_MN_WRITE_CONFIG or b) SetBusData is not working: the written value
> (0x06, 0xFF, 0xFFFF) then became at read to 0x00 on W7 x64, 0x02 - on W7
> x32.

This too can be work of the PCI driver. It may filter writes to the command
register or do something else besides of the write.

> Dunno how Jungo WinDriver makes our CMD be 0x06 after the same PCI config
> writes.
> Maybe that procedure should be executed at some special place ? (We’ve
> tried it in EvtDevicePrepareHardware, EvtDeviceD0Entry/Exit and by IOCTL
> from user space)

Windriver is a development tool after all, it is made to deal with buggy
hardware.
Won’t be surprise if it can write to the config space bypassing the PCI
driver.

Good luck with fixing the device (or FPGA or whatever it has, may Cadence be
with you!)
–pa

xxxxx@mail2k.ru wrote:

Thank you all for the answers.

We still cant get the device to work properly in Windows 7 x32/x64.

Host W7 x64 WinDBG used with 1394 connection to target W7 x64 checked
build system. Two breakpoints set: 1) on EvtDeviceAdd and 2) on
EvtDevicePrepareHardware. No more code between those two calls. At
the target machine “!pci” command in WinDBG used to print out the PCI
config space of the device.

So, the driver starts and at the first bp the CMD register is 0x06.
It is still 0x06 at the end of EvtDeviceAdd - before “return
STATUS_SUCCESS”. And at the beginning of EvtDevicePrepareHardware it
is already 0x00 !

Ah. That sounds like the same problem I was seeing. While I’m not a KMDF
expert (my driver programming time predates the existence of KMDF) the
slot between EvtDeviceAdd and EvtDevicePrepareHardware is where the KMDF
framework sends the WDM PNP IRP_MN_START_DEVICE request to the PCI bus
device driver. It will then call EvtDevicePrepareHardware when the PCI
bus driver completes the IRP. It will then call EvtDeviceD0Entry at a guess.

  1. We are also trying to find out some in compliance tests. We can
    ask the hardware developers to make some changes to the device but do
    not realize which of 'em. 2. Probably manual reset CMD to 0x06 could
    be helpful a bit. But the write to PCI config CMD register using a)
    IRP_MJ_PNP, IRP_MN_WRITE_CONFIG or b) SetBusData is not working: the
    written value (0x06, 0xFF, 0xFFFF) then became at read to 0x00 on W7
    x64, 0x02 - on W7 x32.

A quick read of the KMDF docs suggests you should do the CMD register
write in EvtDeviceD0Entry.

It should be valid write PCI configuration space for your device in
EvtDeviceD0Entry as the device SHOULD be powered up at that point. If
writes to the CMD register at that point in time do not persist in the
CMD register of your device then you have found your hardware problem.
as the system provided PCI bus driver will rewrite that register during
EvtDeviceAdd and EvtDevicePrepareHardware as part of the normal WDM PNP
state machine transition. I’d also suggest posting the code that you
used to attempt the config space access. It is possible some coding
error in that piece of code was the reason why the CMD register could
not be written.

Mike

Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: xxxxx@mpcdata.com web: www.mpcdata.com
tel: +44 (0) 1225 710600 fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635

MPC Data Limited is a company registered in England and Wales with
company number 05507446
Registered Address: County Gate, County Way, Trowbridge, Wiltshire,
BA14 7FJ
VAT no: 850625238

The information in this email and in the attached documents is
confidential and may be legally privileged. Any unauthorized review,
copying, disclosure or distribution is prohibited and may be unlawful.
It is intended solely for the addressee. Access to this email by anyone
else is unauthorized. If you are not the intended recipient, please
contact the sender by reply email and destroy all copies of the original
message. When addressed to our clients any opinions or advice contained
in this email is subject to the terms and conditions expressed in the
governing contract.

More to this - it may be perfectly OK that the CMD register is zeroed
before the driver gets EvtDevicePrepareHardware callback.
Bit 0x2 in the CMD register turns on memory address decoders.
Until PnP together with pci.sys has its resource allocation magic done,
you don’t want to enable decoders, because you don’t know the values to
write into the BARs. The system sets the proper physical addresses in the
BARs.

The BIOS likely will initialize your BARs and CMD register and WinXP likely
will leave this choice intact, but Win7 is more aggressive, it may
shuffle resources allocated by BIOS, so it will zero your CMD reg
to prevent your device from accessing random memory addresses.

Why pci.sys won’t allow to set bit 4? This bit enables bus master operation.
Have you specified to KMDF that the device is bus master capable?

– pa

  1. To read/write CMD register of hte PCI config space we used 1) WinDBG: “!pci 0x100 8 1 0” / “!ecw 8.1.0 4 0xFFFF” and 2) Read(Write)PCIConfig routines:

PDEVICE_OBJECT pdo;
DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) UCHAR buffer[PCI_COMMON_HDR_LENGTH];
PPCI_COMMON_CONFIG pPciConfig = (PPCI_COMMON_CONFIG) buffer;

NTSTATUS
ReadPCIConfig(
IN PDEVICE_CONTEXT pContext
)
{
PAGED_CODE();

pdo = WdfDeviceWdmGetDeviceObject(pContext->WdfDevice);
return ReadWriteConfigSpace(pdo, 0, buffer, 0, PCI_COMMON_HDR_LENGTH);
}

NTSTATUS
WritePCIConfig(
IN PDEVICE_CONTEXT pContext
)
{
PAGED_CODE();

pdo = WdfDeviceWdmGetDeviceObject(pContext->WdfDevice);

// Set CMD register manually
pPciConfig->Command = 0xFFFF;
return ReadWriteConfigSpace(pdo, 1, buffer, FIELD_OFFSET(PCI_COMMON_CONFIG, Command), sizeof(pPciConfig->Command));
}

…and the ReadWriteConfigSpace routine we’ve used from some PCI config space read/write example:

NTSTATUS
ReadWriteConfigSpace(
__in PDEVICE_OBJECT DeviceObject,
__in ULONG ReadOrWrite,
__in PVOID Buffer,
__in ULONG Offset,
__in ULONG Length
)
/*++
Routine Description:

Worker function to read & write to PCI config space at
PASSIVE_LEVEL

Arguments:

DeviceObject - Pointer to the PDO
ReadOrWrite - Whichspace - 0 for read 1 for write
Buffer - Buffer to be written to or read from
Offset - Offset in to the PCI config space
Length - Length of the buffer

Return Value:

NT Status code

–*/
{
KEVENT event;
NTSTATUS status;
PIRP irp;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT targetObject;

PAGED_CODE();

KeInitializeEvent(&event, NotificationEvent, FALSE);

targetObject = IoGetAttachedDeviceReference(DeviceObject);

irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock );

if (irp == NULL) {

status = STATUS_INSUFFICIENT_RESOURCES;

// Done with reference
ObDereferenceObject(targetObject);
return status;
}

irpStack = IoGetNextIrpStackLocation( irp );
irpStack->MinorFunction = ReadOrWrite ? IRP_MN_WRITE_CONFIG : IRP_MN_READ_CONFIG;
irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
irpStack->Parameters.ReadWriteConfig.Offset = Offset;
irpStack->Parameters.ReadWriteConfig.Length = Length;

//
// Initialize the status to error in case the bus driver does not
// set it correctly.
irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;

status = IoCallDriver(targetObject, irp);

if (status == STATUS_PENDING) {

KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatusBlock.Status;

}

// Done with reference
ObDereferenceObject( targetObject );
return status;
}

On some PC with Windows 7 CMD eq 0x02 after WritePCIConfig(…)

  1. Probably we missed something in configuring our device. How can one specify to KMDF that our device is bus master capable (Pavel) ?

xxxxx@mail2k.ru wrote:

  1. To read/write CMD register of hte PCI config space we used 1)
    WinDBG: “!pci 0x100 8 1 0” / “!ecw 8.1.0 4 0xFFFF” and 2)
    Read(Write)PCIConfig routines:

Okay that’s interesting. So you couldn’t write to PCI config space when
you broke in at EvtDeviceD0Entry using WinDBG. That really does suggest
a hardware bug in your PCI device. As others have stated Win 7 is much
more likely to mess around with your config space(including the command
register) than older versions of Windows and there isn’t a lot you can
do about it.

PDEVICE_OBJECT pdo; DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
UCHAR buffer[PCI_COMMON_HDR_LENGTH]; PPCI_COMMON_CONFIG pPciConfig
= (PPCI_COMMON_CONFIG) buffer;

NTSTATUS ReadPCIConfig( IN PDEVICE_CONTEXT pContext ) {
PAGED_CODE();

pdo = WdfDeviceWdmGetDeviceObject(pContext->WdfDevice); return
ReadWriteConfigSpace(pdo, 0, buffer, 0, PCI_COMMON_HDR_LENGTH); }

NTSTATUS WritePCIConfig( IN PDEVICE_CONTEXT pContext ) {
PAGED_CODE();

pdo = WdfDeviceWdmGetDeviceObject(pContext->WdfDevice);

// Set CMD register manually pPciConfig->Command = 0xFFFF; return
ReadWriteConfigSpace(pdo, 1, buffer, FIELD_OFFSET(PCI_COMMON_CONFIG,
Command), sizeof(pPciConfig->Command)); }

…and the ReadWriteConfigSpace routine we’ve used from some PCI
config space read/write example:

NTSTATUS ReadWriteConfigSpace( __in PDEVICE_OBJECT DeviceObject, __in
ULONG ReadOrWrite, __in PVOID Buffer, __in ULONG
Offset, __in ULONG Length ) /*++ Routine Description:

Worker function to read& write to PCI config space at PASSIVE_LEVEL

Arguments:

DeviceObject - Pointer to the PDO ReadOrWrite - Whichspace - 0 for
read 1 for write Buffer - Buffer to be written to or read from
Offset - Offset in to the PCI config space Length -
Length of the buffer

Return Value:

NT Status code

–*/ { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK
ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT
targetObject;

PAGED_CODE();

KeInitializeEvent(&event, NotificationEvent, FALSE);

targetObject = IoGetAttachedDeviceReference(DeviceObject);

irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, targetObject, NULL,
0, NULL, &event, &ioStatusBlock );

if (irp == NULL) {

status = STATUS_INSUFFICIENT_RESOURCES;

// Done with reference ObDereferenceObject(targetObject); return
status; }

irpStack = IoGetNextIrpStackLocation( irp ); irpStack->MinorFunction
= ReadOrWrite ? IRP_MN_WRITE_CONFIG : IRP_MN_READ_CONFIG;
irpStack->Parameters.ReadWriteConfig.WhichSpace =
PCI_WHICHSPACE_CONFIG; irpStack->Parameters.ReadWriteConfig.Buffer =
Buffer; irpStack->Parameters.ReadWriteConfig.Offset = Offset;
irpStack->Parameters.ReadWriteConfig.Length = Length;

// // Initialize the status to error in case the bus driver does not
// set it correctly. irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;

status = IoCallDriver(targetObject, irp);

if (status == STATUS_PENDING) {

KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatusBlock.Status;

}

// Done with reference ObDereferenceObject( targetObject ); return
status; }

On some PC with Windows 7 CMD eq 0x02 after WritePCIConfig(…)

Was this value read back using the same code?

One observation is that your code is always writing the entire config
space header. Whenever I’ve modified the CMD register I just used the
relevant offset and told the PCI bus driver to write 2 bytes rather than
rewriting the entire config header. If you rewrite the whole header it
might cause problems. However if you can’t write config space with
WinDBG when sitting at a breakpoint in EvtDeviceD0Entry then you have a
hardware problem that will have to be fixed.
Using windbg to do the write was how I proved that writing the CMD
register would make the device work before I added the workround to my code.

  1. Probably we missed something in configuring our device. How can
    one specify to KMDF that our device is bus master capable (Pavel) ?

In order to use DMA you must create a DMA Enabler object in WDF. I’ve
just taken a look and its almost assumed in WDF that you are using a bus
mastering device. The type of DMA you support is declared when you call
WDF_DMA_ENABLED_CONFIG_INIT in the WDF_DMA_PROFILE structure. Can’t see
how an ISA DMA device would be handled in WDF but I’m guessing that’s
considered so legacy as to be not worth supporting in the framework.

Mike

Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: xxxxx@mpcdata.com web: www.mpcdata.com
tel: +44 (0) 1225 710600 fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635

MPC Data Limited is a company registered in England and Wales with
company number 05507446
Registered Address: County Gate, County Way, Trowbridge, Wiltshire,
BA14 7FJ
VAT no: 850625238

The information in this email and in the attached documents is
confidential and may be legally privileged. Any unauthorized review,
copying, disclosure or distribution is prohibited and may be unlawful.
It is intended solely for the addressee. Access to this email by anyone
else is unauthorized. If you are not the intended recipient, please
contact the sender by reply email and destroy all copies of the original
message. When addressed to our clients any opinions or advice contained
in this email is subject to the terms and conditions expressed in the
governing contract.

  1. No-no, we could successfully write to PCI config space when debug connected in WinDBG as well as by WinDriver dialog. It seems that we also can write to that space by WritePCIConfig routine. But the result differs: we still miss valuable bits in CMD - the read value (by !pci or ReadPCIConfig) is 0x02 or 0x00 instead of 0x06 when the !ecw WinDBG command used on write.

  2. We are trying not to touch the entire PCI config space but just CMD register. It can be seen in debug message that we write the word pPciConfig->Command = 0xFFFF which has
    a) sizeof(pPciConfig->Command) = 2 bytes and has offset in the PCI config
    b) FIELD_OFFSET(PCI_COMMON_CONFIG, Command) = 4

  3. We need contiguous buffers for our device data transfer. So we allocated them by using WdfDmaEnablerCreate and WdfCommonBufferCreate. Is it the right way to say the device support Busmaster ?

> The BIOS likely will initialize your BARs and CMD register

Only for boot disk controller I think.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>> The BIOS likely will initialize your BARs and CMD register
>
> Only for boot disk controller I think.
>

Depends on the BIOS. Some of them initialize also netcards and custom
devices. Depends how they interpret “PnP OS” toggle.

– pa

> So, the driver starts and at the first bp the CMD register is 0x06. It is still 0x06 at the end of EvtDeviceAdd -

before “return STATUS_SUCCESS”. And at the beginning of EvtDevicePrepareHardware it is already 0x00 !

Go on digging inside the assembler code in pci.sys to find the place where this register is written.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

We’ve been trying to test our driver on the third-party devices (Ethernet controllers, Sound cards, etc.) - just to see the value of CMD register in the EvtDeviceAdd and EvtPrepareHardware routines. And we’ve found out (thanx Mike Pumford and others for the tip) that CMD is *not nulled* on all of those devices which have *not nulled* PCI Power Management Capabilities in PCI configuration space.

We’ve taken some old Ethernet controller (NE200 PCI 8029) which also doesn’t have those capabilities. The W7 OS made the CMD register zeroed when our driver have started on that controller.

  1. The PCI Power Management Interface Specification says:
    [http://www.pcisig.com/specifications/conventional/pcipm1.2.pdf]

“8.2.2 D3 State
Prior to placing a PCI function into D3, the operating system must determine if the device driver for the function has the capability to restore the function from this state. Restoration includes reinitializing the function. PCI functions that require specific, non-standard, initialization may have the DSI bit (bit 5 in the Power Management Capabilities register) set. In the event that the device driver cannot restore the function from D3, the operating system must make sure that the function is treated as a PCI legacy function. Note that the function?s driver is responsible for fully restoring the function from D3. If the device driver is not capable of fully reinitializing a function, the operating system should not put the function into D3. When placing a function into D3, the operating system software is required to disable I/O and memory space as well as bus mastering via the PCI Command register.”

  1. The WDK says:
    “…Legacy devices and other devices for which no power management specification exists should follow the Default Device Class Power Management Specification. The default specification requires:
    . Support for the D0 and D3 states.
    . A driver that saves and restores or reinitializes device context when the device is powered on.
    . A driver that manages the device power policy.”

So, the question is how to say to Windows 7 OS that we have a legacy device with no power management support ?

Probably WdfDeviceSetPowerCapabilities could help but does anybody know the values of WDF_DEVICE_POWER_CAPABILITIES which should be specified for the device without PM support ?


Best regards,
Sinnet del Reccos

On 12-Sep-2011 18:02, xxxxx@mail2k.ru wrote:

  1. The WDK says:
    “…Legacy devices and other devices for which no power management specification exists should follow the Default Device Class Power Management Specification. The default specification requires:
    . Support for the D0 and D3 states.
    . A driver that saves and restores or reinitializes device context when the device is powered on.
    . A driver that manages the device power policy.”

So, the question is how to say to Windows 7 OS that we have a legacy device with no power management support ?

Do you really want this? Perhaps what you really want is to fix the
device power caps descriptor and have the driver to do what it should do?

– pa