Just a guess, but that BSOD may be due to the USB stack using fields from
the previous URB. Probably TransferBufferMDL. If you pass a non-NULL
TransferBuffer, and a null TransferBufferMDL (which is quite common), then I
believe the USB stack creates an MDL for that transfer anyway, and stores it
in the TransferBufferMDL field. If you are not explicitly setting this
field, then the next time you re-use that buffer, the USB stack will notice
the non-NULL TransferBufferMDL and attempt to use it. But that MDL has
already been freed (along with the memory it referenced), so… boom.
– arlie
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of S. Drasnin
Sent: Wednesday, December 07, 2005 12:00 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] USB Zero length packets (ZLP) on windows
Here’s a code snippet for your bulk write completion routine to try. Note
that pContext is the Context passed in IoSetCompletionRoutine().
Note that I once had a USB blue screen issue that apparently had to do with
not being able to re-use the transfer request again. I added an explicit
call to UsbBuildInterruptOrBulkTransfer() request in the completion routine
and the blue screens went away.
ULONG urbFlags = urbFlags = USBD_SHORT_TRANSFER_OK |
USBD_TRANSFER_DIRECTION_OUT;
else if ( ( pContext->RemainingLength == 0 ) &&
pContext->DevExt->fNeedZLP )
{
//KdPrint((“---->About to send ZLP\r\n”));
// clear so it’s not set after we send out the Zero Length
Packet
pContext->DevExt->fNeedZLP = FALSE;
UsbBuildInterruptOrBulkTransferRequest(
pContext->Urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
pContext->DevExt->BulkOutPipe->PipeInformation.PipeHandle,
NULL, // Transfer Buffer
NULL, // Transfer Buffer MDL
0, // length
urbFlags,
NULL);
IoQueueWorkItem(pContext->PWorkItem,
IssueUsbWriteRequest,CriticalWorkQueue, pContext);
return STATUS_MORE_PROCESSING_REQUIRED;