usb.c

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

C
822
字号
    //
    // Skip this mismatch descriptor
    //
    Length -= Len;
    ptr += Len;
    Parsed += Len;
  }

  *ParsedBytes = Parsed;

  return EFI_SUCCESS;
}


STATIC
EFI_STATUS
ParseThisEndpoint (
  IN  ENDPOINT_DESC_LIST_ENTRY     *EndpointEntry,
  IN  UINT8                        *Buffer,
  IN  UINTN                        BufferLength,
  OUT UINTN                        *ParsedBytes
  )
/*++

  Routine Description:
    Get the start position of next wanted endpoint descriptor.

  Arguments:
    EndpointEntry - ENDPOINT_DESC_LIST_ENTRY
    Buffer        - Buffer to parse 
    BufferLength  - Buffer Length
    ParsedBytes   - Parsed Bytes to return
  Returns:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8       *ptr;
  EFI_STATUS  Status;
  UINTN       SkipBytes;

  //
  // Skip some data for this interface
  //
  Status = GetExpectedDescriptor (
            Buffer,
            BufferLength,
            USB_DT_ENDPOINT,
            sizeof (EFI_USB_ENDPOINT_DESCRIPTOR),
            &SkipBytes
            );

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

  ptr           = Buffer + SkipBytes;
  *ParsedBytes  = SkipBytes;

  EfiCopyMem (
    &EndpointEntry->EndpointDescriptor,
    ptr,
    sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)
    );

  *ParsedBytes += sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
ParseThisInterface (
  IN  INTERFACE_DESC_LIST_ENTRY     *InterfaceEntry,
  IN  UINT8                         *Buffer,
  IN  UINTN                         *BufferLen,
  OUT UINTN                         *ParsedBytes
  )
/*++

  Routine Description:
    Get the start position of next wanted interface descriptor.

  Arguments:
    InterfaceEntry - INTERFACE_DESC_LIST_ENTRY
    Buffer         - Buffer to parse 
    BufferLength   - Buffer Length
    ParsedBytes    - Parsed Bytes to return

  Returns:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8                     *ptr;
  UINTN                     SkipBytes;
  UINTN                     Index;
  UINTN                     Length;
  UINTN                     Parsed;
  ENDPOINT_DESC_LIST_ENTRY  *EndpointEntry;
  EFI_STATUS                Status;

  //
  // Skip some data for this interface
  //
  Status = GetExpectedDescriptor (
            Buffer,
            *BufferLen,
            USB_DT_INTERFACE,
            sizeof (EFI_USB_INTERFACE_DESCRIPTOR),
            &SkipBytes
            );

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

  ptr           = Buffer + SkipBytes;
  *ParsedBytes  = SkipBytes;

  //
  // Copy the interface descriptor
  //
  EfiCopyMem (
    &InterfaceEntry->InterfaceDescriptor,
    ptr,
    sizeof (EFI_USB_INTERFACE_DESCRIPTOR)
    );

  ptr = Buffer + sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
  *ParsedBytes += sizeof (EFI_USB_INTERFACE_DESCRIPTOR);

  InitializeListHead (&InterfaceEntry->EndpointDescListHead);

  Length = *BufferLen - SkipBytes - sizeof (EFI_USB_INTERFACE_DESCRIPTOR);

  for (Index = 0; Index < InterfaceEntry->InterfaceDescriptor.NumEndpoints; Index++) {
    EndpointEntry = EfiLibAllocateZeroPool (sizeof (ENDPOINT_DESC_LIST_ENTRY));
    if (EndpointEntry == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    
    //
    // Parses all the endpoint descriptors within this interface.
    //
    Status = ParseThisEndpoint (EndpointEntry, ptr, Length, &Parsed);

    if (EFI_ERROR (Status)) {
      gBS->FreePool (EndpointEntry);
      return Status;
    }

    InsertTailList (
      &InterfaceEntry->EndpointDescListHead,
      &EndpointEntry->Link
      );

    Length -= Parsed;
    ptr += Parsed;
    *ParsedBytes += Parsed;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
ParseThisConfig (
  IN CONFIG_DESC_LIST_ENTRY     *ConfigDescEntry,
  IN UINT8                      *Buffer,
  IN UINTN                      Length
  )
/*++

  Routine Description:
    Parse the current configuration descriptior.

  Arguments:
    ConfigDescEntry - CONFIG_DESC_LIST_ENTRY
    Buffer          - Buffer to parse 
    Length          - Buffer Length

  Returns
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8                     *ptr;
  UINT8                     NumInterface;
  UINTN                     Index;
  INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;
  UINTN                     SkipBytes;
  UINTN                     Parsed;
  EFI_STATUS                Status;
  UINTN                     LengthLeft;

  //
  //  First skip the current config descriptor;
  //
  Status = GetExpectedDescriptor (
            Buffer,
            Length,
            USB_DT_CONFIG,
            sizeof (EFI_USB_CONFIG_DESCRIPTOR),
            &SkipBytes
            );

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

  ptr = Buffer + SkipBytes;

  EfiCopyMem (
    &ConfigDescEntry->CongfigDescriptor,
    ptr,
    sizeof (EFI_USB_CONFIG_DESCRIPTOR)
    );

  NumInterface = ConfigDescEntry->CongfigDescriptor.NumInterfaces;

  //
  // Skip size of Configuration Descriptor
  //
  ptr += sizeof (EFI_USB_CONFIG_DESCRIPTOR);

  LengthLeft = Length - SkipBytes - sizeof (EFI_USB_CONFIG_DESCRIPTOR);

  for (Index = 0; Index < NumInterface; Index++) {
    //
    // Parse all Interface
    //
    InterfaceEntry = EfiLibAllocateZeroPool (sizeof (INTERFACE_DESC_LIST_ENTRY));
    if (InterfaceEntry == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = ParseThisInterface (InterfaceEntry, ptr, &LengthLeft, &Parsed);
    if (EFI_ERROR (Status)) {
      gBS->FreePool (InterfaceEntry);
      return Status;
    }

    InsertTailList (
      &ConfigDescEntry->InterfaceDescListHead,
      &InterfaceEntry->Link
      );

    //
    // Parsed for next interface
    //
    LengthLeft -= Parsed;
    ptr += Parsed;
  }
  //
  // Parse for additional alt setting;
  //
  return EFI_SUCCESS;
}

EFI_STATUS
UsbSetConfiguration (
  IN USB_IO_DEVICE     *UsbIoDev,
  IN UINTN             ConfigurationValue
  )
/*++

  Routine Description:
    Set the device to a configuration value.
    
  Arguments:
    UsbIoDev            -   USB_IO_DEVICE to be set configuration
    ConfigrationValue   -   The configuration value to be set to that device
    
  Returns:
    EFI_SUCCESS
    EFI_DEVICE_ERROR
    
--*/
{
  EFI_LIST_ENTRY          *NextEntry;
  CONFIG_DESC_LIST_ENTRY  *ConfigEntry;
  UINT32                  Status;
  EFI_STATUS              Result;
  EFI_USB_IO_PROTOCOL     *UsbIo;

  UsbIo     = &(UsbIoDev->UsbController[0]->UsbIo);
  NextEntry = UsbIoDev->ConfigDescListHead.ForwardLink;

  while (NextEntry != &UsbIoDev->ConfigDescListHead) {
    //
    // Get one entry
    //
    ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;
    if (ConfigEntry->CongfigDescriptor.ConfigurationValue == ConfigurationValue) {
      //
      // Find one, set to the active configuration
      //
      UsbIoDev->ActiveConfig = ConfigEntry;
      break;
    }

    NextEntry = NextEntry->ForwardLink;
  }
  //
  // Next Entry should not be null
  //
  Result = UsbSetDeviceConfiguration (
            UsbIo,
            (UINT16) ConfigurationValue,
            &Status
            );

  return Result;
}

EFI_STATUS
UsbSetDefaultConfiguration (
  IN  USB_IO_DEVICE      *UsbIoDev
  )
/*++

  Routine Description:
    Set the device to a default configuration value.
    
  Arguments:
    UsbIoDev       -    USB_IO_DEVICE to be set configuration
    
  Returns
    EFI_SUCCESS
    EFI_DEVICE_ERROR
    
--*/
{
  CONFIG_DESC_LIST_ENTRY  *ConfigEntry;
  UINT16                  ConfigValue;
  EFI_LIST_ENTRY          *NextEntry;

  if (IsListEmpty (&UsbIoDev->ConfigDescListHead)) {
    return EFI_DEVICE_ERROR;
  }

  NextEntry   = UsbIoDev->ConfigDescListHead.ForwardLink;

  ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;
  ConfigValue = ConfigEntry->CongfigDescriptor.ConfigurationValue;

  return UsbSetConfiguration (UsbIoDev, ConfigValue);
}

VOID
UsbDestroyAllConfiguration (
  IN  USB_IO_DEVICE      *UsbIoDevice
  )
/*++

  Routine Description:
    Delete all configuration data when device is not used.
    
  Arguments:
    UsbIoDevice  - USB_IO_DEVICE to be set configuration
  
  Returns:
    N/A
    
--*/
{
  CONFIG_DESC_LIST_ENTRY    *ConfigEntry;
  INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;
  ENDPOINT_DESC_LIST_ENTRY  *EndpointEntry;
  EFI_LIST_ENTRY            *NextEntry;

  //
  // Delete all configuration descriptor data
  //
  ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) UsbIoDevice->ConfigDescListHead.ForwardLink;

  while (ConfigEntry != (CONFIG_DESC_LIST_ENTRY *) &UsbIoDevice->ConfigDescListHead) {
    //
    // Delete all its interface descriptors
    //
    InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) ConfigEntry->InterfaceDescListHead.ForwardLink;

    while (InterfaceEntry != (INTERFACE_DESC_LIST_ENTRY *) &ConfigEntry->InterfaceDescListHead) {
      //
      // Delete all its endpoint descriptors
      //
      EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) InterfaceEntry->EndpointDescListHead.ForwardLink;
      while (EndpointEntry != (ENDPOINT_DESC_LIST_ENTRY *) &InterfaceEntry->EndpointDescListHead) {
        NextEntry = ((EFI_LIST_ENTRY *) EndpointEntry)->ForwardLink;
        RemoveEntryList ((EFI_LIST_ENTRY *) EndpointEntry);
        gBS->FreePool (EndpointEntry);
        EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) NextEntry;
      }

      NextEntry = ((EFI_LIST_ENTRY *) InterfaceEntry)->ForwardLink;
      RemoveEntryList ((EFI_LIST_ENTRY *) InterfaceEntry);
      gBS->FreePool (InterfaceEntry);
      InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) NextEntry;
    }

    NextEntry = ((EFI_LIST_ENTRY *) ConfigEntry)->ForwardLink;
    RemoveEntryList ((EFI_LIST_ENTRY *) ConfigEntry);
    gBS->FreePool (ConfigEntry);
    ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;
  }
}

⌨️ 快捷键说明

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