We’re seeing an intermittent pair of verifier bugchecks in a KMDF USB driver. The issue never happens on some systems, but happens regularly enough on others.
WDF_VIOLATION (10d)
The Kernel-Mode Driver Framework was notified that Windows detected an error
in a framework-based driver...
Arguments:
Arg1: 0000000000000006, A fatal error was made in handling a WDF request. In this case,
Parameter 2 further specifies the type of fatal error that has
been made, as defined by the enumeration WDF_REQUEST_FATAL_ERROR.
Arg2: 0000000000000003, The driver attempted to send a framework request that has
already been sent to an I/O target.
Arg3: 00003f719a03bf18, The WDF request handle value.
Arg4: ffffc08e614c9de0, Reserved.
STACK_TEXT:
fffff807`120da148 fffff807`108b8920 : 00000000`0000010d 00000000`00000006 00000000`00000003 00003f71`9a03bf18 : nt!KeBugCheckEx
fffff807`120da150 fffff807`1087d5c1 : 00003f71`9a03bf18 00000000`00000000 00003f71`9a03bf18 fffff807`10863f7d : Wdf01000!FxVerifierBugCheckWorker+0x24 [minkernel\wdf\framework\shared\object\fxverifierbugcheck.cpp @ 68]
fffff807`120da190 fffff807`10861c4a : ffffc08e`65fc4000 ffffc08e`65fc40e0 00000000`00000000 ffffc08e`65fc40e0 : Wdf01000!FxIoTarget::SubmitLocked+0x1b631 [minkernel\wdf\framework\shared\targets\general\fxiotarget.cpp @ 1318]
fffff807`120da220 fffff807`1922cb34 : ffffc08e`614c9f00 ffffc08e`65fc40e0 ffffc08e`65d2ddf0 00000000`00000000 : Wdf01000!imp_WdfRequestSend+0x17a [minkernel\wdf\framework\shared\core\fxrequestapi.cpp @ 2055]
fffff807`120da2a0 fffff807`192283a5 : fffff807`1922a1a0 ffffc08e`6215a820 ffffc08e`6215aa58 fffff807`192480a0 : FocusriteUsb!IsocUrb::Submit+0x74 [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\isocurb.cpp @ 280]
fffff807`120da2f0 fffff807`19229dde : ffffc08e`6215a820 00000000`00000009 ffffc08e`67b84f40 ffffc08e`67b84f40 : FocusriteUsb!UsbAudioStream::SubmitAudioUrb+0x45 [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\audstream.cpp @ 909]
fffff807`120da320 fffff807`10869248 : ffffc08e`65fbf2f0 00000000`00000001 fffff807`1922a1a0 ffffc08e`61721e10 : FocusriteUsb!UsbAudioStream::RequestCompletion+0x25e [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\audstream.cpp @ 671]
fffff807`120da380 fffff807`1086c854 : 00003f71`9a040d08 ffffc08e`65fbf2f0 ffffc08e`65fbf2f0 fffff807`0fdf8a48 : Wdf01000!FxRequestBase::CompleteSubmitted+0xe8 [...
AND
DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 000000000000020b, The caller of IoFreeIrp is freeing an IRP that is still in use.
Arg2: fffff8035b897ace, The address in the driver's code where the error was detected.
Arg3: ffffe6827b112af0, IRP address.
Arg4: 0000000000000000
STACK_TEXT:
fffff803`5e2d9f48 fffff803`5bfd5e34 : 00000000`000000c9 00000000`0000020b fffff803`5b897ace ffffe682`7b112af0 : nt!KeBugCheckEx
fffff803`5e2d9f50 fffff803`5bfdd393 : 00000000`00000000 00000000`00000000 00000000`0000020b fffff803`5c3469b0 : nt!VerifierBugCheckIfAppropriate+0xe0
fffff803`5e2d9f90 fffff803`5bba3bbb : 00000000`0000020b 00000000`00000000 ffffe682`7b112af0 00000000`00000000 : nt!ViErrorFinishReport+0x117
fffff803`5e2d9ff0 fffff803`5bfd62cf : fffff803`5b897ace 00000000`00000002 00000000`00000000 fffff803`5ca6b7ee : nt!ViErrorReport1+0x63
fffff803`5e2da090 fffff803`5bfca23c : ffffe682`7956e70f ffffe682`7b112af0 ffffe682`6baf3000 ffffe682`7956e710 : nt!VfIoFreeIrp+0x83
fffff803`5e2da0d0 fffff803`5b897ace : ffffe682`78204c00 ffffe682`7956e710 ffffe682`7b112af0 ffffe682`79936af0 : nt!IovFreeIrpPrivate+0x6c
fffff803`5e2da110 fffff803`5ca87eab : fffff803`663b3d38 00000000`00000000 ffffe682`7bfd5000 ffffe682`6baf51a0 : nt!IoFreeIrp+0x1e
fffff803`5e2da140 fffff803`5cace16d : ffffe682`79580700 ffffe682`7956e710 ffffe682`79580700 fffff803`5ca6cdd7 : Wdf01000!FxRequestBase::ValidateTarget+0x1c70f [minkernel\wdf\framework\shared\core\fxrequestbase.cpp @ 375]
fffff803`5e2da190 fffff803`5cac85e7 : ffffe682`79580700 fffff803`5e2da260 0000197d`82163af8 00000000`00000000 : Wdf01000!FxFormatUrbRequest+0x2d [minkernel\wdf\framework\shared\targets\usb\usbutil.cpp @ 76]
fffff803`5e2da1e0 fffff803`6639c350 : ffffe682`7de9c568 ffffe682`7bae2858 00000000`00000000 ffffe682`6b0f9060 : Wdf01000!imp_WdfUsbTargetPipeFormatRequestForUrb+0x1a7 [minkernel\wdf\framework\shared\targets\usb\fxusbpipeapi.cpp @ 806]
fffff803`5e2da290 fffff803`6639838d : fffff803`6639a1a0 ffffe682`7bae2858 00000000`00000000 fffff803`663b80a0 : FocusriteUsb!IsocUrb::Recycle+0x1c0 [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\isocurb.cpp @ 204]
fffff803`5e2da2f0 fffff803`66399dde : ffffe682`7bae2820 00000000`00000009 ffffe682`74611570 ffffe682`74611570 : FocusriteUsb!UsbAudioStream::SubmitAudioUrb+0x2d [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\audstream.cpp @ 907]
fffff803`5e2da320 fffff803`5ca69248 : ffffe682`6b0f9060 00000000`00000001 fffff803`6639a1a0 ffffe682`7d780df0 : FocusriteUsb!UsbAudioStream::RequestCompletion+0x25e [c:\Jenkins\jenkins2\workspace\HMP_Driver_Build_feature_wdf_iso\source\driver\usb\audstream.cpp @ 671]
fffff803`5e2da380 fffff803`5ca6c854 : 0000197d`94f06f98 ffffe682`6b0f9060 ffffe682`6b0f9060 fffff803`5bfe5a48 : Wdf01000!FxRequestBase::CompleteSubmitted+0xe8 ...
The driver is using this code from (a function called from) its EvtRequestCompletion routine
NTSTATUS IsocUrb::Recycle(bool reuse)
{
NTSTATUS status = STATUS_SUCCESS;
ASSERT(_urb != NULL);
ASSERT(m_Buffer != NULL);
ASSERT(m_NumPackets > 0);
ASSERT(_pipe);
const USHORT urbLength = (USHORT)GET_ISO_URB_SIZE(m_NumPackets);
// zero header but not IsoPackets (for now)
RtlZeroMemory(_urb, sizeof(_urb->UrbIsochronousTransfer) - sizeof(_urb->UrbIsochronousTransfer.IsoPacket));
_urb->UrbHeader.Length = urbLength;
_urb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
_urb->UrbHeader.Status = 0xFFFFFFFF;
_urb->UrbIsochronousTransfer.PipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(_pipe);
_urb->UrbIsochronousTransfer.TransferFlags = (m_IsInput ? USBD_TRANSFER_DIRECTION_IN : 0);
_urb->UrbIsochronousTransfer.TransferBufferLength = m_TransferLength;
_urb->UrbIsochronousTransfer.TransferBuffer = m_Buffer;
//urb->UrbIsochronousTransfer.StartFrame = startFrame;
_urb->UrbIsochronousTransfer.NumberOfPackets = m_NumPackets;
for (ULONG i = 0; i < _urb->UrbIsochronousTransfer.NumberOfPackets; i++)
{
_urb->UrbIsochronousTransfer.IsoPacket[i].Status = 0xFFFFFFFF;
if (m_IsInput)
{
// This fixes compatibility with the Renesas USB 3.0 host controller driver (nusb3xhc.sys)
_urb->UrbIsochronousTransfer.IsoPacket[i].Length = 0;
}
}
if (reuse)
{
WDF_REQUEST_REUSE_PARAMS wdfrup;
WDF_REQUEST_REUSE_PARAMS_INIT(&wdfrup, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_SUCCESS);
status = WdfRequestReuse(_wdfRequest, &wdfrup);
TraceAssert(NT_SUCCESS(status));
}
// m_Completions++;
status = WdfUsbTargetPipeFormatRequestForUrb(_pipe, _wdfRequest, _urbMemory, 0);
TraceAssert(NT_SUCCESS(status));
return status;
}
followed by
...
if (!WdfRequestSend(_wdfRequest, WdfUsbTargetPipeGetIoTarget(_pipe), WDF_NO_SEND_OPTIONS))
{
status = WdfRequestGetStatus(_wdfRequest);
TraceError("Isoc URB WDFREQUEST failed with error %!STATUS!", status);
}
TraceVerbose(TRACEFLG_USBURB,"URB[%c%d] REQ[%p] Submission: frame:%d status: %!STATUS!", m_IsInput ? 'I':'O', m_ID, (PVOID)_wdfRequest, startFrame, status);
...
My question is, Since I created the request in the first place, and am in the context of my completion routine, shouldn’t I be able Resubmit or free the request?
(the complete stack dumps won’t fit in this post)
Thanks!