WdfRequestSend blocks forever

Hi,
This is a USB device and the driver has a USB_send() function like
below:

Usb_send()
{

WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);

ret = WdfRequestSend(Request,
WdfUsbTargetPipeGetIoTarget(UsbLink->SendPipe),
&SendOptions);


}

Now the scenario, when this function blocks forever, is like this:

EvtDeviceD0Entry()
{
// Set a break point here and remove the device before proceeding

ntStatus = Usb_send(); // <- returns failure

if (NT_SUCCESS(ntStatus)) {
}

ntStatus = Usb_send(); // <- but this call never returns
}

I also tried converting this into an async function but the completion
routine never gets called. WdfIoTargetGetState() returns
WdfIoTargetStarted even after the device is removed. This happens only
rarely in an end user scenario, but can be easily simulated with a
debugger. Does anybody have a clue?


Vijairaj
http://vijairaj.blogspot.com

xxxxx@gmail.com wrote:

Hi,
This is a USB device and the driver has a USB_send() function like
below:

Now the scenario, when this function blocks forever, is like this:

EvtDeviceD0Entry()
{
// Set a break point here and remove the device before proceeding

ntStatus = Usb_send(); // <- returns failure

if (NT_SUCCESS(ntStatus)) {
}

ntStatus = Usb_send(); // <- but this call never returns
}

I also tried converting this into an async function but the completion
routine never gets called. WdfIoTargetGetState() returns
WdfIoTargetStarted even after the device is removed. This happens only
rarely in an end user scenario, but can be easily simulated with a
debugger. Does anybody have a clue?

If the first send fails, why do you expect the second one to succeed?
The error should tell you that the device is gone. In that case, you
should abandon ship.

I have also seen this with WDM USB drivers. When a device is pulled,
the first request (sometimes more) get a friendly error. After that,
the request blocks waiting for an event that is never going to happen.


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

Thanks Tim,

If the first send fails, why do you expect the second one to succeed?
The error should tell you that the device is gone. In that case, you
should abandon ship.

The original scenario is a little more complex, this scenario is one
easy way of reproducing the issue. The status code for the first failure
is STATUS_UNSUCCESSFUL where I would expect something like
STATUS_DEVICE_REMOVED to reliably assume that the device has been
removed.


Vijairaj

xxxxx@gmail.com wrote:

Thanks Tim,

> If the first send fails, why do you expect the second one to succeed?
> The error should tell you that the device is gone. In that case, you
> should abandon ship.
>

The original scenario is a little more complex, this scenario is one
easy way of reproducing the issue. The status code for the first failure
is STATUS_UNSUCCESSFUL where I would expect something like
STATUS_DEVICE_REMOVED to reliably assume that the device has been
removed.

I agree that would seem reasonable, but in my experience that’s not what
happens. Once you get an error that indicates you have been surprise
removed, it is up to YOU to stop submitting URBs.


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

> I agree that would seem reasonable, but in my experience that’s not

what happens. Once you get an error that indicates you have been
surprise removed, it is up to YOU to stop submitting URBs.

Tim, Thanks again, I made sure not to submit any more URBs after an
error in the USB layer and now it works perfectly well.

Thanks to the KMDF team, Never before I have felt so confident about my
driver.


Vijairaj