Пример #1
0
/**
  Get the usb endpoint descriptor.

  @param  PeiServices          General-purpose services that are available to every PEIM.
  @param  This                 Indicates the PEI_USB_IO_PPI instance.
  @param  EndpointIndex        The valid index of the specified endpoint.
  @param  EndpointDescriptor   Request endpoint descriptor.

  @retval EFI_SUCCESS       Usb endpoint descriptor is obtained successfully.
  @retval EFI_NOT_FOUND     Usb endpoint descriptor is NOT found.

**/
EFI_STATUS
EFIAPI
PeiUsbGetEndpointDescriptor (
  IN  EFI_PEI_SERVICES               **PeiServices,
  IN  PEI_USB_IO_PPI                 *This,
  IN  UINT8                          EndpointIndex,
  OUT EFI_USB_ENDPOINT_DESCRIPTOR    **EndpointDescriptor
  )
{
  PEI_USB_DEVICE  *PeiUsbDev;

  PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);

  ASSERT (EndpointDescriptor != NULL);

  //
  // The valid range of EndpointIndex is 0..15
  // If EndpointIndex is lesser than 15 but larger than the number of interfaces,
  // a EFI_NOT_FOUND should be returned
  //
  ASSERT (EndpointIndex <= 15);

  if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) {
    return EFI_NOT_FOUND;
  }

  *EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex];

  return EFI_SUCCESS;
}
Пример #2
0
/**
  Get the usb interface descriptor.

  @param  PeiServices          General-purpose services that are available to every PEIM.
  @param  This                 Indicates the PEI_USB_IO_PPI instance.
  @param  InterfaceDescriptor  Request interface descriptor.


  @retval EFI_SUCCESS          Usb interface descriptor is obtained successfully.

**/
EFI_STATUS
EFIAPI
PeiUsbGetInterfaceDescriptor (
  IN  EFI_PEI_SERVICES               **PeiServices,
  IN  PEI_USB_IO_PPI                 *This,
  OUT EFI_USB_INTERFACE_DESCRIPTOR   **InterfaceDescriptor
  )
{
  PEI_USB_DEVICE  *PeiUsbDev;
  PeiUsbDev             = PEI_USB_DEVICE_FROM_THIS (This);
  *InterfaceDescriptor  = PeiUsbDev->InterfaceDesc;
  return EFI_SUCCESS;
}
Пример #3
0
/**
  Submits control transfer to a target USB device.
  
  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
  @param  This                   The pointer of PEI_USB_IO_PPI.
  @param  Request                USB device request to send.
  @param  Direction              Specifies the data direction for the data stage.
  @param  Timeout                Indicates the maximum timeout, in millisecond.
  @param  Data                   Data buffer to be transmitted or received from USB device.
  @param  DataLength             The size (in bytes) of the data buffer.

  @retval EFI_SUCCESS            Transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
  @retval EFI_TIMEOUT            Transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
PeiUsbControlTransfer (
  IN     EFI_PEI_SERVICES          **PeiServices,
  IN     PEI_USB_IO_PPI            *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
  )
{
  EFI_STATUS                  Status;
  PEI_USB_DEVICE              *PeiUsbDev;
  UINT32                      TransferResult;

  PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);

  if (PeiUsbDev->Usb2HcPpi != NULL) {
    Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (
                        PeiServices,
                        PeiUsbDev->Usb2HcPpi,
                        PeiUsbDev->DeviceAddress,
                        PeiUsbDev->DeviceSpeed,
                        PeiUsbDev->MaxPacketSize0,
                        Request,
                        Direction,
                        Data,
                        &DataLength,
                        Timeout,
                        &(PeiUsbDev->Translator),
                        &TransferResult
                        );
  } else {
    Status = PeiUsbDev->UsbHcPpi->ControlTransfer (
                        PeiServices,
                        PeiUsbDev->UsbHcPpi,
                        PeiUsbDev->DeviceAddress,
                        PeiUsbDev->DeviceSpeed,
                        PeiUsbDev->MaxPacketSize0,
                        Request,
                        Direction,
                        Data,
                        &DataLength,
                        Timeout,
                        &TransferResult
                        );
  }
  return Status;
}
Пример #4
0
/**
  Reset the port and re-configure the usb device.

  @param  PeiServices    General-purpose services that are available to every PEIM.
  @param  This           Indicates the PEI_USB_IO_PPI instance.

  @retval EFI_SUCCESS    Usb device is reset and configured successfully.
  @retval Others         Other failure occurs.

**/
EFI_STATUS
EFIAPI
PeiUsbPortReset (
  IN EFI_PEI_SERVICES               **PeiServices,
  IN PEI_USB_IO_PPI                 *This
  )
{
  PEI_USB_DEVICE  *PeiUsbDev;
  EFI_STATUS      Status;
  UINT8           Address;

  PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);

  ResetRootPort (
    PeiServices,
    PeiUsbDev->UsbHcPpi,
    PeiUsbDev->Usb2HcPpi,
    PeiUsbDev->DeviceAddress,
    0
    );

  //
  // Set address
  //
  Address                   = PeiUsbDev->DeviceAddress;
  PeiUsbDev->DeviceAddress  = 0;

  Status = PeiUsbSetDeviceAddress (
            PeiServices,
            This,
            Address
            );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  PeiUsbDev->DeviceAddress = Address;

  //
  // Set default configuration
  //
  Status = PeiUsbSetConfiguration (
            PeiServices,
            This
            );

  return Status;
}
Пример #5
0
/**
  Clear Endpoint Halt.

  @param  PeiServices       General-purpose services that are available to every PEIM.
  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
  @param  EndpointAddress   The endpoint address.

  @retval EFI_SUCCESS       Endpoint halt is cleared successfully.
  @retval EFI_DEVICE_ERROR  Cannot clear the endpoint halt status due to a hardware error.
  @retval Others            Other failure occurs.

**/
EFI_STATUS
PeiUsbClearEndpointHalt (
  IN EFI_PEI_SERVICES         **PeiServices,
  IN PEI_USB_IO_PPI           *UsbIoPpi,
  IN UINT8                    EndpointAddress
  )
{
  EFI_STATUS                  Status;
  PEI_USB_DEVICE              *PeiUsbDev;
  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
  UINT8                       EndpointIndex;

  EndpointIndex = 0;
  PeiUsbDev     = PEI_USB_DEVICE_FROM_THIS (UsbIoPpi);

  while (EndpointIndex < MAX_ENDPOINT) {
    Status = UsbIoPpi->UsbGetEndpointDescriptor (PeiServices, UsbIoPpi, EndpointIndex, &EndpointDescriptor);
    if (EFI_ERROR (Status)) {
      return EFI_INVALID_PARAMETER;
    }

    if (EndpointDescriptor->EndpointAddress == EndpointAddress) {
      break;
    }

    EndpointIndex++;
  }

  if (EndpointIndex == MAX_ENDPOINT) {
    return EFI_INVALID_PARAMETER;
  }

  Status = PeiUsbClearDeviceFeature (
            PeiServices,
            UsbIoPpi,
            EfiUsbEndpoint,
            EfiUsbEndpointHalt,
            EndpointAddress
            );

  //
  // set data toggle to zero.
  //
  if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
    PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
  }

  return Status;
}
Пример #6
0
/**
  Submits bulk transfer to a bulk endpoint of a USB device.
  
  @param  PeiServices           The pointer of EFI_PEI_SERVICES.
  @param  This                  The pointer of PEI_USB_IO_PPI.
  @param  DeviceEndpoint        Endpoint number and its direction in bit 7.
  @param  Data                  A pointer to the buffer of data to transmit 
                                from or receive into.
  @param  DataLength            The lenght of the data buffer.
  @param  Timeout               Indicates the maximum time, in millisecond, which the
                                transfer is allowed to complete.

  @retval EFI_SUCCESS           The transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
  @retval EFI_INVALID_PARAMETER Parameters are invalid.
  @retval EFI_TIMEOUT           The transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.

**/
EFI_STATUS
EFIAPI
PeiUsbBulkTransfer (
  IN     EFI_PEI_SERVICES    **PeiServices,
  IN     PEI_USB_IO_PPI      *This,
  IN     UINT8               DeviceEndpoint,
  IN OUT VOID                *Data,
  IN OUT UINTN               *DataLength,
  IN     UINTN               Timeout
  )
{
  EFI_STATUS                  Status;
  PEI_USB_DEVICE              *PeiUsbDev;
  UINT32                      TransferResult;
  UINTN                       MaxPacketLength;
  UINT8                       DataToggle;
  UINT8                       OldToggle;
  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
  UINT8                       EndpointIndex;
  VOID                        *Data2[EFI_USB_MAX_BULK_BUFFER_NUM];

  PeiUsbDev     = PEI_USB_DEVICE_FROM_THIS (This);

  EndpointDescriptor = NULL;
  EndpointIndex = 0;
  Data2[0] = Data;
  Data2[1] = NULL;

  while (EndpointIndex < MAX_ENDPOINT) {
    Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
    if (EFI_ERROR (Status)) {
      return EFI_INVALID_PARAMETER;
    }

    if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
      break;
    }

    EndpointIndex++;
  }

  if (EndpointIndex == MAX_ENDPOINT) {
    return EFI_INVALID_PARAMETER;
  }

  MaxPacketLength = PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize;
  if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
    DataToggle = 1;
  } else {
    DataToggle = 0;
  }

  OldToggle = DataToggle;

  if (PeiUsbDev->Usb2HcPpi != NULL) {
    Status = PeiUsbDev->Usb2HcPpi->BulkTransfer (
                        PeiServices,
                        PeiUsbDev->Usb2HcPpi,
                        PeiUsbDev->DeviceAddress,
                        DeviceEndpoint,
                        PeiUsbDev->DeviceSpeed,
                        MaxPacketLength,
                        Data2,
                        DataLength,
                        &DataToggle,
                        Timeout,
                        &(PeiUsbDev->Translator),
                        &TransferResult
                        );
  } else {
    Status = PeiUsbDev->UsbHcPpi->BulkTransfer (
                        PeiServices,
                        PeiUsbDev->UsbHcPpi,
                        PeiUsbDev->DeviceAddress,
                        DeviceEndpoint,
                        (UINT8) MaxPacketLength,
                        Data,
                        DataLength,
                        &DataToggle,
                        Timeout,
                        &TransferResult
                        );
  }

  if (OldToggle != DataToggle) {
    PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
  }

  return Status;
}
Пример #7
0
/**
  Submits control transfer to a target USB device.
  
  @param  PeiServices            The pointer of EFI_PEI_SERVICES.
  @param  This                   The pointer of PEI_USB_IO_PPI.
  @param  Request                USB device request to send.
  @param  Direction              Specifies the data direction for the data stage.
  @param  Timeout                Indicates the maximum timeout, in millisecond. If Timeout
                                 is 0, then the caller must wait for the function to be
                                 completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
  @param  Data                   Data buffer to be transmitted or received from USB device.
  @param  DataLength             The size (in bytes) of the data buffer.

  @retval EFI_SUCCESS            Transfer was completed successfully.
  @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
  @retval EFI_TIMEOUT            Transfer failed due to timeout.
  @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.

**/
EFI_STATUS
EFIAPI
PeiUsbControlTransfer (
  IN     EFI_PEI_SERVICES          **PeiServices,
  IN     PEI_USB_IO_PPI            *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
  )
{
  EFI_STATUS                  Status;
  PEI_USB_DEVICE              *PeiUsbDev;
  UINT32                      TransferResult;
  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
  UINT8                       EndpointIndex;

  PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);

  EndpointDescriptor = NULL;
  EndpointIndex = 0;

  if ((Request->Request     == USB_REQ_CLEAR_FEATURE) &&
      (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&
      (Request->Value       == USB_FEATURE_ENDPOINT_HALT)) {
    //
    // Request->Index is the Endpoint Address, use it to get the Endpoint Index.
    //
    while (EndpointIndex < MAX_ENDPOINT) {
      Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
      if (EFI_ERROR (Status)) {
        return EFI_INVALID_PARAMETER;
      }

      if (EndpointDescriptor->EndpointAddress == Request->Index) {
        break;
      }

      EndpointIndex++;
    }

    if (EndpointIndex == MAX_ENDPOINT) {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (PeiUsbDev->Usb2HcPpi != NULL) {
    Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (
                        PeiServices,
                        PeiUsbDev->Usb2HcPpi,
                        PeiUsbDev->DeviceAddress,
                        PeiUsbDev->DeviceSpeed,
                        PeiUsbDev->MaxPacketSize0,
                        Request,
                        Direction,
                        Data,
                        &DataLength,
                        Timeout,
                        &(PeiUsbDev->Translator),
                        &TransferResult
                        );
  } else {
    Status = PeiUsbDev->UsbHcPpi->ControlTransfer (
                        PeiServices,
                        PeiUsbDev->UsbHcPpi,
                        PeiUsbDev->DeviceAddress,
                        PeiUsbDev->DeviceSpeed,
                        (UINT8) PeiUsbDev->MaxPacketSize0,
                        Request,
                        Direction,
                        Data,
                        &DataLength,
                        Timeout,
                        &TransferResult
                        );
  }

  //
  // Reset the endpoint toggle when endpoint stall is cleared
  //
  if ((Request->Request     == USB_REQ_CLEAR_FEATURE) &&
      (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&
      (Request->Value       == USB_FEATURE_ENDPOINT_HALT)) {
    if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
      PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
    }
  }

  DEBUG ((EFI_D_INFO, "PeiUsbControlTransfer: %r\n", Status));
  return Status;
}