⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbfx2lk_usb.cpp

📁 USBFX2LK WDM drive for OSR s USB FX2 Learning Kit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//                 and submit to the device
//      Urb     -  Address of the USB to be delivered.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      Arbitrary Context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitIrpAndUrbAsync(PUSBFX2LK_EXT DevExt, PIRP Irp, PURB Urb)
{
    PIO_STACK_LOCATION nextStack;
    NTSTATUS status;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,
                            ("SubmitIrpAndUrbAsync: Enter\n"));

    //
    // We need to submit this request as a USB request, 
    //  so we'll get the next IRP stack location and set
    //  it up as a USB interrupt transfer.
    //
    nextStack = IoGetNextIrpStackLocation(Irp);

    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    nextStack->Parameters.DeviceIoControl.IoControlCode = 
                                               IOCTL_INTERNAL_USB_SUBMIT_URB;

    nextStack->Parameters.Others.Argument1 = Urb;

    //
    // Setup our completion routine that will free the URB
    //
    IoSetCompletionRoutine(Irp, AsynchronousUrbRequestCompletion,
                           Urb, TRUE, TRUE, TRUE);


    //
    // We're submitting this URB to the device and it may 
    //  complete at an arbitrary point in the future, so 
    //  we need to mark it pending
    //
    IoMarkIrpPending(Irp);

    //
    // While we have the Irp in our queue, store the address of the URB
    // in the DriverContext[1] field of the Irp.   We do this so that 
    // if the Irp is canceled while in our queue, we have enough information 
    // to do the correct cleanup.
    //
    Irp->Tail.Overlay.DriverContext[1] = Urb;

    //
    // Queue the using the appropriate cancel safe queue routin
    //
#ifdef W2K3
    
    //
    // IoCsqInsertIrpEx returns whatever we return from OsrCsqInsertIoIrpEx, 
    //  which for us is STATUS_SUCCESS.
    //
    status = IoCsqInsertIrpEx(&DevExt->CancelSafeIoQueue,Irp,NULL,DevExt);
    ASSERT(status == STATUS_SUCCESS);

#else // W2K3
    IoCsqInsertIrp(&DevExt->CancelSafeIoQueue,Irp,NULL);
#endif // W2K3


    //
    // We have queued this IRP onto our internal queue. 
    //  Now call our helper routine ProcessNextIrpInQueue
    //  to pass this request (or possibly another request
    //  that was running parallel and beat us to the queue)
    //  to the host controller. 
    //
    // ProcessNextIrpInQueue will pass the request on to the
    //  host if we are in an applicable PnP state otherwise the
    //  request will just stay in the queue.
    //
    ProcessNextIrpInQueue(DevExt);    

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,
            ("SubmitIrpAndUrbAsync: Exit\n"));

    return STATUS_PENDING;
}


///////////////////////////////////////////////////////////////////////////////
//
// SubmitResetPipe
//
//      Resets the passed in pipe
//
//  INPUTS:
//
//      DevExt  -  One of our device extensions
//
//      Irp     -  Pointer to an IOCTL_OSRUSBFX2_RESET_PIPE
//                  IRP.
//
//      Pipe    -  The USBFX2_PIPE_ENUM for the pipe to reset
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      An appropriate NTSTATUS value
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      User context
//
//  NOTES:
//
//      Routine assumes that the output data buffer in the IRP is
//      valid for this request. Must be checked by caller.
//
//      Called relinquishes ownership of the IRP when calling this
//      routine, IRP must NOT be touched by caller after this routine
//      returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitResetPipe(PUSBFX2LK_EXT DevExt, PIRP Irp, USBFX2_PIPE_ENUM Pipe)
{
    NTSTATUS status;
    PURB resetUrb;
    PUSBFX2LK_PIPE_CONTEXT pipeContext = NULL;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ResetPipe: Enter\n"));

    //
    // Find the pipe context for the pipe that we're resetting
    //
    switch(Pipe) {

        case USBFx2BulkInPipe:
            pipeContext = DevExt->BulkInPipe;
            break;

        case USBFx2BulkOutPipe:
            pipeContext = DevExt->BulkOutPipe;
            break;
        
        case USBFx2InterruptPipe:
            pipeContext = DevExt->InterruptPipe;
            break;

        default:
            //
            // Bogus pipe
            //
            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("ResetPipe: Exit Invalid Pipe\n"));
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_INVALID_PARAMETER;
    }

    //
    // We'd better have a pipe at this point, 
    //  otherwise our device configuration failed
    //
    ASSERT(pipeContext);

    //
    // Allocate our reset URB
    //
    resetUrb = 
        (PURB)ExAllocatePoolWithTag(NonPagedPool,
                                    sizeof(struct _URB_PIPE_REQUEST),
                                    'PRxF');

    if (!resetUrb) {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("ResetPipe: Failed to allocate memory, Exiting.\n"));

        //
        // We need to complete the IRP ourselves
        //
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INSUFFICIENT_RESOURCES;

    }


    //
    // Setup the URB_FUNCTION_RESET_PIPE URB appropriately
    //
    resetUrb->UrbHeader.Length          = sizeof(struct _URB_PIPE_REQUEST);
    resetUrb->UrbHeader.Function        = URB_FUNCTION_RESET_PIPE;
    resetUrb->UrbPipeRequest.PipeHandle = pipeContext->PipeInformation.PipeHandle;

    status = SubmitIrpAndUrbAsync(DevExt, Irp, resetUrb);

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ResetPipe: Exit\n"));

    //
    // Return whatever status SubmitIrpAndUrbAsync returned
    //
    return status;

}


///////////////////////////////////////////////////////////////////////////////
//
// SubmitGetBarGraphState
//
//  This routine gets the state of the bar graph on the board
//
//
//  INPUTS:
//
//      DevExt  -  One of our device extensions
//
//      Irp     -  Pointer to an IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY
//                  IRP. User's buffer has already been validated
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      An appropriate NTSTATUS value
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      User context
//
//  NOTES:
//
//      Routine assumes that the output data buffer in the IRP is
//      valid for this request. Must be checked by caller.
//
//      Called relinquishes ownership of the IRP when calling this
//      routine, IRP must NOT be touched by caller after this routine
//      returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitGetBarGraphState(PUSBFX2LK_EXT DevExt, PIRP Irp)
{
    NTSTATUS status;
    PURB getBarGraphUrb;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("GetBarGraphState: Enter\n"));

    //
    // Allocate our get bar graph URB
    //
    getBarGraphUrb = 
        (PURB)ExAllocatePoolWithTag(NonPagedPool,
                                    sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                                    'BGxF');

    if (!getBarGraphUrb) {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("GetBarGraphState: Failed to allocate memory, Exiting.\n"));

        //
        // We need to complete the IRP ourselves
        //
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INSUFFICIENT_RESOURCES;

    }

    RtlZeroMemory(getBarGraphUrb,
                  sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));


    //
    // Build the vendor request with the appropriate 
    //  flags and command
    //
    //  We're getting data from the device,
    //  to we need to set the USBD_TRANSFER_DIRECTION_IN flag
    // 
    UsbBuildVendorRequest(getBarGraphUrb,
                          URB_FUNCTION_VENDOR_DEVICE,
                          sizeof(struct  _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                          USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN,
                          0,
                          USBFX2LK_READ_BARGRAPH_DISPLAY,
                          0,
                          0,
                          Irp->AssociatedIrp.SystemBuffer,
                          NULL,
                          sizeof(BAR_GRAPH_STATE),
                          NULL);

    status = SubmitIrpAndUrbAsync(DevExt, Irp, getBarGraphUrb);

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("GetBarGraphState: Exit\n"));

    //
    // Return whatever status SubmitIrpAndUrbAsync returned
    //
    return status;
    
}

///////////////////////////////////////////////////////////////////////////////
//
// SubmitSetBarGraphState
//
//  This routine sets the state of the bar graph on the board
//
//
//  INPUTS:
//
//      DevExt  -  One of our device extensions
//
//      Irp     -  Pointer to an IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY
//                  IRP. User's buffer has already been validated
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      An appropriate NTSTATUS value
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      User context
//
//  NOTES:
//
//      Routine assumes that the output data buffer in the IRP is
//      valid for this request. Must be checked by caller.
//
//      Called relinquishes ownership of the IRP when calling this
//      routine, IRP must NOT be touched by caller after this routine
//      returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitSetBarGraphState(PUSBFX2LK_EXT DevExt, PIRP Irp)
{

    NTSTATUS status;
    PURB setBarGraphUrb;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("SetBarGraphState: Enter\n"));

    //
    // Allocate our set bar graph URB
    //
    setBarGraphUrb = 
        (PURB)ExAllocatePoolWithTag(NonPagedPool,
                                    sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                                    'BSxF');

    if (!setBarGraphUrb) {

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
                ("SetBarGraphState: Failed to allocate memory, Exiting.\n"));

        //
        // We need to complete the IRP ourselves
        //
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INSUFFICIENT_RESOURCES;

    }

    RtlZeroMemory(setBarGraphUrb,
                  sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));


    //
    // Build the vendor request with the appropriate 
    //  flags and command
    //
    //  We're getting data from the device,
    //  to we need to set the USBD_TRANSFER_DIRECTION_IN flag
    // 
    UsbBuildVendorRequest(setBarGraphUrb,
                          URB_FUNCTION_VENDOR_DEVICE,
                          sizeof(struct  _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                          USBD_SHORT_TRANSFER_OK,
                          0,
                          USBFX2LK_SET_BARGRAPH_DISPLAY,
                          0,
                          0,
                          Irp->AssociatedIrp.SystemBuffer,
                          NULL,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -