pnpPowerCallbacks causes "device cannot start error code 10"??

Hi,

I was struggling with debugging the “device cannot start error code 10” for the FX2LP board. And I found out that if I comment out the lines related to the pnpPowerCallbacks, the “device cannot start …” is gone. So what is wrong in the pnpPowerCallbacks functions that causes the error: (Codes are shown below)

pnpPowerCallbacks.EvtDevicePrepareHardware = OsrFxEvtDevicePrepareHardware;
pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry;
pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit;
pnpPowerCallbacks.EvtDeviceSelfManagedIoFlush = OsrFxEvtDeviceSelfManagedIoFlush;

==================================================
NTSTATUS
OsrFxEvtDevicePrepareHardware(
WDFDEVICE Device,
WDFCMRESLIST ResourceList,
WDFCMRESLIST ResourceListTranslated
)
/*++

Routine Description:

In this callback, the driver does whatever is necessary to make the
hardware ready to use. In the case of a USB device, this involves
reading and selecting descriptors.

Arguments:

Device - handle to a device

ResourceList - handle to a resource-list object that identifies the
raw hardware resources that the PnP manager assigned
to the device

ResourceListTranslated - handle to a resource-list object that
identifies the translated hardware resources
that the PnP manager assigned to the device

Return Value:

NT status value

–*/
{
NTSTATUS status;
PDEVICE_CONTEXT pDeviceContext;
WDF_USB_DEVICE_INFORMATION deviceInfo;
ULONG waitWakeEnable;

UNREFERENCED_PARAMETER(ResourceList);
UNREFERENCED_PARAMETER(ResourceListTranslated);
waitWakeEnable = FALSE;
PAGED_CODE();

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “–> EvtDevicePrepareHardware\n”);

pDeviceContext = GetDeviceContext(Device);

//
// Create a USB device handle so that we can communicate with the
// underlying USB stack. The WDFUSBDEVICE handle is used to query,
// configure, and manage all aspects of the USB device.
// These aspects include device properties, bus properties,
// and I/O creation and synchronization. We only create device the first
// the PrepareHardware is called. If the device is restarted by pnp manager
// for resource rebalance, we will use the same device handle but then select
// the interfaces again because the USB stack could reconfigure the device on
// restart.
//
if (pDeviceContext->UsbDevice == NULL) {
WDF_USB_DEVICE_CREATE_CONFIG config;

WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config,
USBD_CLIENT_CONTRACT_VERSION_602);

status = WdfUsbTargetDeviceCreateWithParameters(Device,
&config,
WDF_NO_OBJECT_ATTRIBUTES,
&pDeviceContext->UsbDevice);

if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“WdfUsbTargetDeviceCreateWithParameters failed with Status code %!STATUS!\n”, status);
return status;
}

//
// TODO: If you are fetching configuration descriptor from device for
// selecting a configuration or to parse other descriptors, call OsrFxValidateConfigurationDescriptor
// to do basic validation on the descriptors before you access them .
//
}

//
// Retrieve USBD version information, port driver capabilites and device
// capabilites such as speed, power, etc.
//
WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);

status = WdfUsbTargetDeviceRetrieveInformation(
pDeviceContext->UsbDevice,
&deviceInfo);
if (NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “IsDeviceHighSpeed: %s\n”,
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? “TRUE” : “FALSE”);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“IsDeviceSelfPowered: %s\n”,
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? “TRUE” : “FALSE”);

waitWakeEnable = deviceInfo.Traits &
WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“IsDeviceRemoteWakeable: %s\n”,
waitWakeEnable ? “TRUE” : “FALSE”);
//
// Save these for use later.
//
pDeviceContext->UsbDeviceTraits = deviceInfo.Traits;
}
else {
pDeviceContext->UsbDeviceTraits = 0;
}

status = SelectInterfaces(Device);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“SelectInterfaces failed 0x%x\n”, status);
return status;
}

//
// Enable wait-wake and idle timeout if the device supports it
//
if (waitWakeEnable) {
status = OsrFxSetPowerPolicy(Device);
if (!NT_SUCCESS (status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“OsrFxSetPowerPolicy failed %!STATUS!\n”, status);
return status;
}
}

status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “<– EvtDevicePrepareHardware\n”);

return status;
}

===================================================
NTSTATUS
OsrFxEvtDeviceD0Entry(
WDFDEVICE Device,
WDF_POWER_DEVICE_STATE PreviousState
)
/*++

Routine Description:

EvtDeviceD0Entry event callback must perform any operations that are
necessary before the specified device is used. It will be called every
time the hardware needs to be (re-)initialized.

This function is not marked pageable because this function is in the
device power up path. When a function is marked pagable and the code
section is paged out, it will generate a page fault which could impact
the fast resume behavior because the client driver will have to wait
until the system drivers can service this page fault.

This function runs at PASSIVE_LEVEL, even though it is not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE
is set. Even if DO_POWER_PAGABLE isn’t set, this function still runs
at PASSIVE_LEVEL. In this case, though, the function absolutely must
not do anything that will cause a page fault.

Arguments:

Device - Handle to a framework device object.

PreviousState - Device power state which the device was in most recently.
If the device is being newly started, this will be
PowerDeviceUnspecified.

Return Value:

NTSTATUS

–*/
{
PDEVICE_CONTEXT pDeviceContext;
NTSTATUS status;
BOOLEAN isTargetStarted;

pDeviceContext = GetDeviceContext(Device);
isTargetStarted = FALSE;

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
“–>OsrFxEvtEvtDeviceD0Entry - coming from %s\n”,
DbgDevicePowerString(PreviousState));

//
// Since continuous reader is configured for this interrupt-pipe, we must explicitly start
// the I/O target to get the framework to post read requests.
//
status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_POWER, “Failed to start interrupt pipe %!STATUS!\n”, status);
goto End;
}

isTargetStarted = TRUE;

End:

if (!NT_SUCCESS(status)) {
//
// Failure in D0Entry will lead to device being removed. So let us stop the continuous
// reader in preparation for the ensuing remove.
//
if (isTargetStarted) {
WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo);
}
}

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, “<–OsrFxEvtEvtDeviceD0Entry\n”);

return status;
}

NTSTATUS
OsrFxEvtDeviceD0Exit(
WDFDEVICE Device,
WDF_POWER_DEVICE_STATE TargetState
)
/*++

Routine Description:

This routine undoes anything done in EvtDeviceD0Entry. It is called
whenever the device leaves the D0 state, which happens when the device is
stopped, when it is removed, and when it is powered off.

The device is still in D0 when this callback is invoked, which means that
the driver can still touch hardware in this routine.

EvtDeviceD0Exit event callback must perform any operations that are
necessary before the specified device is moved out of the D0 state. If the
driver needs to save hardware state before the device is powered down, then
that should be done here.

This function runs at PASSIVE_LEVEL, though it is generally not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE is set.

Even if DO_POWER_PAGABLE isn’t set, this function still runs at
PASSIVE_LEVEL. In this case, though, the function absolutely must not do
anything that will cause a page fault.

Arguments:

Device - Handle to a framework device object.

TargetState - Device power state which the device will be put in once this
callback is complete.

Return Value:

Success implies that the device can be used. Failure will result in the
device stack being torn down.

–*/
{
PDEVICE_CONTEXT pDeviceContext;

PAGED_CODE();

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
“–>OsrFxEvtDeviceD0Exit - moving to %s\n”,
DbgDevicePowerString(TargetState));

pDeviceContext = GetDeviceContext(Device);

WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo);

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, “<–OsrFxEvtDeviceD0Exit\n”);

return STATUS_SUCCESS;
}

==================================================
VOID
OsrFxEvtDeviceSelfManagedIoFlush(
In WDFDEVICE Device
)
/*++

Routine Description:

This routine handles flush activity for the device’s
self-managed I/O operations.

Arguments:

Device - Handle to a framework device object.

Return Value:

None

–*/
{
// Service the interrupt message queue to drain any outstanding
// requests
OsrUsbIoctlGetInterruptMessage(Device, STATUS_DEVICE_REMOVED);
}

Step through each of them with a kernel debugger and the error should be pretty clear. We can?t tell you just by looking

Sent from Outlook Mailhttp: for Windows 10

From: xxxxx@gmail.com
Sent: Thursday, July 2, 2015 8:29 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] pnpPowerCallbacks causes “device cannot start error code 10”??

Hi,

I was struggling with debugging the “device cannot start error code 10” for the FX2LP board. And I found out that if I comment out the lines related to the pnpPowerCallbacks, the “device cannot start …” is gone. So what is wrong in the pnpPowerCallbacks functions that causes the error: (Codes are shown below)

pnpPowerCallbacks.EvtDevicePrepareHardware = OsrFxEvtDevicePrepareHardware;
pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry;
pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit;
pnpPowerCallbacks.EvtDeviceSelfManagedIoFlush = OsrFxEvtDeviceSelfManagedIoFlush;

==================================================
NTSTATUS
OsrFxEvtDevicePrepareHardware(
WDFDEVICE Device,
WDFCMRESLIST ResourceList,
WDFCMRESLIST ResourceListTranslated
)
/++

Routine Description:

In this callback, the driver does whatever is necessary to make the
hardware ready to use. In the case of a USB device, this involves
reading and selecting descriptors.

Arguments:

Device - handle to a device

ResourceList - handle to a resource-list object that identifies the
raw hardware resources that the PnP manager assigned
to the device

ResourceListTranslated - handle to a resource-list object that
identifies the translated hardware resources
that the PnP manager assigned to the device

Return Value:

NT status value

/
{
NTSTATUS status;
PDEVICE_CONTEXT pDeviceContext;
WDF_USB_DEVICE_INFORMATION deviceInfo;
ULONG waitWakeEnable;

UNREFERENCED_PARAMETER(ResourceList);
UNREFERENCED_PARAMETER(ResourceListTranslated);
waitWakeEnable = FALSE;
PAGED_CODE();

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “–> EvtDevicePrepareHardware\n”);

pDeviceContext = GetDeviceContext(Device);

//
// Create a USB device handle so that we can communicate with the
// underlying USB stack. The WDFUSBDEVICE handle is used to query,
// configure, and manage all aspects of the USB device.
// These aspects include device properties, bus properties,
// and I/O creation and synchronization. We only create device the first
// the PrepareHardware is called. If the device is restarted by pnp manager
// for resource rebalance, we will use the same device handle but then select
// the interfaces again because the USB stack could reconfigure the device on
// restart.
//
if (pDeviceContext->UsbDevice == NULL) {
WDF_USB_DEVICE_CREATE_CONFIG config;

WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config,
USBD_CLIENT_CONTRACT_VERSION_602);

status = WdfUsbTargetDeviceCreateWithParameters(Device,
&config,
WDF_NO_OBJECT_ATTRIBUTES,
&pDeviceContext->UsbDevice);

if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“WdfUsbTargetDeviceCreateWithParameters failed with Status code %!STATUS!\n”, status);
return status;
}

//
// TODO: If you are fetching configuration descriptor from device for
// selecting a configuration or to parse other descriptors, call OsrFxValidateConfigurationDescriptor
// to do basic validation on the descriptors before you access them .
//
}

//
// Retrieve USBD version information, port driver capabilites and device
// capabilites such as speed, power, etc.
//
WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);

status = WdfUsbTargetDeviceRetrieveInformation(
pDeviceContext->UsbDevice,
&deviceInfo);
if (NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “IsDeviceHighSpeed: %s\n”,
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? “TRUE” : “FALSE”);
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“IsDeviceSelfPowered: %s\n”,
(deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? “TRUE” : “FALSE”);

waitWakeEnable = deviceInfo.Traits &
WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
“IsDeviceRemoteWakeable: %s\n”,
waitWakeEnable ? “TRUE” : “FALSE”);
//
// Save these for use later.
//
pDeviceContext->UsbDeviceTraits = deviceInfo.Traits;
}
else {
pDeviceContext->UsbDeviceTraits = 0;
}

status = SelectInterfaces(Device);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“SelectInterfaces failed 0x%x\n”, status);
return status;
}

//
// Enable wait-wake and idle timeout if the device supports it
//
if (waitWakeEnable) {
status = OsrFxSetPowerPolicy(Device);
if (!NT_SUCCESS (status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“OsrFxSetPowerPolicy failed %!STATUS!\n”, status);
return status;
}
}

status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, “<– EvtDevicePrepareHardware\n”);

return status;
}

===================================================
NTSTATUS
OsrFxEvtDeviceD0Entry(
WDFDEVICE Device,
WDF_POWER_DEVICE_STATE PreviousState
)
/++

Routine Description:

EvtDeviceD0Entry event callback must perform any operations that are
necessary before the specified device is used. It will be called every
time the hardware needs to be (re-)initialized.

This function is not marked pageable because this function is in the
device power up path. When a function is marked pagable and the code
section is paged out, it will generate a page fault which could impact
the fast resume behavior because the client driver will have to wait
until the system drivers can service this page fault.

This function runs at PASSIVE_LEVEL, even though it is not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE
is set. Even if DO_POWER_PAGABLE isn’t set, this function still runs
at PASSIVE_LEVEL. In this case, though, the function absolutely must
not do anything that will cause a page fault.

Arguments:

Device - Handle to a framework device object.

PreviousState - Device power state which the device was in most recently.
If the device is being newly started, this will be
PowerDeviceUnspecified.

Return Value:

NTSTATUS

/
{
PDEVICE_CONTEXT pDeviceContext;
NTSTATUS status;
BOOLEAN isTargetStarted;

pDeviceContext = GetDeviceContext(Device);
isTargetStarted = FALSE;

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
“–>OsrFxEvtEvtDeviceD0Entry - coming from %s\n”,
DbgDevicePowerString(PreviousState));

//
// Since continuous reader is configured for this interrupt-pipe, we must explicitly start
// the I/O target to get the framework to post read requests.
//
status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_POWER, “Failed to start interrupt pipe %!STATUS!\n”, status);
goto End;
}

isTargetStarted = TRUE;

End:

if (!NT_SUCCESS(status)) {
//
// Failure in D0Entry will lead to device being removed. So let us stop the continuous
// reader in preparation for the ensuing remove.
//
if (isTargetStarted) {
WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo);
}
}

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, “<–OsrFxEvtEvtDeviceD0Entry\n”);

return status;
}
===================================================
NTSTATUS
OsrFxEvtDeviceD0Exit(
WDFDEVICE Device,
WDF_POWER_DEVICE_STATE TargetState
)
/++

Routine Description:

This routine undoes anything done in EvtDeviceD0Entry. It is called
whenever the device leaves the D0 state, which happens when the device is
stopped, when it is removed, and when it is powered off.

The device is still in D0 when this callback is invoked, which means that
the driver can still touch hardware in this routine.

EvtDeviceD0Exit event callback must perform any operations that are
necessary before the specified device is moved out of the D0 state. If the
driver needs to save hardware state before the device is powered down, then
that should be done here.

This function runs at PASSIVE_LEVEL, though it is generally not paged. A
driver can optionally make this function pageable if DO_POWER_PAGABLE is set.

Even if DO_POWER_PAGABLE isn’t set, this function still runs at
PASSIVE_LEVEL. In this case, though, the function absolutely must not do
anything that will cause a page fault.

Arguments:

Device - Handle to a framework device object.

TargetState - Device power state which the device will be put in once this
callback is complete.

Return Value:

Success implies that the device can be used. Failure will result in the
device stack being torn down.

/
{
PDEVICE_CONTEXT pDeviceContext;

PAGED_CODE();

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
“–>OsrFxEvtDeviceD0Exit - moving to %s\n”,
DbgDevicePowerString(TargetState));

pDeviceContext = GetDeviceContext(Device);

WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo);

TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, “<–OsrFxEvtDeviceD0Exit\n”);

return STATUS_SUCCESS;
}

==================================================
VOID
OsrFxEvtDeviceSelfManagedIoFlush(
In WDFDEVICE Device
)
/++

Routine Description:

This routine handles flush activity for the device’s
self-managed I/O operations.

Arguments:

Device - Handle to a framework device object.

Return Value:

None

/
{
// Service the interrupt message queue to drain any outstanding
// requests
OsrUsbIoctlGetInterruptMessage(Device, STATUS_DEVICE_REMOVED);
}


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</http:>

Which kernel debugger should I use?

I try to use TraceView by following the steps in this link: http://www.osronline.com/showthread.cfm?link=115758

And I was expecting to see some traces as I reinstall the driver but I can’t see anything.

xxxxx@gmail.com wrote:

I was struggling with debugging the “device cannot start error code 10” for the FX2LP board. And I found out that if I comment out the lines related to the pnpPowerCallbacks, the “device cannot start …” is gone. So what is wrong in the pnpPowerCallbacks functions that causes the error: (Codes are shown below)

Remember that the sample driver assumes that you are using the OSR
development board, which has a very specific set of descriptors and
endpoints. If you are “borrowing” this driver for a device that doesn’t
look exactly like the OSR board, then it’s not surprising that bad
things happen.

In particular, this driver expects to find an interrupt endpoint. If
you don’t have an interrupt endpoint, it should be pretty clear where it
will crash.


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

The board I am using has a FX2LP so it does have interrupt endpoint.

I can use TraceView.exe to see the trace message now. I use a new GUID generated from http://new-guid.com/.

And I replace the GUID in the trace.h with this GUID and now I can see the trace message.

Just use uuidgen.exe, no need for a website

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, July 2, 2015 11:20 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] pnpPowerCallbacks causes “device cannot start error code 10”??

I can use TraceView.exe to see the trace message now. I use a new GUID generated from http://new-guid.com/.

And I replace the GUID in the trace.h with this GUID and now I can see the trace message.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

The board I am using has a FX2LP so it does have interrupt endpoint.

That doesn’t mean ANYTHING. The FX2LP is a completely programmable USB
chip. You create the descriptors in the firmware you write, and the
descriptors determine which endpoints are available. Unless you are
using OSR’s firmware, there’s no guarantee that the endpoints are the same.

If you don’t know what firmware is in the device, then you have no idea
what endpoints are available. Perhaps you should use usbview or uvcview
to examine your descriptors.


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

Thanks Tim. I removed that parts that related to the interruptEndPoint in the driver and now it doesn’t have Error Code 10 anymore. I will have to test some read and write function to make sure it works.