/** @file

    Manage Usb Descriptor List

Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UsbBus.h"

/**
  Free the interface setting descriptor.

  @param  Setting               The descriptor to free.

**/
VOID
UsbFreeInterfaceDesc (
  IN USB_INTERFACE_SETTING  *Setting
  )
{
  USB_ENDPOINT_DESC  *Ep;
  UINTN              Index;

  if (Setting->Endpoints != NULL) {
    //
    // Each interface setting may have several endpoints, free them first.
    //
    for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {
      Ep = Setting->Endpoints[Index];

      if (Ep != NULL) {
        FreePool (Ep);
      }
    }

    //
    // Only call FreePool() if NumEndpoints > 0.
    //
    if (Setting->Desc.NumEndpoints > 0) {
      FreePool (Setting->Endpoints);
    }
  }

  FreePool (Setting);
}

/**
  Free a configuration descriptor with its interface
  descriptors. It may be initialized partially.

  @param  Config                The configuration descriptor to free.

**/
VOID
UsbFreeConfigDesc (
  IN USB_CONFIG_DESC  *Config
  )
{
  USB_INTERFACE_DESC  *Interface;
  UINTN               Index;
  UINTN               SetIndex;

  if (Config->Interfaces != NULL) {
    //
    // A configuration may have several interfaces, free the interface
    //
    for (Index = 0; Index < Config->Desc.NumInterfaces; Index++) {
      Interface = Config->Interfaces[Index];

      if (Interface == NULL) {
        continue;
      }

      //
      // Each interface may have several settings, free the settings
      //
      for (SetIndex = 0; SetIndex < Interface->NumOfSetting; SetIndex++) {
        if (Interface->Settings[SetIndex] != NULL) {
          UsbFreeInterfaceDesc (Interface->Settings[SetIndex]);
        }
      }

      FreePool (Interface);
    }

    FreePool (Config->Interfaces);
  }

  FreePool (Config);
}

/**
  Free a device descriptor with its configurations.

  @param  DevDesc               The device descriptor.

**/
VOID
UsbFreeDevDesc (
  IN USB_DEVICE_DESC  *DevDesc
  )
{
  UINTN  Index;

  if (DevDesc->Configs != NULL) {
    for (Index = 0; Index < DevDesc->Desc.NumConfigurations; Index++) {
      if (DevDesc->Configs[Index] != NULL) {
        UsbFreeConfigDesc (DevDesc->Configs[Index]);
      }
    }

    FreePool (DevDesc->Configs);
  }

  FreePool (DevDesc);
}

/**
  Create a descriptor.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.
  @param  Type                  The type of descriptor to create.
  @param  Consumed              Number of bytes consumed.

  @return Created descriptor or NULL.

**/
VOID *
UsbCreateDesc (
  IN  UINT8  *DescBuf,
  IN  UINTN  Len,
  IN  UINT8  Type,
  OUT UINTN  *Consumed
  )
{
  USB_DESC_HEAD  *Head;
  UINTN          DescLen;
  UINTN          CtrlLen;
  UINTN          Offset;
  VOID           *Desc;

  DescLen   = 0;
  CtrlLen   = 0;
  *Consumed = 0;

  switch (Type) {
    case USB_DESC_TYPE_DEVICE:
      DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);
      CtrlLen = sizeof (USB_DEVICE_DESC);
      break;

    case USB_DESC_TYPE_CONFIG:
      DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);
      CtrlLen = sizeof (USB_CONFIG_DESC);
      break;

    case USB_DESC_TYPE_INTERFACE:
      DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
      CtrlLen = sizeof (USB_INTERFACE_SETTING);
      break;

    case USB_DESC_TYPE_ENDPOINT:
      DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
      CtrlLen = sizeof (USB_ENDPOINT_DESC);
      break;

    default:
      ASSERT (FALSE);
      return NULL;
  }

  //
  // Total length is too small that cannot hold the single descriptor header plus data.
  //
  if (Len <= sizeof (USB_DESC_HEAD)) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));
    return NULL;
  }

  //
  // All the descriptor has a common LTV (Length, Type, Value)
  // format. Skip the descriptor that isn't of this Type
  //
  Offset = 0;
  Head   = (USB_DESC_HEAD *)DescBuf;
  while (Offset < Len - sizeof (USB_DESC_HEAD)) {
    //
    // Above condition make sure Head->Len and Head->Type are safe to access
    //
    Head = (USB_DESC_HEAD *)&DescBuf[Offset];

    if (Head->Len == 0) {
      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
      return NULL;
    }

    //
    // Make sure no overflow when adding Head->Len to Offset.
    //
    if (Head->Len > MAX_UINTN - Offset) {
      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));
      return NULL;
    }

    Offset += Head->Len;

    if (Head->Type == Type) {
      break;
    }
  }

  //
  // Head->Len is invalid resulting data beyond boundary, or
  // Descriptor cannot be found: No such type.
  //
  if (Len < Offset) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));
    return NULL;
  }

  if ((Head->Type != Type) || (Head->Len < DescLen)) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));
    return NULL;
  }

  Desc = AllocateZeroPool ((UINTN)CtrlLen);
  if (Desc == NULL) {
    return NULL;
  }

  CopyMem (Desc, Head, (UINTN)DescLen);

  *Consumed = Offset;

  return Desc;
}

/**
  Parse an interface descriptor and its endpoints.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.
  @param  Consumed              The number of raw descriptor consumed.

  @return The create interface setting or NULL if failed.

**/
USB_INTERFACE_SETTING *
UsbParseInterfaceDesc (
  IN  UINT8  *DescBuf,
  IN  UINTN  Len,
  OUT UINTN  *Consumed
  )
{
  USB_INTERFACE_SETTING  *Setting;
  USB_ENDPOINT_DESC      *Ep;
  UINTN                  Index;
  UINTN                  NumEp;
  UINTN                  Used;
  UINTN                  Offset;

  *Consumed = 0;
  Setting   = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);

  if (Setting == NULL) {
    DEBUG ((DEBUG_ERROR, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
    return NULL;
  }

  Offset = Used;

  //
  // Create an array to hold the interface's endpoints
  //
  NumEp = Setting->Desc.NumEndpoints;

  DEBUG ((
    DEBUG_INFO,
    "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
    Setting->Desc.InterfaceNumber,
    Setting->Desc.AlternateSetting,
    (UINT32)NumEp
    ));

  if (NumEp == 0) {
    goto ON_EXIT;
  }

  Setting->Endpoints = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);

  if (Setting->Endpoints == NULL) {
    goto ON_ERROR;
  }

  //
  // Create the endpoints for this interface
  //
  for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {
    Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);

    if (Ep == NULL) {
      DEBUG ((DEBUG_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32)Index));
      goto ON_ERROR;
    }

    Setting->Endpoints[Index] = Ep;
    Offset                   += Used;
  }

ON_EXIT:
  *Consumed = Offset;
  return Setting;

ON_ERROR:
  UsbFreeInterfaceDesc (Setting);
  return NULL;
}

/**
  Parse the configuration descriptor and its interfaces.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.

  @return The created configuration descriptor.

**/
USB_CONFIG_DESC *
UsbParseConfigDesc (
  IN UINT8  *DescBuf,
  IN UINTN  Len
  )
{
  USB_CONFIG_DESC        *Config;
  USB_INTERFACE_SETTING  *Setting;
  USB_INTERFACE_DESC     *Interface;
  UINTN                  Index;
  UINTN                  NumIf;
  UINTN                  Consumed;

  ASSERT (DescBuf != NULL);

  Config = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_CONFIG, &Consumed);

  if (Config == NULL) {
    return NULL;
  }

  //
  // Initialize an array of setting for the configuration's interfaces.
  //
  NumIf              = Config->Desc.NumInterfaces;
  Config->Interfaces = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);

  if (Config->Interfaces == NULL) {
    goto ON_ERROR;
  }

  DEBUG ((
    DEBUG_INFO,
    "UsbParseConfigDesc: config %d has %d interfaces\n",
    Config->Desc.ConfigurationValue,
    (UINT32)NumIf
    ));

  for (Index = 0; Index < NumIf; Index++) {
    Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));

    if (Interface == NULL) {
      goto ON_ERROR;
    }

    Config->Interfaces[Index] = Interface;
  }

  //
  // If a configuration has several interfaces, these interfaces are
  // numbered from zero to n. If a interface has several settings,
  // these settings are also number from zero to m. The interface
  // setting must be organized as |interface 0, setting 0|interface 0
  // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
  // USB2.0 spec, page 267.
  //
  DescBuf += Consumed;
  Len     -= Consumed;

  //
  // Make allowances for devices that return extra data at the
  // end of their config descriptors
  //
  while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {
    Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);

    if (Setting == NULL) {
      DEBUG ((DEBUG_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
      break;
    } else if (Setting->Desc.InterfaceNumber >= NumIf) {
      DEBUG ((DEBUG_ERROR, "UsbParseConfigDesc: malformatted interface descriptor\n"));

      UsbFreeInterfaceDesc (Setting);
      goto ON_ERROR;
    }

    //
    // Insert the descriptor to the corresponding set.
    //
    Interface = Config->Interfaces[Setting->Desc.InterfaceNumber];

    if (Interface->NumOfSetting >= USB_MAX_INTERFACE_SETTING) {
      goto ON_ERROR;
    }

    Interface->Settings[Interface->NumOfSetting] = Setting;
    Interface->NumOfSetting++;

    DescBuf += Consumed;
    Len     -= Consumed;
  }

  return Config;

ON_ERROR:
  UsbFreeConfigDesc (Config);
  return NULL;
}

/**
  USB standard control transfer support routine. This
  function is used by USB device. It is possible that
  the device's interfaces are still waiting to be
  enumerated.

  @param  UsbDev                The usb device.
  @param  Direction             The direction of data transfer.
  @param  Type                  Standard / class specific / vendor specific.
  @param  Target                The receiving target.
  @param  Request               Which request.
  @param  Value                 The wValue parameter of the request.
  @param  Index                 The wIndex parameter of the request.
  @param  Buf                   The buffer to receive data into / transmit from.
  @param  Length                The length of the buffer.

  @retval EFI_SUCCESS           The control request is executed.
  @retval EFI_DEVICE_ERROR      Failed to execute the control transfer.

**/
EFI_STATUS
UsbCtrlRequest (
  IN USB_DEVICE              *UsbDev,
  IN EFI_USB_DATA_DIRECTION  Direction,
  IN UINTN                   Type,
  IN UINTN                   Target,
  IN UINTN                   Request,
  IN UINT16                  Value,
  IN UINT16                  Index,
  IN OUT VOID                *Buf,
  IN UINTN                   Length
  )
{
  EFI_USB_DEVICE_REQUEST  DevReq;
  EFI_STATUS              Status;
  UINT32                  Result;
  UINTN                   Len;

  ASSERT ((UsbDev != NULL) && (UsbDev->Bus != NULL));

  DevReq.RequestType = USB_REQUEST_TYPE (Direction, Type, Target);
  DevReq.Request     = (UINT8)Request;
  DevReq.Value       = Value;
  DevReq.Index       = Index;
  DevReq.Length      = (UINT16)Length;

  Len    = Length;
  Status = UsbHcControlTransfer (
             UsbDev->Bus,
             UsbDev->Address,
             UsbDev->Speed,
             UsbDev->MaxPacket0,
             &DevReq,
             Direction,
             Buf,
             &Len,
             USB_GENERAL_DEVICE_REQUEST_TIMEOUT,
             &UsbDev->Translator,
             &Result
             );

  return Status;
}

/**
  Get the standard descriptors.

  @param  UsbDev                The USB device to read descriptor from.
  @param  DescType              The type of descriptor to read.
  @param  DescIndex             The index of descriptor to read.
  @param  LangId                Language ID, only used to get string, otherwise set
                                it to 0.
  @param  Buf                   The buffer to hold the descriptor read.
  @param  Length                The length of the buffer.

  @retval EFI_SUCCESS           The descriptor is read OK.
  @retval Others                Failed to retrieve the descriptor.

**/
EFI_STATUS
UsbCtrlGetDesc (
  IN  USB_DEVICE  *UsbDev,
  IN  UINTN       DescType,
  IN  UINTN       DescIndex,
  IN  UINT16      LangId,
  OUT VOID        *Buf,
  IN  UINTN       Length
  )
{
  EFI_STATUS  Status;

  Status = UsbCtrlRequest (
             UsbDev,
             EfiUsbDataIn,
             USB_REQ_TYPE_STANDARD,
             USB_TARGET_DEVICE,
             USB_REQ_GET_DESCRIPTOR,
             (UINT16)((DescType << 8) | DescIndex),
             LangId,
             Buf,
             Length
             );

  return Status;
}

/**
  Return the max packet size for endpoint zero. This function
  is the first function called to get descriptors during bus
  enumeration.

  @param  UsbDev                The usb device.

  @retval EFI_SUCCESS           The max packet size of endpoint zero is retrieved.
  @retval EFI_DEVICE_ERROR      Failed to retrieve it.

**/
EFI_STATUS
UsbGetMaxPacketSize0 (
  IN USB_DEVICE  *UsbDev
  )
{
  EFI_USB_DEVICE_DESCRIPTOR  DevDesc;
  EFI_STATUS                 Status;
  UINTN                      Index;

  //
  // Get the first 8 bytes of the device descriptor which contains
  // max packet size for endpoint 0, which is at least 8.
  //
  for (Index = 0; Index < 3; Index++) {
    Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);

    if (!EFI_ERROR (Status)) {
      if ((DevDesc.BcdUSB >= 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {
        UsbDev->MaxPacket0 = 1 << 9;
        return EFI_SUCCESS;
      }

      UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0;
      return EFI_SUCCESS;
    }

    gBS->Stall (USB_RETRY_MAX_PACK_SIZE_STALL);
  }

  return EFI_DEVICE_ERROR;
}

/**
  Get the device descriptor for the device.

  @param  UsbDev                The Usb device to retrieve descriptor from.

  @retval EFI_SUCCESS           The device descriptor is returned.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.

**/
EFI_STATUS
UsbGetDevDesc (
  IN USB_DEVICE  *UsbDev
  )
{
  USB_DEVICE_DESC  *DevDesc;
  EFI_STATUS       Status;

  DevDesc = AllocateZeroPool (sizeof (USB_DEVICE_DESC));

  if (DevDesc == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = UsbCtrlGetDesc (
             UsbDev,
             USB_DESC_TYPE_DEVICE,
             0,
             0,
             DevDesc,
             sizeof (EFI_USB_DEVICE_DESCRIPTOR)
             );

  if (EFI_ERROR (Status)) {
    gBS->FreePool (DevDesc);
  } else {
    UsbDev->DevDesc = DevDesc;
  }

  return Status;
}

/**
  Retrieve the indexed string for the language. It requires two
  steps to get a string, first to get the string's length. Then
  the string itself.

  @param  UsbDev                The usb device.
  @param  Index                 The index the string to retrieve.
  @param  LangId                Language ID.

  @return The created string descriptor or NULL.

**/
EFI_USB_STRING_DESCRIPTOR *
UsbGetOneString (
  IN     USB_DEVICE  *UsbDev,
  IN     UINT8       Index,
  IN     UINT16      LangId
  )
{
  EFI_USB_STRING_DESCRIPTOR  Desc;
  EFI_STATUS                 Status;
  UINT8                      *Buf;

  //
  // First get two bytes which contains the string length.
  //
  Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);

  //
  // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.
  //
  if (EFI_ERROR (Status) ||
      (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) ||
      (Desc.Length % 2 != 0)
      )
  {
    return NULL;
  }

  Buf = AllocateZeroPool (Desc.Length);

  if (Buf == NULL) {
    return NULL;
  }

  Status = UsbCtrlGetDesc (
             UsbDev,
             USB_DESC_TYPE_STRING,
             Index,
             LangId,
             Buf,
             Desc.Length
             );

  if (EFI_ERROR (Status)) {
    FreePool (Buf);
    return NULL;
  }

  return (EFI_USB_STRING_DESCRIPTOR *)Buf;
}

/**
  Build the language ID table for string descriptors.

  @param  UsbDev                The Usb device.

  @retval EFI_UNSUPPORTED       This device doesn't support string table.

**/
EFI_STATUS
UsbBuildLangTable (
  IN USB_DEVICE  *UsbDev
  )
{
  EFI_USB_STRING_DESCRIPTOR  *Desc;
  EFI_STATUS                 Status;
  UINTN                      Index;
  UINTN                      Max;
  UINT16                     *Point;

  //
  // The string of language ID zero returns the supported languages
  //
  Desc = UsbGetOneString (UsbDev, 0, 0);

  if (Desc == NULL) {
    return EFI_UNSUPPORTED;
  }

  if (Desc->Length < 4) {
    Status = EFI_UNSUPPORTED;
    goto ON_EXIT;
  }

  Status = EFI_SUCCESS;

  Max = (Desc->Length - 2) / 2;
  Max = MIN (Max, USB_MAX_LANG_ID);

  Point = Desc->String;
  for (Index = 0; Index < Max; Index++) {
    UsbDev->LangId[Index] = *Point;
    Point++;
  }

  UsbDev->TotalLangId = (UINT16)Max;

ON_EXIT:
  gBS->FreePool (Desc);
  return Status;
}

/**
  Retrieve the indexed configure for the device. USB device
  returns the configuration together with the interfaces for
  this configuration. Configuration descriptor is also of
  variable length.

  @param  UsbDev                The Usb interface.
  @param  Index                 The index of the configuration.

  @return The created configuration descriptor.

**/
EFI_USB_CONFIG_DESCRIPTOR *
UsbGetOneConfig (
  IN USB_DEVICE  *UsbDev,
  IN UINT8       Index
  )
{
  EFI_USB_CONFIG_DESCRIPTOR  Desc;
  EFI_STATUS                 Status;
  VOID                       *Buf;

  //
  // First get four bytes which contains the total length
  // for this configuration.
  //
  Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8);

  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "UsbGetOneConfig: failed to get descript length(%d) - %r\n",
      Desc.TotalLength,
      Status
      ));

    return NULL;
  }

  DEBUG ((DEBUG_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));

  //
  // Reject if TotalLength even cannot cover itself.
  //
  if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) {
    return NULL;
  }

  Buf = AllocateZeroPool (Desc.TotalLength);

  if (Buf == NULL) {
    return NULL;
  }

  Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength);

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "UsbGetOneConfig: failed to get full descript - %r\n", Status));

    FreePool (Buf);
    return NULL;
  }

  return Buf;
}

/**
  Build the whole array of descriptors. This function must
  be called after UsbGetMaxPacketSize0 returns the max packet
  size correctly for endpoint 0.

  @param  UsbDev                The Usb device.

  @retval EFI_SUCCESS           The descriptor table is build.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the descriptor.

**/
EFI_STATUS
UsbBuildDescTable (
  IN USB_DEVICE  *UsbDev
  )
{
  EFI_USB_CONFIG_DESCRIPTOR  *Config;
  USB_DEVICE_DESC            *DevDesc;
  USB_CONFIG_DESC            *ConfigDesc;
  UINT8                      NumConfig;
  EFI_STATUS                 Status;
  UINT8                      Index;

  //
  // Get the device descriptor, then allocate the configure
  // descriptor pointer array to hold configurations.
  //
  Status = UsbGetDevDesc (UsbDev);

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));
    return Status;
  }

  DevDesc   = UsbDev->DevDesc;
  NumConfig = DevDesc->Desc.NumConfigurations;
  if (NumConfig == 0) {
    return EFI_DEVICE_ERROR;
  }

  DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));
  if (DevDesc->Configs == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DEBUG ((DEBUG_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));

  //
  // Read each configurations, then parse them
  //
  for (Index = 0; Index < NumConfig; Index++) {
    Config = UsbGetOneConfig (UsbDev, Index);

    if (Config == NULL) {
      DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));

      //
      // If we can get the default descriptor, it is likely that the
      // device is still operational.
      //
      if (Index == 0) {
        return EFI_DEVICE_ERROR;
      }

      break;
    }

    ConfigDesc = UsbParseConfigDesc ((UINT8 *)Config, Config->TotalLength);

    FreePool (Config);

    if (ConfigDesc == NULL) {
      DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));

      //
      // If we can get the default descriptor, it is likely that the
      // device is still operational.
      //
      if (Index == 0) {
        return EFI_DEVICE_ERROR;
      }

      break;
    }

    DevDesc->Configs[Index] = ConfigDesc;
  }

  //
  // Don't return error even this function failed because
  // it is possible for the device to not support strings.
  //
  Status = UsbBuildLangTable (UsbDev);

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "UsbBuildDescTable: get language ID table - %r\n", Status));
  }

  return EFI_SUCCESS;
}

/**
  Set the device's address.

  @param  UsbDev                The device to set address to.
  @param  Address               The address to set.

  @retval EFI_SUCCESS           The device is set to the address.
  @retval Others                Failed to set the device address.

**/
EFI_STATUS
UsbSetAddress (
  IN USB_DEVICE  *UsbDev,
  IN UINT8       Address
  )
{
  EFI_STATUS  Status;

  Status = UsbCtrlRequest (
             UsbDev,
             EfiUsbNoData,
             USB_REQ_TYPE_STANDARD,
             USB_TARGET_DEVICE,
             USB_REQ_SET_ADDRESS,
             Address,
             0,
             NULL,
             0
             );

  return Status;
}

/**
  Set the device's configuration. This function changes
  the device's internal state. UsbSelectConfig changes
  the Usb bus's internal state.

  @param  UsbDev                The USB device to set configure to.
  @param  ConfigIndex           The configure index to set.

  @retval EFI_SUCCESS           The device is configured now.
  @retval Others                Failed to set the device configure.

**/
EFI_STATUS
UsbSetConfig (
  IN USB_DEVICE  *UsbDev,
  IN UINT8       ConfigIndex
  )
{
  EFI_STATUS  Status;

  Status = UsbCtrlRequest (
             UsbDev,
             EfiUsbNoData,
             USB_REQ_TYPE_STANDARD,
             USB_TARGET_DEVICE,
             USB_REQ_SET_CONFIG,
             ConfigIndex,
             0,
             NULL,
             0
             );

  return Status;
}

/**
  Usb UsbIo interface to clear the feature. This is should
  only be used by HUB which is considered a device driver
  on top of the UsbIo interface.

  @param  UsbIo                 The UsbIo interface.
  @param  Target                The target of the transfer: endpoint/device.
  @param  Feature               The feature to clear.
  @param  Index                 The wIndex parameter.

  @retval EFI_SUCCESS           The device feature is cleared.
  @retval Others                Failed to clear the feature.

**/
EFI_STATUS
UsbIoClearFeature (
  IN  EFI_USB_IO_PROTOCOL  *UsbIo,
  IN  UINTN                Target,
  IN  UINT16               Feature,
  IN  UINT16               Index
  )
{
  EFI_USB_DEVICE_REQUEST  DevReq;
  UINT32                  UsbResult;
  EFI_STATUS              Status;

  DevReq.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);
  DevReq.Request     = USB_REQ_CLEAR_FEATURE;
  DevReq.Value       = Feature;
  DevReq.Index       = Index;
  DevReq.Length      = 0;

  Status = UsbIo->UsbControlTransfer (
                    UsbIo,
                    &DevReq,
                    EfiUsbNoData,
                    USB_CLEAR_FEATURE_REQUEST_TIMEOUT,
                    NULL,
                    0,
                    &UsbResult
                    );

  return Status;
}
