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

📄 usb.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
    //
    // Descriptor length should be at least 2
    // and should not exceed the buffer length
    //
    if (Len < 2) {
      return EFI_DEVICE_ERROR;
    }

    if(Len > Length) {
      return EFI_DEVICE_ERROR;
    }

    //
    // 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.

  Parameters:
  
  Return Value:
    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.

  Parameters:
  
  Return Value:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8                       *ptr;
  UINTN                       SkipBytes;
  UINTN                       i;
  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(i = 0; i < (InterfaceEntry->InterfaceDescriptor).NumEndpoints; i++) {
    EndpointEntry = NULL;
    Status = gBS->AllocatePool(
                    EfiBootServicesData,
                    sizeof(ENDPOINT_DESC_LIST_ENTRY),
                    &EndpointEntry
                  );

    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }
    
    EfiZeroMem(EndpointEntry, sizeof(ENDPOINT_DESC_LIST_ENTRY));

    //
    // 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.

  Parameters:
  
  Return Value:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8                       *ptr;
  UINT8                       NumInterface;
  UINTN                       i;
  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(i = 0; i < NumInterface; i++) {
    //
    // Parse all Interface
    //
    InterfaceEntry = NULL;
    Status = gBS->AllocatePool(
                    EfiBootServicesData,
                    sizeof(INTERFACE_DESC_LIST_ENTRY),
                    &InterfaceEntry
                  );

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

    EfiZeroMem(InterfaceEntry, sizeof(INTERFACE_DESC_LIST_ENTRY));

    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   *Dev,
  IN  UINTN           ConfigurationValue
  )
/*++

  Routine Description:
    Set the device to a configuration value.
    
  Parameters:
    Dev                 -   USB_IO_DEVICE to be set configuration
    ConfigrationValue   -   The configuration value to be set to that device
    
  Return Value:
    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 = &(Dev->UsbController[0]->UsbIo);
  NextEntry = (Dev->ConfigDescListHead).ForwardLink;

  while(NextEntry != &Dev->ConfigDescListHead) {
    //
    // Get one entry
    //
    ConfigEntry = (CONFIG_DESC_LIST_ENTRY *)NextEntry;
    if ((ConfigEntry->CongfigDescriptor).ConfigurationValue
      == ConfigurationValue) {
      //
      // Find one, set to the active configuration
      //
      Dev->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      *Dev
  )
/*++

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

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

  NextEntry = (Dev->ConfigDescListHead).ForwardLink;

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

  return UsbSetConfiguration(Dev, ConfigValue);
}

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

  Routine Description:
    Delete all configuration data when device is not used.
    
  Parameter:
    Dev         -    USB_IO_DEVICE to be set configuration
  
  Return Value:
    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*)(Dev->ConfigDescListHead).ForwardLink;

  while (ConfigEntry != (CONFIG_DESC_LIST_ENTRY *)&Dev->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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -