usbio.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,196 行 · 第 1/3 页

C
1,196
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

  Module Name:

    UsbIo.c

  Abstract:

    USB I/O Abstraction Driver

  Revision History

--*/

#include "usbbus.h"

//
// USB I/O Support Function Prototypes
//
STATIC
EFI_STATUS
EFIAPI
UsbControlTransfer (
  IN       EFI_USB_IO_PROTOCOL        *This,
  IN       EFI_USB_DEVICE_REQUEST     *Request,
  IN       EFI_USB_DATA_DIRECTION     Direction,
  IN       UINT32                     Timeout,
  IN OUT   VOID                       *Data, OPTIONAL
  IN       UINTN                      DataLength, OPTIONAL
  OUT      UINT32                     *Status
  );

STATIC
EFI_STATUS
EFIAPI
UsbBulkTransfer (
  IN       EFI_USB_IO_PROTOCOL     *This,
  IN       UINT8                   DeviceEndpoint,
  IN OUT   VOID                    *Data,
  IN OUT   UINTN                   *DataLength,
  IN       UINTN                   Timeout,
  OUT      UINT32                  *Status
  );

STATIC
EFI_STATUS
EFIAPI
UsbAsyncInterruptTransfer (
  IN EFI_USB_IO_PROTOCOL                 * This,
  IN UINT8                               DeviceEndpoint,
  IN BOOLEAN                             IsNewTransfer,
  IN UINTN                               PollingInterval, OPTIONAL
  IN UINTN                               DataLength, OPTIONAL
  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     InterruptCallBack, OPTIONAL
  IN VOID                                *Context OPTIONAL
  );

STATIC
EFI_STATUS
EFIAPI
UsbSyncInterruptTransfer (
  IN       EFI_USB_IO_PROTOCOL     *This,
  IN       UINT8                   DeviceEndpoint,
  IN OUT   VOID                    *Data,
  IN OUT   UINTN                   *DataLength,
  IN       UINTN                   Timeout,
  OUT      UINT32                  *Status
  );

STATIC
EFI_STATUS
EFIAPI
UsbIsochronousTransfer (
  IN       EFI_USB_IO_PROTOCOL     *This,
  IN       UINT8                   DeviceEndpoint,
  IN OUT   VOID                    *Data,
  IN       UINTN                   DataLength,
  OUT      UINT32                  *Status
  );

STATIC
EFI_STATUS
EFIAPI
UsbAsyncIsochronousTransfer (
  IN        EFI_USB_IO_PROTOCOL                 * This,
  IN        UINT8                               DeviceEndpoint,
  IN OUT    VOID                                *Data,
  IN        UINTN                               DataLength,
  IN        EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,
  IN        VOID                                *Context OPTIONAL
  );

extern
EFI_STATUS
EFIAPI
UsbPortReset (
  IN EFI_USB_IO_PROTOCOL     *This
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetDeviceDescriptor (
  IN  EFI_USB_IO_PROTOCOL           *This,
  OUT EFI_USB_DEVICE_DESCRIPTOR     *DeviceDescriptor
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetActiveConfigDescriptor (
  IN  EFI_USB_IO_PROTOCOL           *This,
  OUT EFI_USB_CONFIG_DESCRIPTOR     *ConfigurationDescriptor
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetInterfaceDescriptor (
  IN  EFI_USB_IO_PROTOCOL              *This,
  OUT EFI_USB_INTERFACE_DESCRIPTOR     *InterfaceDescriptor
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetEndpointDescriptor (
  IN  EFI_USB_IO_PROTOCOL             *This,
  IN  UINT8                           EndpointIndex,
  OUT EFI_USB_ENDPOINT_DESCRIPTOR     *EndpointDescriptor
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetStringDescriptor (
  IN  EFI_USB_IO_PROTOCOL     *This,
  IN  UINT16                  LangID,
  IN  UINT8                   StringIndex,
  OUT CHAR16                  **String
  );

STATIC
EFI_STATUS
EFIAPI
UsbGetSupportedLanguages (
  IN  EFI_USB_IO_PROTOCOL      *This,
  OUT UINT16                   **LangIDTable,
  OUT UINT16                   *TableSize
  );

//
// USB I/O Interface structure
//
STATIC EFI_USB_IO_PROTOCOL  UsbIoInterface = {
  UsbControlTransfer,
  UsbBulkTransfer,
  UsbAsyncInterruptTransfer,
  UsbSyncInterruptTransfer,
  UsbIsochronousTransfer,
  UsbAsyncIsochronousTransfer,
  UsbGetDeviceDescriptor,
  UsbGetActiveConfigDescriptor,
  UsbGetInterfaceDescriptor,
  UsbGetEndpointDescriptor,
  UsbGetStringDescriptor,
  UsbGetSupportedLanguages,
  UsbPortReset
};

VOID
InitializeUsbIoInstance (
  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController
  )
/*++

Routine Description:

  Initialize the instance of UsbIo controller

Arguments:

  UsbIoController - A pointer to controller structure of UsbIo

Returns:

--*/
{
  //
  // Copy EFI_USB_IO protocol instance
  //
  EfiCopyMem (
    &UsbIoController->UsbIo,
    &UsbIoInterface,
    sizeof (EFI_USB_IO_PROTOCOL)
    );
}
//
// Implementation
//
STATIC
EFI_STATUS
EFIAPI
UsbControlTransfer (
  IN       EFI_USB_IO_PROTOCOL        *This,
  IN       EFI_USB_DEVICE_REQUEST     *Request,
  IN       EFI_USB_DATA_DIRECTION     Direction,
  IN       UINT32                     Timeout,
  IN OUT   VOID                       *Data, OPTIONAL
  IN       UINTN                      DataLength, OPTIONAL
  OUT      UINT32                     *Status
  )
/*++

  Routine Description:
    This function is used to manage a USB device with a control transfer pipe.

  Arguments:
    This        -   Indicates calling context.
    Request     -   A pointer to the USB device request that will be sent to
                    the USB device.
    Direction   -   Indicates the data direction.
    Data        -   A pointer to the buffer of data that will be transmitted
                    to USB device or received from USB device.
    Timeout     -   Indicates the transfer should be completed within this time
                    frame.
    DataLength  -   The size, in bytes, of the data buffer specified by Data.
    Status      -   A pointer to the result of the USB transfer.

  Returns:
    EFI_SUCCESS
    EFI_INVALID_PARAMETER
    EFI_OUT_OF_RESOURCES
    EFI_TIMEOUT
    EFI_DEVICE_ERROR

--*/
{
  USB_IO_CONTROLLER_DEVICE  *UsbIoController;
  EFI_STATUS                RetStatus;
  USB_IO_DEVICE             *UsbIoDev;
  UINT8                     MaxPacketLength;
  UINT32                    TransferResult;
  BOOLEAN                   Disconnected;
  
  //
  // Parameters Checking
  //
  if (Status == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // leave the HostController's ControlTransfer
  // to perform other parameters checking
  //
  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
  UsbIoDev        = UsbIoController->UsbDevice;
  MaxPacketLength = UsbIoDev->DeviceDescriptor.MaxPacketSize0;

 
  if (Request->Request     == USB_DEV_CLEAR_FEATURE && 
      Request->RequestType == 0x02                  && 
      Request->Value       == EfiUsbEndpointHalt) {
    //
    // Reduce the remove delay time for system response
    //
    IsDeviceDisconnected (UsbIoController, &Disconnected);
    if (!EFI_ERROR (Status) && Disconnected == TRUE) {
      DEBUG ((gUSBErrorLevel, "Device is disconnected when trying reset\n"));
      return EFI_DEVICE_ERROR;
    }
  }
  //
  // using HostController's ControlTransfer to complete the request
  //
  RetStatus = UsbVirtualHcControlTransfer (
                UsbIoDev->BusController,
                UsbIoDev->DeviceAddress,
                UsbIoDev->DeviceSpeed,
                MaxPacketLength,
                Request,
                Direction,
                Data,
                &DataLength,
                (UINTN) Timeout,
                UsbIoDev->Translator,
                &TransferResult
                );

  *Status = TransferResult;

  if (Request->Request == USB_DEV_CLEAR_FEATURE && Request->RequestType == 0x02 && Request->Value == EfiUsbEndpointHalt) {
    //
    // This is a UsbClearEndpointHalt request
    // Need to clear data toggle
    // Request.Index == EndpointAddress
    //
    if (!EFI_ERROR (RetStatus) && TransferResult == EFI_USB_NOERROR) {
      SetDataToggleBit (
        This,
        (UINT8) Request->Index,
        0
        );
    }
  }

  return RetStatus;
}

STATIC
EFI_STATUS
EFIAPI
UsbBulkTransfer (
  IN       EFI_USB_IO_PROTOCOL     *This,
  IN       UINT8                   DeviceEndpoint,
  IN OUT   VOID                    *Data,
  IN OUT   UINTN                   *DataLength,
  IN       UINTN                   Timeout,
  OUT      UINT32                  *Status
  )
/*++

  Routine Description:
    This function is used to manage a USB device with the bulk transfer pipe.

  Arguments:
    This            - Indicates calling context.
    DeviceEndpoint  - The destination USB device endpoint to which the device
                      request is being sent.
    Data            - A pointer to the buffer of data that will be transmitted
                      to USB device or received from USB device.
    DataLength      - On input, the size, in bytes, of the data buffer
                      specified by Data.  On output, the number of bytes that
                      were actually transferred.
    Timeout         - Indicates the transfer should be completed within this
                      time frame.
    Status          - This parameter indicates the USB transfer status.

  Returns:
    EFI_SUCCESS
    EFI_INVALID_PARAMETER
    EFI_OUT_OF_RESOURCES
    EFI_TIMEOUT
    EFI_DEVICE_ERROR

--*/
{
  USB_IO_DEVICE             *UsbIoDev;
  UINTN                     MaxPacketLength;
  UINT8                     DataToggle;
  UINT8                     OldToggle;
  EFI_STATUS                RetStatus;
  USB_IO_CONTROLLER_DEVICE  *UsbIoController;
  ENDPOINT_DESC_LIST_ENTRY  *EndPointListEntry;
  UINT8                     DataBuffersNumber;
  UINT32                    TransferResult;

  DataBuffersNumber = 1;
  UsbIoController   = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
  UsbIoDev          = UsbIoController->UsbDevice;

  //
  // Parameters Checking
  //
  if ((DeviceEndpoint & 0x7F) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DeviceEndpoint & 0x7F) > 15) {
    return EFI_INVALID_PARAMETER;
  }

  if (Status == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  EndPointListEntry = FindEndPointListEntry (
                        This,
                        DeviceEndpoint
                        );

  if (EndPointListEntry == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x02) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // leave the HostController's BulkTransfer

⌨️ 快捷键说明

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