USB Zero length packets (ZLP) on windows

I am restating this question as unfortunately I have still not been able to
solve my problem.

Has anybody out there been able to send zero length bulk messages on
windows XP. If so could they please post a code snippet on here of how they
did it.

Note: Zero length packets (ZLP) are valid and the Microsoft host driver
does not send them automatically.

Stewart

OK, OK… I’ll bite: I’ve heard of zero length DMA transactions, but zero length USB Bulk Transfers?

You want to do this… why?? (and no, I will not consider “because it says in the spec I can” a useful answer).

P

To indicate the end of a bulk transmission of YYYY bytes , one
option USB specifications mention, is the sending of a short
packet. This is a packet less than the endpoints max packet
size. Typically 64 bytes in USB 1.1. When the YYYY bytes an EXACT
multiple of the endpoints max packet size you need to send a zero length
packet to indicated the end of the transfer.

OK, OK… I’ll bite: I’ve heard of zero length DMA transactions, but zero
length USB Bulk Transfers?

You want to do this… why?? (and no, I will not consider “because it
says in the spec I can” a useful answer).

P


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@varianinc.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Have you tried sending a URB with a transfer length of zero and a
TransferBuffer of NULL? If that doesn’t work, send a transfer length of
zero and a TransferBuffer pointing to a one byte array and see if that
works.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of stewart hamilton
Sent: Tuesday, December 06, 2005 3:39 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] USB Zero length packets (ZLP) on windows

To indicate the end of a bulk transmission of YYYY bytes , one
option USB specifications mention, is the sending of a short
packet. This is a packet less than the endpoints max packet
size. Typically 64 bytes in USB 1.1. When the YYYY bytes an EXACT
multiple of the endpoints max packet size you need to send a zero
length
packet to indicated the end of the transfer.

OK, OK… I’ll bite: I’ve heard of zero length DMA transactions, but
zero
length USB Bulk Transfers?

You want to do this… why?? (and no, I will not consider “because it
says in the spec I can” a useful answer).

P


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@varianinc.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Yes I have. With a NULL buffer I get a blue screen. With a a transfer
length of
zero and a valid buffer , I get a USBD_STATUS_INVALID_PARAMETER error
number 0x80000300L

NOTE : I have tried with and without the USBD_SHORT_TRANSFER_OK set and it
makes no difference.

If I set a non zero length EG say 20, then the packet is sent without errors .

Stewart

Have you tried sending a URB with a transfer length of zero and a
TransferBuffer of NULL? If that doesn’t work, send a transfer length of
zero and a TransferBuffer pointing to a one byte array and see if that
works.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of stewart hamilton
Sent: Tuesday, December 06, 2005 3:39 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] USB Zero length packets (ZLP) on windows

To indicate the end of a bulk transmission of YYYY bytes , one
option USB specifications mention, is the sending of a short
packet. This is a packet less than the endpoints max packet
size. Typically 64 bytes in USB 1.1. When the YYYY bytes an EXACT
multiple of the endpoints max packet size you need to send a zero
length
packet to indicated the end of the transfer.

>OK, OK… I’ll bite: I’ve heard of zero length DMA transactions, but
zero
>length USB Bulk Transfers?
>
>You want to do this… why?? (and no, I will not consider “because it
>says in the spec I can” a useful answer).
>
>P
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as:
xxxxx@varianinc.com
>To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

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;

----- Original Message -----
From: stewart hamiltonmailto:xxxxx
To: Windows System Software Devs Interest Listmailto:xxxxx
Sent: Tuesday, December 06, 2005 5:59 PM
Subject: RE: [ntdev] USB Zero length packets (ZLP) on windows

Yes I have. With a NULL buffer I get a blue screen. With a a transfer
length of
zero and a valid buffer , I get a USBD_STATUS_INVALID_PARAMETER error
number 0x80000300L

NOTE : I have tried with and without the USBD_SHORT_TRANSFER_OK set and it
makes no difference.

If I set a non zero length EG say 20, then the packet is sent without errors .

Stewart

>Have you tried sending a URB with a transfer length of zero and a
>TransferBuffer of NULL? If that doesn’t work, send a transfer length of
>zero and a TransferBuffer pointing to a one byte array and see if that
>works.
>
>d
>
>-----Original Message-----
>From: xxxxx@lists.osr.commailto:xxxxx
>[mailto:xxxxx@lists.osr.com] On Behalf Of stewart hamilton
>Sent: Tuesday, December 06, 2005 3:39 PM
>To: Windows System Software Devs Interest List
>Subject: RE:[ntdev] USB Zero length packets (ZLP) on windows
>
>To indicate the end of a bulk transmission of YYYY bytes , one
>option USB specifications mention, is the sending of a short
>packet. This is a packet less than the endpoints max packet
>size. Typically 64 bytes in USB 1.1. When the YYYY bytes an EXACT
>multiple of the endpoints max packet size you need to send a zero
>length
>packet to indicated the end of the transfer.
>
>
>
> >OK, OK… I’ll bite: I’ve heard of zero length DMA transactions, but
>zero
> >length USB Bulk Transfers?
> >
> >You want to do this… why?? (and no, I will not consider “because it
> >says in the spec I can” a useful answer).
> >
> >P
> >
> >—
> >Questions? First check the Kernel Driver FAQ at
> >http://www.osronline.com/article.cfm?id=256
> >
> >You are currently subscribed to ntdev as:
>xxxxx@varianinc.com
> >To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@microsoft.commailto:xxxxx
>To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:

You are currently subscribed to ntdev as: xxxxx@msn.commailto:xxxxx
To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx</mailto:xxxxx></mailto:xxxxx></http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>

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;

Interesting that you have seen this problem as well. Scott told me about when I ran into the problem (long ago - long before I added any ZLP stuff) so that’s why I mentioned making the UsbBuildInterruptOrBulkTranfer() call to Stewart.

At that time, I was pretty surprised that the OS took my pointer that I explicitly set to NULL (since I wasn’t using a MDL), used it under the covers, and then didn’t set it back to NULL when it got done. I guess the OS guys could make the argument that you can’t assume anything about the structure after it is used, though it seems like a common enough problem that maybe they might consider setting the pointer back to NULL or at least document it with the api call. (I’m going to put my money where my mouth is, and click the “send feedback” link at the bottom of the api documentation to request it.)

----- Original Message -----
From: Arlie Davismailto:xxxxx
To: Windows System Software Devs Interest Listmailto:xxxxx
Sent: Wednesday, December 07, 2005 11:28 AM
Subject: RE: [ntdev] USB Zero length packets (ZLP) on windows

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.commailto:xxxxx
[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;


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:

You are currently subscribed to ntdev as: xxxxx@msn.commailto:xxxxx
To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx</mailto:xxxxx></mailto:xxxxx></http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>