]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
MdeModulePkg/UsbBus: Reject descriptor whose length is bad
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbDesc.c
index 6d68d818d2aaea5f665d757a2c48eccf6f94a68d..9fc6422ab17ca84924df5f850dc91b23800e1238 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
 \r
-Copyright (c) 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+    Manage Usb Descriptor List\r
+\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -9,31 +11,17 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-  Module Name:\r
-\r
-    UsbDesc.c\r
-\r
-  Abstract:\r
-\r
-    Manage Usb Descriptor List\r
-\r
-  Revision History\r
-\r
-\r
 **/\r
 \r
 #include "UsbBus.h"\r
 \r
 \r
 /**\r
-  Free the interface setting descriptor\r
+  Free the interface setting descriptor.\r
 \r
-  @param  Setting               The descriptor to free\r
-\r
-  @return None\r
+  @param  Setting               The descriptor to free.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 UsbFreeInterfaceDesc (\r
   IN USB_INTERFACE_SETTING  *Setting\r
@@ -50,28 +38,29 @@ UsbFreeInterfaceDesc (
       Ep = Setting->Endpoints[Index];\r
 \r
       if (Ep != NULL) {\r
-        gBS->FreePool (Ep);\r
+        FreePool (Ep);\r
       }\r
     }\r
 \r
-    gBS->FreePool (Setting->Endpoints);\r
+    //\r
+    // Only call FreePool() if NumEndpoints > 0.\r
+    //\r
+    if (Setting->Desc.NumEndpoints > 0) {\r
+      FreePool (Setting->Endpoints);\r
+    }\r
   }\r
 \r
-  gBS->FreePool (Setting);\r
+  FreePool (Setting);\r
 }\r
 \r
 \r
-\r
 /**\r
   Free a configuration descriptor with its interface\r
-  descriptors. It may be initialized partially\r
-\r
-  @param  Config                The configuration descriptor to free\r
+  descriptors. It may be initialized partially.\r
 \r
-  @return None\r
+  @param  Config                The configuration descriptor to free.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 UsbFreeConfigDesc (\r
   IN USB_CONFIG_DESC      *Config\r
@@ -101,24 +90,21 @@ UsbFreeConfigDesc (
         }\r
       }\r
 \r
-      gBS->FreePool (Interface);\r
+      FreePool (Interface);\r
     }\r
 \r
-    gBS->FreePool (Config->Interfaces);\r
+    FreePool (Config->Interfaces);\r
   }\r
 \r
-  gBS->FreePool (Config);\r
+  FreePool (Config);\r
 \r
 }\r
 \r
 \r
-\r
 /**\r
-  Free a device descriptor with its configurations\r
-\r
-  @param  DevDesc               The device descriptor\r
+  Free a device descriptor with its configurations.\r
 \r
-  @return None\r
+  @param  DevDesc               The device descriptor.\r
 \r
 **/\r
 VOID\r
@@ -135,37 +121,36 @@ UsbFreeDevDesc (
       }\r
     }\r
 \r
-    gBS->FreePool (DevDesc->Configs);\r
+    FreePool (DevDesc->Configs);\r
   }\r
 \r
-  gBS->FreePool (DevDesc);\r
+  FreePool (DevDesc);\r
 }\r
 \r
 \r
 /**\r
-  Create a descriptor\r
+  Create a descriptor.\r
 \r
-  @param  DescBuf               The buffer of raw descriptor\r
-  @param  Len                   The lenght of the raw descriptor buffer\r
-  @param  Type                  The type of descriptor to create\r
-  @param  Consumed              Number of bytes consumed\r
+  @param  DescBuf               The buffer of raw descriptor.\r
+  @param  Len                   The length of the raw descriptor buffer.\r
+  @param  Type                  The type of descriptor to create.\r
+  @param  Consumed              Number of bytes consumed.\r
 \r
-  @return Created descriptor or NULL\r
+  @return Created descriptor or NULL.\r
 \r
 **/\r
-STATIC\r
 VOID *\r
 UsbCreateDesc (\r
   IN  UINT8               *DescBuf,\r
-  IN  INTN                Len,\r
+  IN  UINTN               Len,\r
   IN  UINT8               Type,\r
-  OUT INTN                *Consumed\r
+  OUT UINTN               *Consumed\r
   )\r
 {\r
   USB_DESC_HEAD           *Head;\r
-  INTN                    DescLen;\r
-  INTN                    CtrlLen;\r
-  INTN                    Offset;\r
+  UINTN                   DescLen;\r
+  UINTN                   CtrlLen;\r
+  UINTN                   Offset;\r
   VOID                    *Desc;\r
 \r
   DescLen   = 0;\r
@@ -192,6 +177,18 @@ UsbCreateDesc (
     DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);\r
     CtrlLen = sizeof (USB_ENDPOINT_DESC);\r
     break;\r
+\r
+  default:\r
+    ASSERT (FALSE);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Total length is too small that cannot hold the single descriptor header plus data. \r
+  //\r
+  if (Len <= sizeof (USB_DESC_HEAD)) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));\r
+    return NULL;\r
   }\r
 \r
   //\r
@@ -199,56 +196,82 @@ UsbCreateDesc (
   // format. Skip the descriptor that isn't of this Type\r
   //\r
   Offset = 0;\r
-  Head   = (USB_DESC_HEAD*)DescBuf;\r
+  Head   = (USB_DESC_HEAD *)DescBuf;\r
+  while (Offset < Len - sizeof (USB_DESC_HEAD)) {\r
+    //\r
+    // Above condition make sure Head->Len and Head->Type are safe to access\r
+    //\r
+    Head = (USB_DESC_HEAD *)&DescBuf[Offset];\r
+\r
+    if (Head->Len == 0) {\r
+      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));\r
+      return NULL;\r
+    }\r
+\r
+    //\r
+    // Make sure no overflow when adding Head->Len to Offset.\r
+    //\r
+    if (Head->Len > MAX_UINTN - Offset) {\r
+      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));\r
+      return NULL;\r
+    }\r
 \r
-  while ((Offset < Len) && (Head->Type != Type)) {\r
     Offset += Head->Len;\r
-    Head    = (USB_DESC_HEAD*)(DescBuf + Offset);\r
+\r
+    if (Head->Type == Type) {\r
+      break;\r
+    }\r
   }\r
 \r
-  if ((Len <= Offset)      || (Len < Offset + DescLen) ||\r
-      (Head->Type != Type) || (Head->Len != DescLen)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor\n"));\r
-    return NULL;\r
+  //\r
+  // Head->Len is invalid resulting data beyond boundary, or\r
+  // Descriptor cannot be found: No such type.\r
+  //\r
+  if (Len < Offset) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));\r
   }\r
 \r
-  Desc = AllocateZeroPool (CtrlLen);\r
+  if ((Head->Type != Type) || (Head->Len < DescLen)) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));\r
+    return NULL;\r
+  }\r
 \r
+  Desc = AllocateZeroPool ((UINTN) CtrlLen);\r
   if (Desc == NULL) {\r
     return NULL;\r
   }\r
 \r
-  CopyMem (Desc, Head, DescLen);\r
-  *Consumed = Offset + Head->Len;\r
+  CopyMem (Desc, Head, (UINTN) DescLen);\r
+\r
+  *Consumed = Offset;\r
 \r
   return Desc;\r
 }\r
 \r
 \r
 /**\r
-  Parse an interface desciptor and its endpoints\r
+  Parse an interface descriptor and its endpoints.\r
 \r
-  @param  DescBuf               The buffer of raw descriptor\r
-  @param  Len                   The lenght of the raw descriptor buffer\r
-  @param  Consumed              The number of raw descriptor consumed\r
+  @param  DescBuf               The buffer of raw descriptor.\r
+  @param  Len                   The length of the raw descriptor buffer.\r
+  @param  Consumed              The number of raw descriptor consumed.\r
 \r
-  @return The create interface setting or NULL if failed\r
+  @return The create interface setting or NULL if failed.\r
 \r
 **/\r
-STATIC\r
 USB_INTERFACE_SETTING *\r
 UsbParseInterfaceDesc (\r
   IN  UINT8               *DescBuf,\r
-  IN  INTN                Len,\r
-  OUT INTN                *Consumed\r
+  IN  UINTN               Len,\r
+  OUT UINTN               *Consumed\r
   )\r
 {\r
   USB_INTERFACE_SETTING   *Setting;\r
   USB_ENDPOINT_DESC       *Ep;\r
   UINTN                   Index;\r
   UINTN                   NumEp;\r
-  INTN                    Used;\r
-  INTN                    Offset;\r
+  UINTN                   Used;\r
+  UINTN                   Offset;\r
 \r
   *Consumed = 0;\r
   Setting   = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);\r
@@ -261,12 +284,12 @@ UsbParseInterfaceDesc (
   Offset = Used;\r
 \r
   //\r
-  // Create an arry to hold the interface's endpoints\r
+  // Create an array to hold the interface's endpoints\r
   //\r
   NumEp  = Setting->Desc.NumEndpoints;\r
 \r
   DEBUG (( EFI_D_INFO, "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",\r
-              Setting->Desc.InterfaceNumber, Setting->Desc.AlternateSetting, NumEp));\r
+              Setting->Desc.InterfaceNumber, Setting->Desc.AlternateSetting, (UINT32)NumEp));\r
 \r
   if (NumEp == 0) {\r
     goto ON_EXIT;\r
@@ -281,11 +304,11 @@ UsbParseInterfaceDesc (
   //\r
   // Create the endpoints for this interface\r
   //\r
-  for (Index = 0; Index < NumEp; Index++) {\r
+  for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {\r
     Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);\r
 \r
     if (Ep == NULL) {\r
-      DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", Index));\r
+      DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32)Index));\r
       goto ON_ERROR;\r
     }\r
 \r
@@ -307,17 +330,16 @@ ON_ERROR:
 /**\r
   Parse the configuration descriptor and its interfaces.\r
 \r
-  @param  DescBuf               The buffer of raw descriptor\r
-  @param  Len                   The lenght of the raw descriptor buffer\r
+  @param  DescBuf               The buffer of raw descriptor.\r
+  @param  Len                   The length of the raw descriptor buffer.\r
 \r
-  @return The created configuration descriptor\r
+  @return The created configuration descriptor.\r
 \r
 **/\r
-STATIC\r
 USB_CONFIG_DESC *\r
 UsbParseConfigDesc (\r
   IN UINT8                *DescBuf,\r
-  IN INTN                 Len\r
+  IN UINTN                Len\r
   )\r
 {\r
   USB_CONFIG_DESC         *Config;\r
@@ -325,7 +347,7 @@ UsbParseConfigDesc (
   USB_INTERFACE_DESC      *Interface;\r
   UINTN                   Index;\r
   UINTN                   NumIf;\r
-  INTN                    Consumed;\r
+  UINTN                   Consumed;\r
 \r
   ASSERT (DescBuf != NULL);\r
 \r
@@ -346,7 +368,7 @@ UsbParseConfigDesc (
   }\r
 \r
   DEBUG (( EFI_D_INFO, "UsbParseConfigDesc: config %d has %d interfaces\n",\r
-                Config->Desc.ConfigurationValue, NumIf));\r
+                Config->Desc.ConfigurationValue, (UINT32)NumIf));\r
 \r
   for (Index = 0; Index < NumIf; Index++) {\r
     Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));\r
@@ -369,12 +391,16 @@ UsbParseConfigDesc (
   DescBuf += Consumed;\r
   Len     -= Consumed;\r
 \r
-  while (Len > 0) {\r
+  //\r
+  // Make allowances for devices that return extra data at the\r
+  // end of their config descriptors\r
+  //\r
+  while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {\r
     Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);\r
 \r
-    if ((Setting == NULL)) {\r
-      DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: failed to parse interface setting\n"));\r
-      goto ON_ERROR;\r
+    if (Setting == NULL) {\r
+      DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));\r
+      break;\r
 \r
     } else if (Setting->Desc.InterfaceNumber >= NumIf) {\r
       DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: mal-formated interface descriptor\n"));\r
@@ -407,25 +433,24 @@ ON_ERROR:
 }\r
 \r
 \r
-\r
 /**\r
   USB standard control transfer support routine. This\r
   function is used by USB device. It is possible that\r
   the device's interfaces are still waiting to be\r
   enumerated.\r
 \r
-  @param  UsbDev                The usb device\r
-  @param  Direction             The direction of data transfer\r
-  @param  Type                  Standard / class specific / vendor specific\r
-  @param  Target                The receiving target\r
-  @param  Request               Which request\r
-  @param  Value                 The wValue parameter of the request\r
-  @param  Index                 The wIndex parameter of the request\r
-  @param  Buf                   The buffer to receive data into / transmit from\r
-  @param  Length                The length of the buffer\r
+  @param  UsbDev                The usb device.\r
+  @param  Direction             The direction of data transfer.\r
+  @param  Type                  Standard / class specific / vendor specific.\r
+  @param  Target                The receiving target.\r
+  @param  Request               Which request.\r
+  @param  Value                 The wValue parameter of the request.\r
+  @param  Index                 The wIndex parameter of the request.\r
+  @param  Buf                   The buffer to receive data into / transmit from.\r
+  @param  Length                The length of the buffer.\r
 \r
-  @retval EFI_SUCCESS           The control request is executed\r
-  @retval EFI_DEVICE_ERROR      Failed to execute the control transfer\r
+  @retval EFI_SUCCESS           The control request is executed.\r
+  @retval EFI_DEVICE_ERROR      Failed to execute the control transfer.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -464,7 +489,7 @@ UsbCtrlRequest (
              Direction,\r
              Buf,\r
              &Len,\r
-             50 * USB_STALL_1_MS,\r
+             USB_GENERAL_DEVICE_REQUEST_TIMEOUT,\r
              &UsbDev->Translator,\r
              &Result\r
              );\r
@@ -473,23 +498,21 @@ UsbCtrlRequest (
 }\r
 \r
 \r
-\r
 /**\r
   Get the standard descriptors.\r
 \r
-  @param  UsbDev                The USB device to read descriptor from\r
-  @param  DescType              The type of descriptor to read\r
-  @param  DescIndex             The index of descriptor to read\r
+  @param  UsbDev                The USB device to read descriptor from.\r
+  @param  DescType              The type of descriptor to read.\r
+  @param  DescIndex             The index of descriptor to read.\r
   @param  LangId                Language ID, only used to get string, otherwise set\r
-                                it to 0\r
-  @param  Buf                   The buffer to hold the descriptor read\r
-  @param  Length                The length of the buffer\r
+                                it to 0.\r
+  @param  Buf                   The buffer to hold the descriptor read.\r
+  @param  Length                The length of the buffer.\r
 \r
-  @retval EFI_SUCCESS           The descriptor is read OK\r
-  @retval Others                Failed to retrieve the descriptor\r
+  @retval EFI_SUCCESS           The descriptor is read OK.\r
+  @retval Others                Failed to retrieve the descriptor.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 UsbCtrlGetDesc (\r
   IN  USB_DEVICE          *UsbDev,\r
@@ -518,16 +541,15 @@ UsbCtrlGetDesc (
 }\r
 \r
 \r
-\r
 /**\r
   Return the max packet size for endpoint zero. This function\r
   is the first function called to get descriptors during bus\r
   enumeration.\r
 \r
-  @param  UsbDev                The usb device\r
+  @param  UsbDev                The usb device.\r
 \r
-  @retval EFI_SUCCESS           The max packet size of endpoint zero is retrieved\r
-  @retval EFI_DEVICE_ERROR      Failed to retrieve it\r
+  @retval EFI_SUCCESS           The max packet size of endpoint zero is retrieved.\r
+  @retval EFI_DEVICE_ERROR      Failed to retrieve it.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -544,34 +566,34 @@ UsbGetMaxPacketSize0 (
   // Get the first 8 bytes of the device descriptor which contains\r
   // max packet size for endpoint 0, which is at least 8.\r
   //\r
-  UsbDev->MaxPacket0 = 8;\r
-\r
   for (Index = 0; Index < 3; Index++) {\r
     Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);\r
 \r
     if (!EFI_ERROR (Status)) {\r
+      if ((DevDesc.BcdUSB >= 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {\r
+        UsbDev->MaxPacket0 = 1 << 9;\r
+        return EFI_SUCCESS;\r
+      }\r
       UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0;\r
       return EFI_SUCCESS;\r
     }\r
 \r
-    gBS->Stall (100 * USB_STALL_1_MS);\r
+    gBS->Stall (USB_RETRY_MAX_PACK_SIZE_STALL);\r
   }\r
 \r
   return EFI_DEVICE_ERROR;\r
 }\r
 \r
 \r
-\r
 /**\r
   Get the device descriptor for the device.\r
 \r
-  @param  UsbDev                The Usb device to retrieve descriptor from\r
+  @param  UsbDev                The Usb device to retrieve descriptor from.\r
 \r
-  @retval EFI_SUCCESS           The device descriptor is returned\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory\r
+  @retval EFI_SUCCESS           The device descriptor is returned.\r
+  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 UsbGetDevDesc (\r
   IN USB_DEVICE           *UsbDev\r
@@ -605,17 +627,16 @@ UsbGetDevDesc (
 }\r
 \r
 \r
-\r
 /**\r
   Retrieve the indexed string for the language. It requires two\r
   steps to get a string, first to get the string's length. Then\r
   the string itself.\r
 \r
-  @param  UsbDev                The usb device\r
-  @param  Index                 The index the string to retrieve\r
-  @param  LangId                Language ID\r
+  @param  UsbDev                The usb device.\r
+  @param  Index                 The index the string to retrieve.\r
+  @param  LangId                Language ID.\r
 \r
-  @return The created string descriptor or NULL\r
+  @return The created string descriptor or NULL.\r
 \r
 **/\r
 EFI_USB_STRING_DESCRIPTOR *\r
@@ -654,7 +675,7 @@ UsbGetOneString (
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (Buf);\r
+    FreePool (Buf);\r
     return NULL;\r
   }\r
 \r
@@ -662,16 +683,14 @@ UsbGetOneString (
 }\r
 \r
 \r
-\r
 /**\r
-  Build the language ID table for string descriptors\r
+  Build the language ID table for string descriptors.\r
 \r
-  @param  UsbDev                The Usb device\r
+  @param  UsbDev                The Usb device.\r
 \r
-  @retval EFI_UNSUPPORTED       This device doesn't support string table\r
+  @retval EFI_UNSUPPORTED       This device doesn't support string table.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 UsbBuildLangTable (\r
   IN USB_DEVICE           *UsbDev\r
@@ -700,7 +719,7 @@ UsbBuildLangTable (
   Status = EFI_SUCCESS;\r
 \r
   Max   = (Desc->Length - 2) / 2;\r
-  Max   = (Max < USB_MAX_LANG_ID ? Max : USB_MAX_LANG_ID);\r
+  Max   = MIN(Max, USB_MAX_LANG_ID);\r
 \r
   Point = Desc->String;\r
   for (Index = 0; Index < Max; Index++) {\r
@@ -716,20 +735,18 @@ ON_EXIT:
 }\r
 \r
 \r
-\r
 /**\r
   Retrieve the indexed configure for the device. USB device\r
-  returns the configuration togetther with the interfaces for\r
+  returns the configuration together with the interfaces for\r
   this configuration. Configuration descriptor is also of\r
-  variable length\r
+  variable length.\r
 \r
-  @param  UsbDev                The Usb interface\r
-  @param  Index                 The index of the configuration\r
+  @param  UsbDev                The Usb interface.\r
+  @param  Index                 The index of the configuration.\r
 \r
-  @return The created configuration descriptor\r
+  @return The created configuration descriptor.\r
 \r
 **/\r
-STATIC\r
 EFI_USB_CONFIG_DESCRIPTOR *\r
 UsbGetOneConfig (\r
   IN USB_DEVICE           *UsbDev,\r
@@ -748,13 +765,20 @@ UsbGetOneConfig (
 \r
   if (EFI_ERROR (Status)) {\r
     DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get descript length(%d) %r\n",\r
-                Status, Desc.TotalLength));\r
+                Desc.TotalLength, Status));\r
 \r
     return NULL;\r
   }\r
 \r
   DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));\r
 \r
+  //\r
+  // Reject if TotalLength even cannot cover itself.\r
+  //\r
+  if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) {\r
+    return NULL;\r
+  }\r
+\r
   Buf = AllocateZeroPool (Desc.TotalLength);\r
 \r
   if (Buf == NULL) {\r
@@ -766,7 +790,7 @@ UsbGetOneConfig (
   if (EFI_ERROR (Status)) {\r
     DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status));\r
 \r
-    gBS->FreePool (Buf);\r
+    FreePool (Buf);\r
     return NULL;\r
   }\r
 \r
@@ -774,16 +798,15 @@ UsbGetOneConfig (
 }\r
 \r
 \r
-\r
 /**\r
   Build the whole array of descriptors. This function must\r
   be called after UsbGetMaxPacketSize0 returns the max packet\r
   size correctly for endpoint 0.\r
 \r
-  @param  UsbDev                The Usb device\r
+  @param  UsbDev                The Usb device.\r
 \r
-  @retval EFI_SUCCESS           The descriptor table is build\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the descriptor\r
+  @retval EFI_SUCCESS           The descriptor table is build.\r
+  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the descriptor.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -809,10 +832,13 @@ UsbBuildDescTable (
     return Status;\r
   }\r
 \r
-  DevDesc          = UsbDev->DevDesc;\r
-  NumConfig        = DevDesc->Desc.NumConfigurations;\r
-  DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));\r
+  DevDesc   = UsbDev->DevDesc;\r
+  NumConfig = DevDesc->Desc.NumConfigurations;\r
+  if (NumConfig == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
+  DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));\r
   if (DevDesc->Configs == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -841,7 +867,7 @@ UsbBuildDescTable (
 \r
     ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);\r
 \r
-    gBS->FreePool (Config);\r
+    FreePool (Config);\r
 \r
     if (ConfigDesc == NULL) {\r
       DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));\r
@@ -867,7 +893,7 @@ UsbBuildDescTable (
   Status = UsbBuildLangTable (UsbDev);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: get language ID table %r\n", Status));\r
+    DEBUG (( EFI_D_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -877,11 +903,11 @@ UsbBuildDescTable (
 /**\r
   Set the device's address.\r
 \r
-  @param  UsbDev                The device to set address to\r
-  @param  Address               The address to set\r
+  @param  UsbDev                The device to set address to.\r
+  @param  Address               The address to set.\r
 \r
-  @retval EFI_SUCCESS           The device is set to the address\r
-  @retval Others                Failed to set the device address\r
+  @retval EFI_SUCCESS           The device is set to the address.\r
+  @retval Others                Failed to set the device address.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -913,11 +939,11 @@ UsbSetAddress (
   the device's internal state. UsbSelectConfig changes\r
   the Usb bus's internal state.\r
 \r
-  @param  UsbDev                The USB device to set configure to\r
-  @param  ConfigIndex           The configure index to set\r
+  @param  UsbDev                The USB device to set configure to.\r
+  @param  ConfigIndex           The configure index to set.\r
 \r
-  @retval EFI_SUCCESS           The device is configured now\r
-  @retval Others                Failed to set the device configure\r
+  @retval EFI_SUCCESS           The device is configured now.\r
+  @retval Others                Failed to set the device configure.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -944,19 +970,18 @@ UsbSetConfig (
 }\r
 \r
 \r
-\r
 /**\r
   Usb UsbIo interface to clear the feature. This is should\r
   only be used by HUB which is considered a device driver\r
   on top of the UsbIo interface.\r
 \r
-  @param  UsbIo                 The UsbIo interface\r
-  @param  Target                The target of the transfer: endpoint/device\r
-  @param  Feature               The feature to clear\r
-  @param  Index                 The wIndex parameter\r
+  @param  UsbIo                 The UsbIo interface.\r
+  @param  Target                The target of the transfer: endpoint/device.\r
+  @param  Feature               The feature to clear.\r
+  @param  Index                 The wIndex parameter.\r
 \r
-  @retval EFI_SUCCESS           The device feature is cleared\r
-  @retval Others                Failed to clear the feature\r
+  @retval EFI_SUCCESS           The device feature is cleared.\r
+  @retval Others                Failed to clear the feature.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -981,7 +1006,7 @@ UsbIoClearFeature (
                     UsbIo,\r
                     &DevReq,\r
                     EfiUsbNoData,\r
-                    10 * USB_STALL_1_MS,\r
+                    USB_CLEAR_FEATURE_REQUEST_TIMEOUT,\r
                     NULL,\r
                     0,\r
                     &UsbResult\r