Hi ,All
I have a driver for a PCIe device which fails to start on Win 7 (it works fine on XP).
This issue has been discussed on this list:
http://www.osronline.com/showthread.cfm?link=206793
Now I want to do a Summary of this issue.
(1)In the Device Manager, it says “This device cannot start. (Code
10-CM_PROB_FAILED_START)” for Device status.I test other windows OS,found that
on XP/2003 the driver is OK,on Vista/2008/windows 7 have Code 10 problem.
I traced the driver and found that DriverEntry and AddDevice passed(return OK).
When it handled the IRP_MN_START_DEVICE PnP request,
call IoCallDriver,it failed,status is 0xC000000D(STATUS_INVALID_PARAMETER) on windows 7.
When I reinstall the driver,it also failed,status is 0xC0000001(STATUS_UNSUCCESSFUL).
Here is the relevant code:
handle the IRP_MN_START_DEVICE PnP request
…
KEVENT WaitEvent;
NTSTATUS status;
// Initialize a kernel event object to wait for lower-level driver IRP processing
KeInitializeEvent(
&WaitEvent,
NotificationEvent,
FALSE
);
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(
pIrp,
PnP_OnRequestComplete,
&WaitEvent,
TRUE,
TRUE,
TRUE
);
status =
IoCallDriver(
((DEVICE_EXTENSION*)fdo->DeviceExtension)->pLowerDeviceObject,
pIrp
);
if (status == STATUS_PENDING)
{
// Wait for completion
KeWaitForSingleObject(
&WaitEvent,
Executive,
KernelMode,
FALSE,
NULL
);
return pIrp->IoStatus.Status;
}
return status; //I traced,return from this path.On XP status is 0,On
//windows 7 is 0xC000000D or 0xC0000001
…
NTSTATUS
PnP_OnRequestComplete(
PDEVICE_OBJECT fdo,
PIRP pIrp,
PKEVENT pKEvent
)
{
KeSetEvent(pKEvent,0,FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
(2)Our device have 5 PCI BAR.The size of BAR 0 and BAR1 is fixed.
The size of BAR2,BAR3 and BAR 4 can be configured(0 and non-zero value).
If the size of BAR2 orBAR4 is configured to 0,“Code 10-CM_PROB_FAILED_START” on windows 7.But when the size of BAR3 is configured to 0,driver is OK.
I checked the config space and found that:
When the size of BAR2(BAR4) is configured to 0,the corresponding Base Address register
(offset 0x18 or 0x20) is 0x00000008.PCI BAR2(BAR4) has the “prefetch bit” set even if the size is configured to 0.
When the size of BAR3 is configured to 0,the corresponding Base Address register(offset 0x1c) is 0x00000000.
So I suspect:windows 7 rejects the driver is related with the case that
PCI BAR has the “prefetch bit” set but the window is probably disabled ?
(3)When driver handle the IRP_MN_START_DEVICE PnP request,I called IoGetCurrentIrpStackLocation to get the I/O stack location.
I traced Input Parameters
“Parameters.StartDevice.AllocatedResourcesTranslated.List[0].PartialResourceList”,
and found:
If the size of BAR2(BAR4) is configured to 0,there is a corresponding CmResourceTypeMemory resource(Start 0,Length 0).
But when the size of BAR3 is configured to 0,there is no such resource,
just 4 CmResourceTypeMemory resource that the PnP manager assigned to the device.
I suspect:Windows 7 does not like the corresponding CmResourceTypeMemory(Start 0,Length 0)?If so,can I delete the CmResourceTypeMemory(Start 0,Length 0) from the list?
If this can realize, when I called IoCopyCurrentIrpStackLocationToNext,the stack location of the next-lower driver can not found this.And how can I realize this?
Best Regards
ZCJ