WdfIoTargetStop can't return

I am using WdfIoTargetStop in ExtDeviceD0Exit to stop usb continuous reader,
and it blocks the power IRP causing BSOD(0x9F). From the dump, I see
the WdfIoTargetStop are waiting for cancel pending request and not return for a long time.

the blocked thread is:
*** Stack trace for last set context - .thread/.cxr resets it
Child-SP RetAddr Call Site
fffff880009e0150 fffff8000367c5f2 nt!KiSwapContext+0x7a
fffff880009e0290 fffff8000368d99f nt!KiCommitThreadWait+0x1d2
fffff880009e0320 fffff88000ef37b9 nt!KeWaitForSingleObject+0x19f
fffff880009e03c0 fffff88000f36f82 Wdf01000!_FX_DRIVER_GLOBALS::WaitForSignal+0x99
fffff880009e0400 fffff88000f37efa Wdf01000!FxUsbPipeContinuousReader::CancelRepeaters+0x6a
fffff880009e0430 fffff88000f5bbf9 Wdf01000!FxUsbPipe::WaitForSentIoToComplete+0xca
fffff880009e0480 fffff88000f290fb Wdf01000!FxIoTarget::Stop+0x51
fffff880009e04c0 fffff88008420bcb Wdf01000!imp_WdfIoTargetStop+0x177
(Inline Function) --------`-------- Btfilter!WdfIoTargetStop+0x17 [c:\program files\windows kits\8.0\include\wdf\kmdf\1.9\wdfiotarget.h @ 428]

0: kd> !wdfkd.wdfiotarget 0x0000057f`f4eb3778 0xff
WDFIOTARGET 0000057ff4eb3778

WDFDEVICE: 0x0000057ff4ed46f8
Target Device: !devobj 0xfffffa800b097e40
Target PDO: !devobj 0xfffffa800c1b8440

Type: Instack target
State: WdfIoTargetStarted
Requests pending: 0
Requests sent: 0
Requests sent with ignore-target-state: 0

It seems no requests are pending in the target???
But:

0: kd> !wdfkd.wdfusbpipe 0x0000057f`f4ecd628

!WDFUSBPIPE 0000057ff4ecd628

Type UsbdPipeTypeInterrupt
Direction In
MaxPacket 0x10, Max Transfer 0x400000
Endpoint Address 0x81
USBD_PIPE_HANDLE fffffa800b153888

Continuous Reader (fffffa800b14f860):
Number of readers: 2
Repeaters are not submitted, either cancelled or not sent.
Read completion routine: RtkBtfilter!FilterEventReadCompletion (fffff8800842152c)
Context fffffa800b12bbb0
Readers failed callback: RtkBtfilter!FilterEventReadFailCompletion (fffff880084216b0)
Repeater fffffa800b14f8c0: !WDFREQUEST 0000057ff4eab788 !irp 0xfffffa800af69b00
Repeater fffffa800b14f930: !WDFREQUEST 0000057ff4eab368 !irp 0xfffffa800b137c60

!WDFUSBDEVICE 0000057ff4eb3778
!WDFUSBINTERFACE 0000057ff3e4acd8


0: kd> !irp 0xfffffa800af69b00 0xff
Irp is active with 8 stacks 9 is current (= 0xfffffa800af69e10)
No Mdl: No System Buffer: Thread 00000000: Irp is completed. Pending has been returned
Flags = 00000000
ThreadListEntry.Flink = fffffa800af69b20
ThreadListEntry.Blink = fffffa800af69b20
IoStatus.Status = c0000120
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 01
CancelIrql = 0
ApcEnvironment = 01
UserIosb = 00000000
UserEvent = 00000000
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000
CancelRoutine = 00000000
UserBuffer = 00000000
&Tail.Overlay.DeviceQueueEntry = fffffa800af69b78
Tail.Overlay.Thread = 00000000
Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000
Tail.Overlay.ListEntry.Blink = 00000000
Tail.Overlay.CurrentStackLocation = fffffa800af69e10
Tail.Overlay.OriginalFileObject = 00000000
Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 2 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 ffffffffc0000120
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[f, 0] 0 2 fffffa8009d0b050 00000000 00000000-00000000
\Driver\usbehci
Args: 00000000 00000000 00000000 00000000

I can see the IRP is pending in the usbehci
Why this happen?

and my source code is:
NTSTATUS
FilterEvtDeviceD0Exit(
IN WDFDEVICE Device,
IN WDF_POWER_DEVICE_STATE TargetState
)
{
PFILTER_EXTENSION FilterExt = NULL;
HCI_DEVICE* phcidevice;
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
UNREFERENCED_PARAMETER(TargetState);
DEBUG(TRACE_LEVEL_WARNING,RTK_HAL,(“HAL: +++++ Target State:%x”, TargetState));
FilterExt = FilterGetData(Device);

WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(FilterExt->EventPipe), WdfIoTargetLeaveSentIoPending);
WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(FilterExt->AclInPipe), WdfIoTargetLeaveSentIoPending);

DEBUG(TRACE_LEVEL_WARNING,RTK_HAL,(“HAL: -----”));
return STATUS_SUCCESS;
}

Many thanks!

Hi,

Since you’re using KMDF 1.9, this article may have some useful ideas: http://support.microsoft.com/kb/2516416

One thing you could try is implementing a EvtUsbTargetPipeReadersFailed callback that returns FALSE (see MSDN documentation) and put it in the config struct you give to WdfUsbTargetPipeConfigContinuousReader.

Also, did you try passing WdfIoTargetCancelSentIo to WdfIoTargetStop instead of WdfIoTargetLeaveSentIoPending?

Thank you for suggestion.

I have tried passing WdfIoTargetCancelSentIo to WdfIoTargetStop, and the BSOD still happened. So, it’s not the matter of the parameter.

"
A KMDF-Based USB device driver can work around these problems by implementing the following solution:
In the USB device driver’s D0Exit routine, call WdfIoTargetStop for each of the USB Pipes (including the pipe associated with the USB Continuous Reader) before calling WdfIoTargetStop for the USB Device itself. This will avoid deadlocks with the thread performing the actions related to stopping the USB I/O targets.
"

I did the right thing in D0Exit, why WdfIoTargetStop still hang up?
And, implement the EvtUsbTargetPipReadersFailed can only reduce the likelihood of occurrence of this problem.
Does it mean my driver should both use these two methods to avoid this issue?