Re: how to modify my usb2.0 driver to usb3.0

zhonghong200@163.com wrote:

the bulk endpoint wMaxPacketSize is 1024bytes, and in super speed endpoint companion bMaxBurst is 1

If bMaxBurst is 1, that means it can burst 2 packets per microframe. 
So, your buffers need to be a multiple of 2048 bytes instead of a
multiple of 1024 bytes.  That’s the only change needed.


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

zhonghong200@163.com wrote:

now i want to refer the wdk usbsamp example,and modify our usb2.0 driver to usb3.0

The usbsamp sample supports bulk streams, a silly and complicated
concept that was added to USB 3.0 at the request of the mass storage
folks and is used by no one else.

Seriously, the only things you need to worry about are (a) parsing the
new descriptors, and (b) incorporating bMaxBurst into your packet sizing
computations.


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

thank you ,Tim Roberts.

>>If bMaxBurst is 1, that means it can burst 2 packets per microframe.?
So, your buffers need to be a multiple of 2048 bytes instead of a
multiple of 1024 bytes.? That’s the only change needed.

Do you mean that my application’s buffer is a multiple of 2048 bytes? yes, my application buffer is large and is a multiple of 2048bytes, but I can not receive any packet from firmware, i use bushound capture the packet, and receive no packet. but i test in linux, it can receive packet .

Is this a firmware issue?

What does the usb etw log indicate?

Bent from my phone


From: 30061735200n behalf of
Sent: Saturday, August 11, 2018 12:15 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Re: how to modify my usb2.0 driver to usb3.0

thank you ,Tim Roberts.

>>If bMaxBurst is 1, that means it can burst 2 packets per microframe.?
So, your buffers need to be a multiple of 2048 bytes instead of a
multiple of 1024 bytes.? That’s the only change needed.

Do you mean that my application’s buffer is a multiple of 2048 bytes? yes, my application buffer is large and is a multiple of 2048bytes, but I can not receive any packet from firmware, i use bushound capture the packet, and receive no packet. but i test in linux, it can receive packet .

Is this a firmware issue?


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

On Aug 11, 2018, at 12:14 AM, zhonghong200@163.com wrote:
>
>
>>>> If bMaxBurst is 1, that means it can burst 2 packets per microframe.ย
> So, your buffers need to be a multiple of 2048 bytes instead of a
> multiple of 1024 bytes.ย That’s the only change needed.
>
>
> Do you mean that my application’s buffer is a multiple of 2048 bytes? yes, my application buffer is large and is a multiple of 2048bytes, but I can not receive any packet from firmware,

No, the buffer in your URB needs to be a multiple of 2048 bytes. If you are passing the user’s buffer directly to the URB, then yes, you’d need to enforce that. This is a restriction that some people don’t realize. When you submit a “read”, the device is never told how many bytes to send. It merely gets a signal that says “GO”. The device is allowed to send up to and including the endpoint’s max packet size (with bursting in USB 3). If you pass in a buffer shorter than that, the host controller might schedule some other device immediately after. If the device sends more than that, it can step on some other device’s time. That condition is called “babble”.

> i use bushound capture the packet, and receive no packet. but i test in linux, it can receive packet .

What error do you get back?

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

>>>What error do you get back?

thank you ,Tim Roberts .

not report any errors, that is, no data can be read, I am using windbg for debugging.

On Aug 13, 2018, at 7:28 PM, zhonghong200@163.com wrote:
>
>>>> What error do you get back?
>
> thank you ,Tim Roberts .
>
> not report any errors, that is, no data can be read, I am using windbg for debugging.

Are you saying the URBs never complete? Are you sure the hardware is capable of USB 3 operation?

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

thank you ,Tim Roberts ,right now i use debugView print the driver log,and find the error.

00006340 84.51743317 Drv: ReadWriteBulkEndPoints - begins
00006341 84.51743317 Drv: Transfer length (122880) is bigger then MaximumTransferSize (65536)!
00006342 84.51744843 Drv: ReadWriteBulkEndPoints - ends

if (totalLength > deviceContext->MaximumTransferSize)
{
PSDrv_DbgPrint(1, (“Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n”, totalLength, deviceContext->MaximumTransferSize));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}

and the driver code is :
VOID ReadWriteBulkEndPoints(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG Length, IN WDF_REQUEST_TYPE RequestType)
{
PMDL newMdl = NULL;
PMDL requestMdl = NULL;
PURB urb = NULL;
WDFMEMORY urbMemory;
ULONG totalLength = Length;
ULONG stageLength = 0;
ULONG urbFlags = 0;
NTSTATUS status;
ULONG_PTR virtualAddress = 0;
PREQUEST_CONTEXT rwContext = NULL;
PFILE_CONTEXT fileContext = NULL;
WDFUSBPIPE pipe;
WDF_USB_PIPE_INFORMATION pipeInfo;
WDF_OBJECT_ATTRIBUTES objectAttribs;
USBD_PIPE_HANDLE usbdPipeHandle;
PDEVICE_CONTEXT deviceContext;
WDF_REQUEST_SEND_OPTIONS sendOptions;

PSDrv_DbgPrint(3, (“ReadWriteBulkEndPoints - begins\n”));

// First validate input parameters.
deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

if (totalLength > deviceContext->MaximumTransferSize)
{
PSDrv_DbgPrint(1, (“Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n”, totalLength, deviceContext->MaximumTransferSize));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}

if ((RequestType != WdfRequestTypeRead) && (RequestType != WdfRequestTypeWrite))
{
PSDrv_DbgPrint(1, (“RequestType has to be either Read or Write! (RequestType = %d)\n”, RequestType));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}

// Get the pipe associate with this request.
fileContext = GetFileContext(WdfRequestGetFileObject(Request));
pipe = fileContext->Pipe;
WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

if((WdfUsbPipeTypeBulk != pipeInfo.PipeType) && (WdfUsbPipeTypeInterrupt != pipeInfo.PipeType))
{
PSDrv_DbgPrint(1, (“Usbd pipe type is not bulk or interrupt! (PipeType = %d)\n”, pipeInfo.PipeType));
status = STATUS_INVALID_DEVICE_REQUEST;
goto Exit;
}

rwContext = GetRequestContext(Request);

if(RequestType == WdfRequestTypeRead)
{
status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
if(!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfRequestRetrieveOutputWdmMdl failed! (Status = %x)\n”, status));
goto Exit;
}

urbFlags |= USBD_TRANSFER_DIRECTION_IN;
rwContext->Read = TRUE;
PSDrv_DbgPrint(3, (“This is a read operation…\n”));
}
else
{
status = WdfRequestRetrieveInputWdmMdl(Request, &requestMdl);
if(!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfRequestRetrieveInputWdmMdl failed! (Status = %x)\n”, status));
goto Exit;
}

urbFlags |= USBD_TRANSFER_DIRECTION_OUT;
rwContext->Read = FALSE;
PSDrv_DbgPrint(3, (“This is a write operation…\n”));
}

urbFlags |= USBD_SHORT_TRANSFER_OK;

virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);

// The transfer request is for totalLength. We can perform a max of MAX_TRANSFER_SIZE in each stage.
if (totalLength > MAX_TRANSFER_SIZE)
{
stageLength = MAX_TRANSFER_SIZE;
}
else
{
stageLength = totalLength;
}

newMdl = IoAllocateMdl((PVOID)virtualAddress, totalLength, FALSE, FALSE, NULL);
if (newMdl == NULL)
{
PSDrv_DbgPrint(1, (“IoAllocateMdl failed! (newMdl is NULL)\n”));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

// Map the portion of user-buffer described by an mdl to another mdl
IoBuildPartialMdl(requestMdl, newMdl, (PVOID)virtualAddress, stageLength);

WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
objectAttribs.ParentObject = Request;

status = WdfMemoryCreate(&objectAttribs, NonPagedPool, POOL_TAG, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), &urbMemory, (PVOID*)&urb);
if (!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfMemoryCreate for urbMemory failed! (Status = %x)\n”, status));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);

UsbBuildInterruptOrBulkTransferRequest(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), usbdPipeHandle, NULL, newMdl, stageLength, urbFlags, NULL);

status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL);
if (!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfUsbTargetPipeFormatRequestForUrb failed! (Status = %x)\n”, status));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);

// Set REQUEST_CONTEXT parameters.
rwContext->UrbMemory = urbMemory;
rwContext->Mdl = newMdl;
rwContext->Length = totalLength - stageLength;
rwContext->Numxfer = 0;
rwContext->VirtualAddress = virtualAddress + stageLength;

// Set the timeout
if (fileContext->nTimeOut != 0)
{
WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(fileContext->nTimeOut));

PSDrv_DbgPrint(3, (“Pipe timeout is set to: %d\n”, fileContext->nTimeOut));

if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), &sendOptions))
{
status = WdfRequestGetStatus(Request);
ASSERT(!NT_SUCCESS(status));
}
}
else
{
if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS))
{
status = WdfRequestGetStatus(Request);
ASSERT(!NT_SUCCESS(status));
}
}

Exit:
if (!NT_SUCCESS(status))
{
WdfRequestCompleteWithInformation(Request, status, 0);

if (newMdl != NULL)
{
IoFreeMdl(newMdl);
}
}

PSDrv_DbgPrint(3, (“ReadWriteBulkEndPoints - ends\n”));

return;
}

zhonghong200@163.com wrote:

thank you ,Tim Roberts ,right now i use debugView print the driver log,and find the error.

00006340 84.51743317 Drv: ReadWriteBulkEndPoints - begins
00006341 84.51743317 Drv: Transfer length (122880) is bigger then MaximumTransferSize (65536)!
00006342 84.51744843 Drv: ReadWriteBulkEndPoints - ends

if (totalLength > deviceContext->MaximumTransferSize)
{
PSDrv_DbgPrint(1, (“Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n”, totalLength, deviceContext->MaximumTransferSize));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}

That’s not so hard to figure out, is it?  As a general-purpose sample
that could have been exploited by any number of unknown misbehaving
clients, it puts a cap on the maximum size it will accept in a user-mode
transfer.  The default size is ridiculously small.  If you had
investigated this even a little, you would have seen in the code that
you can override the default maximum transfer size in the registry.  But
if you are actually modifying this driver for your own use, just screw
the whole concept.  You know what your apps will supply.  Rip out the
MaximumTransferSize checking altogether.


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