]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbDesc.c
index 6d68d818d2aaea5f665d757a2c48eccf6f94a68d..a620a670748cbe34edeec5fe99c36aad75950995 100644 (file)
@@ -1,46 +1,27 @@
 /** @file\r
 \r
-Copyright (c) 2007, Intel Corporation\r
-All rights reserved. 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
-\r
-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
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\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
   )\r
 {\r
-  USB_ENDPOINT_DESC       *Ep;\r
-  UINTN                   Index;\r
+  USB_ENDPOINT_DESC  *Ep;\r
+  UINTN              Index;\r
 \r
   if (Setting->Endpoints != NULL) {\r
     //\r
@@ -50,36 +31,36 @@ 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
+  descriptors. It may be initialized partially.\r
 \r
-  @param  Config                The configuration descriptor to free\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
+  IN USB_CONFIG_DESC  *Config\r
   )\r
 {\r
-  USB_INTERFACE_DESC      *Interface;\r
-  UINTN                   Index;\r
-  UINTN                   SetIndex;\r
+  USB_INTERFACE_DESC  *Interface;\r
+  UINTN               Index;\r
+  UINTN               SetIndex;\r
 \r
   if (Config->Interfaces != NULL) {\r
     //\r
@@ -101,32 +82,27 @@ 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
-\r
+  FreePool (Config);\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
 UsbFreeDevDesc (\r
-  IN USB_DEVICE_DESC      *DevDesc\r
+  IN USB_DEVICE_DESC  *DevDesc\r
   )\r
 {\r
-  UINTN                   Index;\r
+  UINTN  Index;\r
 \r
   if (DevDesc->Configs != NULL) {\r
     for (Index = 0; Index < DevDesc->Desc.NumConfigurations; Index++) {\r
@@ -135,63 +111,73 @@ 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  UINT8               Type,\r
-  OUT INTN                *Consumed\r
+  IN  UINT8  *DescBuf,\r
+  IN  UINTN  Len,\r
+  IN  UINT8  Type,\r
+  OUT UINTN  *Consumed\r
   )\r
 {\r
-  USB_DESC_HEAD           *Head;\r
-  INTN                    DescLen;\r
-  INTN                    CtrlLen;\r
-  INTN                    Offset;\r
-  VOID                    *Desc;\r
+  USB_DESC_HEAD  *Head;\r
+  UINTN          DescLen;\r
+  UINTN          CtrlLen;\r
+  UINTN          Offset;\r
+  VOID           *Desc;\r
 \r
   DescLen   = 0;\r
   CtrlLen   = 0;\r
   *Consumed = 0;\r
 \r
   switch (Type) {\r
-  case USB_DESC_TYPE_DEVICE:\r
-    DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);\r
-    CtrlLen = sizeof (USB_DEVICE_DESC);\r
-    break;\r
+    case USB_DESC_TYPE_DEVICE:\r
+      DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);\r
+      CtrlLen = sizeof (USB_DEVICE_DESC);\r
+      break;\r
+\r
+    case USB_DESC_TYPE_CONFIG:\r
+      DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);\r
+      CtrlLen = sizeof (USB_CONFIG_DESC);\r
+      break;\r
 \r
-  case USB_DESC_TYPE_CONFIG:\r
-    DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);\r
-    CtrlLen = sizeof (USB_CONFIG_DESC);\r
-    break;\r
+    case USB_DESC_TYPE_INTERFACE:\r
+      DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);\r
+      CtrlLen = sizeof (USB_INTERFACE_SETTING);\r
+      break;\r
+\r
+    case USB_DESC_TYPE_ENDPOINT:\r
+      DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);\r
+      CtrlLen = sizeof (USB_ENDPOINT_DESC);\r
+      break;\r
 \r
-  case USB_DESC_TYPE_INTERFACE:\r
-    DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);\r
-    CtrlLen = sizeof (USB_INTERFACE_SETTING);\r
-    break;\r
+    default:\r
+      ASSERT (FALSE);\r
+      return NULL;\r
+  }\r
 \r
-  case USB_DESC_TYPE_ENDPOINT:\r
-    DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);\r
-    CtrlLen = sizeof (USB_ENDPOINT_DESC);\r
-    break;\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,80 +185,111 @@ 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
+  //\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
     return NULL;\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  UINT8  *DescBuf,\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
+  USB_INTERFACE_SETTING  *Setting;\r
+  USB_ENDPOINT_DESC      *Ep;\r
+  UINTN                  Index;\r
+  UINTN                  NumEp;\r
+  UINTN                  Used;\r
+  UINTN                  Offset;\r
 \r
   *Consumed = 0;\r
   Setting   = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);\r
 \r
   if (Setting == NULL) {\r
-    DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));\r
+    DEBUG ((DEBUG_ERROR, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));\r
     return NULL;\r
   }\r
 \r
   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
+  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
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",\r
+    Setting->Desc.InterfaceNumber,\r
+    Setting->Desc.AlternateSetting,\r
+    (UINT32)NumEp\r
+    ));\r
 \r
   if (NumEp == 0) {\r
     goto ON_EXIT;\r
   }\r
 \r
-  Setting->Endpoints  = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);\r
+  Setting->Endpoints = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);\r
 \r
   if (Setting->Endpoints == NULL) {\r
     goto ON_ERROR;\r
@@ -281,19 +298,18 @@ 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 ((DEBUG_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32)Index));\r
       goto ON_ERROR;\r
     }\r
 \r
-    Setting->Endpoints[Index]  = Ep;\r
-    Offset                    += Used;\r
+    Setting->Endpoints[Index] = Ep;\r
+    Offset                   += Used;\r
   }\r
 \r
-\r
 ON_EXIT:\r
   *Consumed = Offset;\r
   return Setting;\r
@@ -303,29 +319,27 @@ ON_ERROR:
   return NULL;\r
 }\r
 \r
-\r
 /**\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 UINT8  *DescBuf,\r
+  IN UINTN  Len\r
   )\r
 {\r
-  USB_CONFIG_DESC         *Config;\r
-  USB_INTERFACE_SETTING   *Setting;\r
-  USB_INTERFACE_DESC      *Interface;\r
-  UINTN                   Index;\r
-  UINTN                   NumIf;\r
-  INTN                    Consumed;\r
+  USB_CONFIG_DESC        *Config;\r
+  USB_INTERFACE_SETTING  *Setting;\r
+  USB_INTERFACE_DESC     *Interface;\r
+  UINTN                  Index;\r
+  UINTN                  NumIf;\r
+  UINTN                  Consumed;\r
 \r
   ASSERT (DescBuf != NULL);\r
 \r
@@ -338,15 +352,19 @@ UsbParseConfigDesc (
   //\r
   // Initialize an array of setting for the configuration's interfaces.\r
   //\r
-  NumIf               = Config->Desc.NumInterfaces;\r
-  Config->Interfaces  = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);\r
+  NumIf              = Config->Desc.NumInterfaces;\r
+  Config->Interfaces = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);\r
 \r
   if (Config->Interfaces == NULL) {\r
     goto ON_ERROR;\r
   }\r
 \r
-  DEBUG (( EFI_D_INFO, "UsbParseConfigDesc: config %d has %d interfaces\n",\r
-                Config->Desc.ConfigurationValue, NumIf));\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "UsbParseConfigDesc: config %d has %d interfaces\n",\r
+    Config->Desc.ConfigurationValue,\r
+    (UINT32)NumIf\r
+    ));\r
 \r
   for (Index = 0; Index < NumIf; Index++) {\r
     Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));\r
@@ -369,15 +387,18 @@ 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
-\r
+    if (Setting == NULL) {\r
+      DEBUG ((DEBUG_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));\r
+      break;\r
     } else if (Setting->Desc.InterfaceNumber >= NumIf) {\r
-      DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: mal-formated interface descriptor\n"));\r
+      DEBUG ((DEBUG_ERROR, "UsbParseConfigDesc: malformatted interface descriptor\n"));\r
 \r
       UsbFreeInterfaceDesc (Setting);\r
       goto ON_ERROR;\r
@@ -406,39 +427,37 @@ ON_ERROR:
   return NULL;\r
 }\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
 UsbCtrlRequest (\r
-  IN USB_DEVICE             *UsbDev,\r
-  IN EFI_USB_DATA_DIRECTION Direction,\r
-  IN UINTN                  Type,\r
-  IN UINTN                  Target,\r
-  IN UINTN                  Request,\r
-  IN UINT16                 Value,\r
-  IN UINT16                 Index,\r
-  IN OUT VOID               *Buf,\r
-  IN UINTN                  Length\r
+  IN USB_DEVICE              *UsbDev,\r
+  IN EFI_USB_DATA_DIRECTION  Direction,\r
+  IN UINTN                   Type,\r
+  IN UINTN                   Target,\r
+  IN UINTN                   Request,\r
+  IN UINT16                  Value,\r
+  IN UINT16                  Index,\r
+  IN OUT VOID                *Buf,\r
+  IN UINTN                   Length\r
   )\r
 {\r
   EFI_USB_DEVICE_REQUEST  DevReq;\r
@@ -448,13 +467,13 @@ UsbCtrlRequest (
 \r
   ASSERT ((UsbDev != NULL) && (UsbDev->Bus != NULL));\r
 \r
-  DevReq.RequestType  = USB_REQUEST_TYPE (Direction, Type, Target);\r
-  DevReq.Request      = (UINT8) Request;\r
-  DevReq.Value        = Value;\r
-  DevReq.Index        = Index;\r
-  DevReq.Length       = (UINT16) Length;\r
+  DevReq.RequestType = USB_REQUEST_TYPE (Direction, Type, Target);\r
+  DevReq.Request     = (UINT8)Request;\r
+  DevReq.Value       = Value;\r
+  DevReq.Index       = Index;\r
+  DevReq.Length      = (UINT16)Length;\r
 \r
-  Len                 = Length;\r
+  Len    = Length;\r
   Status = UsbHcControlTransfer (\r
              UsbDev->Bus,\r
              UsbDev->Address,\r
@@ -464,7 +483,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
@@ -472,35 +491,32 @@ UsbCtrlRequest (
   return Status;\r
 }\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
-  IN  UINTN               DescType,\r
-  IN  UINTN               DescIndex,\r
-  IN  UINT16              LangId,\r
-  OUT VOID                *Buf,\r
-  IN  UINTN               Length\r
+  IN  USB_DEVICE  *UsbDev,\r
+  IN  UINTN       DescType,\r
+  IN  UINTN       DescIndex,\r
+  IN  UINT16      LangId,\r
+  OUT VOID        *Buf,\r
+  IN  UINTN       Length\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   Status = UsbCtrlRequest (\r
              UsbDev,\r
@@ -508,7 +524,7 @@ UsbCtrlGetDesc (
              USB_REQ_TYPE_STANDARD,\r
              USB_TARGET_DEVICE,\r
              USB_REQ_GET_DESCRIPTOR,\r
-             (UINT16) ((DescType << 8) | DescIndex),\r
+             (UINT16)((DescType << 8) | DescIndex),\r
              LangId,\r
              Buf,\r
              Length\r
@@ -517,68 +533,65 @@ UsbCtrlGetDesc (
   return Status;\r
 }\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
 UsbGetMaxPacketSize0 (\r
-  IN USB_DEVICE           *UsbDev\r
+  IN USB_DEVICE  *UsbDev\r
   )\r
 {\r
-  EFI_USB_DEVICE_DESCRIPTOR DevDesc;\r
-  EFI_STATUS                Status;\r
-  UINTN                     Index;\r
-\r
+  EFI_USB_DEVICE_DESCRIPTOR  DevDesc;\r
+  EFI_STATUS                 Status;\r
+  UINTN                      Index;\r
 \r
   //\r
   // 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
+\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
+  IN USB_DEVICE  *UsbDev\r
   )\r
 {\r
-  USB_DEVICE_DESC         *DevDesc;\r
-  EFI_STATUS              Status;\r
+  USB_DEVICE_DESC  *DevDesc;\r
+  EFI_STATUS       Status;\r
 \r
   DevDesc = AllocateZeroPool (sizeof (USB_DEVICE_DESC));\r
 \r
@@ -586,14 +599,14 @@ UsbGetDevDesc (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Status  = UsbCtrlGetDesc (\r
-              UsbDev,\r
-              USB_DESC_TYPE_DEVICE,\r
-              0,\r
-              0,\r
-              DevDesc,\r
-              sizeof (EFI_USB_DEVICE_DESCRIPTOR)\r
-              );\r
+  Status = UsbCtrlGetDesc (\r
+             UsbDev,\r
+             USB_DESC_TYPE_DEVICE,\r
+             0,\r
+             0,\r
+             DevDesc,\r
+             sizeof (EFI_USB_DEVICE_DESCRIPTOR)\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     gBS->FreePool (DevDesc);\r
@@ -604,37 +617,42 @@ UsbGetDevDesc (
   return Status;\r
 }\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
 UsbGetOneString (\r
-  IN     USB_DEVICE       *UsbDev,\r
-  IN     UINT8            Index,\r
-  IN     UINT16           LangId\r
+  IN     USB_DEVICE  *UsbDev,\r
+  IN     UINT8       Index,\r
+  IN     UINT16      LangId\r
   )\r
 {\r
-  EFI_USB_STRING_DESCRIPTOR Desc;\r
-  EFI_STATUS                Status;\r
-  UINT8                     *Buf;\r
+  EFI_USB_STRING_DESCRIPTOR  Desc;\r
+  EFI_STATUS                 Status;\r
+  UINT8                      *Buf;\r
 \r
   //\r
   // First get two bytes which contains the string length.\r
   //\r
   Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);\r
 \r
-  if (EFI_ERROR (Status)) {\r
+  //\r
+  // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.\r
+  //\r
+  if (EFI_ERROR (Status) ||\r
+      (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) ||\r
+      (Desc.Length % 2 != 0)\r
+      )\r
+  {\r
     return NULL;\r
   }\r
 \r
@@ -654,34 +672,31 @@ UsbGetOneString (
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (Buf);\r
+    FreePool (Buf);\r
     return NULL;\r
   }\r
 \r
-  return (EFI_USB_STRING_DESCRIPTOR *) Buf;\r
+  return (EFI_USB_STRING_DESCRIPTOR *)Buf;\r
 }\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
+  IN USB_DEVICE  *UsbDev\r
   )\r
 {\r
-  EFI_USB_STRING_DESCRIPTOR *Desc;\r
-  EFI_STATUS                Status;\r
-  UINTN                     Index;\r
-  UINTN                     Max;\r
-  UINT16                    *Point;\r
+  EFI_USB_STRING_DESCRIPTOR  *Desc;\r
+  EFI_STATUS                 Status;\r
+  UINTN                      Index;\r
+  UINTN                      Max;\r
+  UINT16                     *Point;\r
 \r
   //\r
   // The string of language ID zero returns the supported languages\r
@@ -699,8 +714,8 @@ UsbBuildLangTable (
 \r
   Status = EFI_SUCCESS;\r
 \r
-  Max   = (Desc->Length - 2) / 2;\r
-  Max   = (Max < USB_MAX_LANG_ID ? Max : USB_MAX_LANG_ID);\r
+  Max = (Desc->Length - 2) / 2;\r
+  Max = MIN (Max, USB_MAX_LANG_ID);\r
 \r
   Point = Desc->String;\r
   for (Index = 0; Index < Max; Index++) {\r
@@ -715,30 +730,27 @@ ON_EXIT:
   return Status;\r
 }\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
-  IN UINT8                Index\r
+  IN USB_DEVICE  *UsbDev,\r
+  IN UINT8       Index\r
   )\r
 {\r
-  EFI_USB_CONFIG_DESCRIPTOR Desc;\r
-  EFI_STATUS                Status;\r
-  VOID                      *Buf;\r
+  EFI_USB_CONFIG_DESCRIPTOR  Desc;\r
+  EFI_STATUS                 Status;\r
+  VOID                       *Buf;\r
 \r
   //\r
   // First get four bytes which contains the total length\r
@@ -747,13 +759,24 @@ UsbGetOneConfig (
   Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get descript length(%d) %r\n",\r
-                Status, Desc.TotalLength));\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "UsbGetOneConfig: failed to get descript length(%d) %r\n",\r
+      Desc.TotalLength,\r
+      Status\r
+      ));\r
 \r
     return NULL;\r
   }\r
 \r
-  DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));\r
+  DEBUG ((DEBUG_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
@@ -764,39 +787,37 @@ UsbGetOneConfig (
   Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status));\r
 \r
-    gBS->FreePool (Buf);\r
+    FreePool (Buf);\r
     return NULL;\r
   }\r
 \r
   return Buf;\r
 }\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
 UsbBuildDescTable (\r
-  IN USB_DEVICE           *UsbDev\r
+  IN USB_DEVICE  *UsbDev\r
   )\r
 {\r
-  EFI_USB_CONFIG_DESCRIPTOR *Config;\r
-  USB_DEVICE_DESC           *DevDesc;\r
-  USB_CONFIG_DESC           *ConfigDesc;\r
-  UINT8                     NumConfig;\r
-  EFI_STATUS                Status;\r
-  UINT8                     Index;\r
+  EFI_USB_CONFIG_DESCRIPTOR  *Config;\r
+  USB_DEVICE_DESC            *DevDesc;\r
+  USB_CONFIG_DESC            *ConfigDesc;\r
+  UINT8                      NumConfig;\r
+  EFI_STATUS                 Status;\r
+  UINT8                      Index;\r
 \r
   //\r
   // Get the device descriptor, then allocate the configure\r
@@ -805,19 +826,22 @@ UsbBuildDescTable (
   Status = UsbGetDevDesc (UsbDev);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));\r
+    DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));\r
     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
 \r
-  DEBUG (( EFI_D_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));\r
+  DEBUG ((DEBUG_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));\r
 \r
   //\r
   // Read each configurations, then parse them\r
@@ -826,7 +850,7 @@ UsbBuildDescTable (
     Config = UsbGetOneConfig (UsbDev, Index);\r
 \r
     if (Config == NULL) {\r
-      DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));\r
+      DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));\r
 \r
       //\r
       // If we can get the default descriptor, it is likely that the\r
@@ -839,12 +863,12 @@ UsbBuildDescTable (
       break;\r
     }\r
 \r
-    ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);\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
+      DEBUG ((DEBUG_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));\r
 \r
       //\r
       // If we can get the default descriptor, it is likely that the\r
@@ -867,30 +891,29 @@ 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 ((DEBUG_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\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
 UsbSetAddress (\r
-  IN USB_DEVICE           *UsbDev,\r
-  IN UINT8                Address\r
+  IN USB_DEVICE  *UsbDev,\r
+  IN UINT8       Address\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   Status = UsbCtrlRequest (\r
              UsbDev,\r
@@ -907,26 +930,25 @@ UsbSetAddress (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Set the device's configuration. This function changes\r
   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
 UsbSetConfig (\r
-  IN USB_DEVICE           *UsbDev,\r
-  IN UINT8                ConfigIndex\r
+  IN USB_DEVICE  *UsbDev,\r
+  IN UINT8       ConfigIndex\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   Status = UsbCtrlRequest (\r
              UsbDev,\r
@@ -938,50 +960,48 @@ UsbSetConfig (
              0,\r
              NULL,\r
              0\r
-            );\r
+             );\r
 \r
   return Status;\r
 }\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
 UsbIoClearFeature (\r
-  IN  EFI_USB_IO_PROTOCOL *UsbIo,\r
-  IN  UINTN               Target,\r
-  IN  UINT16              Feature,\r
-  IN  UINT16              Index\r
+  IN  EFI_USB_IO_PROTOCOL  *UsbIo,\r
+  IN  UINTN                Target,\r
+  IN  UINT16               Feature,\r
+  IN  UINT16               Index\r
   )\r
 {\r
   EFI_USB_DEVICE_REQUEST  DevReq;\r
   UINT32                  UsbResult;\r
   EFI_STATUS              Status;\r
 \r
-  DevReq.RequestType  = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);\r
-  DevReq.Request      = USB_REQ_CLEAR_FEATURE;\r
-  DevReq.Value        = Feature;\r
-  DevReq.Index        = Index;\r
-  DevReq.Length       = 0;\r
+  DevReq.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);\r
+  DevReq.Request     = USB_REQ_CLEAR_FEATURE;\r
+  DevReq.Value       = Feature;\r
+  DevReq.Index       = Index;\r
+  DevReq.Length      = 0;\r
 \r
   Status = UsbIo->UsbControlTransfer (\r
                     UsbIo,\r
                     &DevReq,\r
                     EfiUsbNoData,\r
-                    10 * USB_STALL_1_MS,\r
+                    USB_CLEAR_FEATURE_REQUEST_TIMEOUT,\r
                     NULL,\r
                     0,\r
                     &UsbResult\r