none
Please help on ZLP sending crash for my KMDF USB driver RRS feed

  • Question

  • Hi, there

    I developed a KMDF USB driver for our device.
    Now, I need to send a ZLP to end a TX with size of 512 (in high speed case).

    I added following logic in my driver:


    1. VOID TI_EvtIoWrite(
        IN WDFQUEUE         Queue,
        IN WDFREQUEST     Request,
        IN size_t           Length
        )
    {
        ....

        //check packet length to see if we need to send a ZLP
        pInfo = &(pDeviceContext->PipeInfo[BULK_OUT_ENDPOINT_INDEX]);

        maxPload = pInfo->MaximumPacketSize;
        TINsp_DbgPrint(3, ("Length=%d, maxPload=%d \n", Length, maxPload));
        if( (Length % maxPload) == 0 )
        {
            TINsp_DbgPrint(3, ("sending ZLP... \n"));
            needZLP = TRUE;
        }
        ....
    }

    2. VOID EvtRequestWriteCompletionRoutine(
        __in WDFREQUEST                  Request,
        __in WDFIOTARGET                 Target,
        __in PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
        __in WDFCONTEXT                  Context
        )
    {
       ....

        if(needZLP)
        {
            SendZLP(Request, pDeviceContext);
        }
        ....
    }

    3. static VOID SendZLP(
        WDFREQUEST       Request,
        PDEVICE_CONTEXT  pDeviceContext)
    {
        NTSTATUS    status=0;
        PURB          pUrb = NULL;
        WDFMEMORY    urbMemory;
        WDFUSBPIPE  Pipe;

        if ( !needZLP || (pDeviceContext==NULL) || (Request==NULL) )
        {
            TINsp_DbgPrint(1, ("Invalid input parameters!!! \n"));
            return;
        }
        TINsp_DbgPrint(3, ("needZLP=%d, pDeviceContext=%x, Request=%x \n",
                needZLP, pDeviceContext, Request));

        needZLP = FALSE;
        Pipe = pDeviceContext->UsbPipe[BULK_OUT_ENDPOINT_INDEX];

        status = WdfMemoryCreate(
                                WDF_NO_OBJECT_ATTRIBUTES,
                                NonPagedPool,
                                0,
                                sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                                &urbMemory,
                                NULL
                                );
        if (!NT_SUCCESS(status)){
            return;
        }

        pUrb = WdfMemoryGetBuffer(
                                urbMemory,
                                NULL
                                );

        TINsp_DbgPrint(3, ("urbMemory=%x, pUrb=%x, len=%d \n",
                urbMemory, pUrb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)));

        // Well, build Zero Length Packet.
        pUrb->UrbHeader.Length = (USHORT)sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
        pUrb->UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
        pUrb->UrbBulkOrInterruptTransfer.PipeHandle = Pipe;
        pUrb->UrbBulkOrInterruptTransfer.TransferBuffer  = NULL;
        pUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL  = NULL;
        pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
        pUrb->UrbBulkOrInterruptTransfer.UrbLink = NULL;

        status = WdfUsbTargetPipeFormatRequestForUrb(
                                Pipe,
                                Request,
                                urbMemory,
                                NULL
                                );
        if (!NT_SUCCESS(status)) {
            goto Exit;
        }
        TINsp_DbgPrint(3, ("WdfUsbTargetPipeFormatRequestForUrb() status=%d \n", status));

        WdfRequestSetCompletionRoutine(
                                Request,
                                UrbCompletionRoutine,
                                pipe
                                );

        if (WdfRequestSend(
                        Request,
                        WdfUsbTargetPipeGetIoTarget(Pipe),
                        WDF_NO_SEND_OPTIONS
                        ) == FALSE) {
            status = WdfRequestGetStatus(Request);
            goto Exit;
        }
    }

    But, when I run my driver, it crashed all time (blue screen with stop code #0x000000D1: DRIVER_IRQL_NOT_LESS_OR_EQUAL)
    Can you review my code to see if there is any problem?
    How can I debug this crash?

    Thank you so much in advance!


    Wednesday, September 19, 2012 2:10 PM

Answers

  • Hi, Doron:

    I fixed my driver last night and it works fine now.

    Yes, I can use WdfUsbTargetPipeFormatRequestForWrite to send ZLP, I tried this in very beginning, but "WdfRequestSend" return failed with 0xc0000010. I thought it's caused by passing NULL WDFMEMORY, so I changed to create a URB memory, zero it out, and send (this is what somebody posted on the web), and got the same error. I searched MSDN for clue and found that I need to create a new Request for sending this ZLP and delete it in its complete function, then complete the original Request in old complete function.

    Thanks for your reply.

    Nick

    Thursday, September 20, 2012 1:21 PM

All replies

  • please post the output of !analyze -v. why are you rolling your own URB? why not use WdfUsbTargetPipeFormatRequestForWrite and pass a NULL WDFMEMORY?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, September 19, 2012 6:28 PM
  • Thanks for your reply, D
    Wednesday, September 19, 2012 6:35 PM
  • Hi, Doron:

    I fixed my driver last night and it works fine now.

    Yes, I can use WdfUsbTargetPipeFormatRequestForWrite to send ZLP, I tried this in very beginning, but "WdfRequestSend" return failed with 0xc0000010. I thought it's caused by passing NULL WDFMEMORY, so I changed to create a URB memory, zero it out, and send (this is what somebody posted on the web), and got the same error. I searched MSDN for clue and found that I need to create a new Request for sending this ZLP and delete it in its complete function, then complete the original Request in old complete function.

    Thanks for your reply.

    Nick

    Thursday, September 20, 2012 1:21 PM