]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbUtility.c
index cd3e72eeebec12f986fc46bc3dc7d3703ac8db8d..8559992d27430335f6c23551be3457254d65a0aa 100644 (file)
@@ -1,24 +1,9 @@
 /** @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
-    UsbUtility.c\r
-\r
-  Abstract:\r
-\r
-    Wrapper function for usb host controller interface\r
-\r
-  Revision History\r
+    Wrapper function for usb host controller interface.\r
 \r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -30,13 +15,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 // Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices\r
 // are wanted Usb devices\r
 //\r
-STATIC USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {\r
+USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {\r
   {\r
     {\r
       MESSAGING_DEVICE_PATH,\r
       MSG_USB_CLASS_DP,\r
-      (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),\r
-      (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)\r
+      {\r
+        (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)\r
+      }\r
     },\r
     0xffff, // VendorId\r
     0xffff, // ProductId\r
@@ -48,21 +35,23 @@ STATIC USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {
   {\r
     END_DEVICE_PATH_TYPE,\r
     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-    END_DEVICE_PATH_LENGTH,\r
-    0\r
+    {\r
+      END_DEVICE_PATH_LENGTH,\r
+      0\r
+    }\r
   }\r
 };\r
 \r
 \r
 /**\r
-  Get the capability of the host controller\r
+  Get the capability of the host controller.\r
 \r
-  @param  UsbBus           The usb driver\r
-  @param  MaxSpeed         The maximum speed this host controller supports\r
-  @param  NumOfPort        The number of the root hub port\r
-  @param  Is64BitCapable   Whether this controller support 64 bit addressing\r
+  @param  UsbBus           The usb driver.\r
+  @param  MaxSpeed         The maximum speed this host controller supports.\r
+  @param  NumOfPort        The number of the root hub port.\r
+  @param  Is64BitCapable   Whether this controller support 64 bit addressing.\r
 \r
-  @retval EFI_SUCCESS      The host controller capability is returned\r
+  @retval EFI_SUCCESS      The host controller capability is returned.\r
   @retval Others           Failed to retrieve the host controller capability.\r
 \r
 **/\r
@@ -95,98 +84,23 @@ UsbHcGetCapability (
 }\r
 \r
 \r
-/**\r
-  Reset the host controller\r
-\r
-  @param  UsbBus           The usb bus driver\r
-  @param  Attributes       The reset type, only global reset is used by this driver\r
-\r
-  @return GC_TODO: add return values\r
-\r
-**/\r
-EFI_STATUS\r
-UsbHcReset (\r
-  IN USB_BUS              *UsbBus,\r
-  IN UINT16               Attributes\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  if (UsbBus->Usb2Hc != NULL) {\r
-    Status = UsbBus->Usb2Hc->Reset (UsbBus->Usb2Hc, Attributes);\r
-  } else {\r
-    Status = UsbBus->UsbHc->Reset (UsbBus->UsbHc, Attributes);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Get the current operation state of the host controller\r
-\r
-  @param  UsbBus           The USB bus driver\r
-  @param  State            The host controller operation state\r
-\r
-  @retval EFI_SUCCESS      The operation state is returned in State\r
-  @retval Others           Failed to get the host controller state\r
 \r
-**/\r
-EFI_STATUS\r
-UsbHcGetState (\r
-  IN  USB_BUS             *UsbBus,\r
-  OUT EFI_USB_HC_STATE    *State\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
 \r
-  if (UsbBus->Usb2Hc != NULL) {\r
-    Status = UsbBus->Usb2Hc->GetState (UsbBus->Usb2Hc, State);\r
-  } else {\r
-    Status = UsbBus->UsbHc->GetState (UsbBus->UsbHc, State);\r
-  }\r
 \r
-  return Status;\r
-}\r
 \r
 \r
-/**\r
-  Set the host controller operation state\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  State            The state to set\r
-\r
-  @retval EFI_SUCCESS      The host controller is now working at State\r
-  @retval Others           Failed to set operation state\r
-\r
-**/\r
-EFI_STATUS\r
-UsbHcSetState (\r
-  IN USB_BUS              *UsbBus,\r
-  IN EFI_USB_HC_STATE     State\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  if (UsbBus->Usb2Hc != NULL) {\r
-    Status = UsbBus->Usb2Hc->SetState (UsbBus->Usb2Hc, State);\r
-  } else {\r
-    Status = UsbBus->UsbHc->SetState (UsbBus->UsbHc, State);\r
-  }\r
-\r
-  return Status;\r
-}\r
 \r
 \r
 /**\r
-  Get the root hub port state\r
+  Get the root hub port state.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  PortIndex        The index of port\r
-  @param  PortStatus       The variable to save port state\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  PortIndex        The index of port.\r
+  @param  PortStatus       The variable to save port state.\r
 \r
-  @retval EFI_SUCCESS      The root port state is returned in\r
-  @retval Others           Failed to get the root hub port state\r
+  @retval EFI_SUCCESS      The root port state is returned in.\r
+  @retval Others           Failed to get the root hub port state.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -209,14 +123,14 @@ UsbHcGetRootHubPortStatus (
 \r
 \r
 /**\r
-  Set the root hub port feature\r
+  Set the root hub port feature.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  PortIndex        The port index\r
-  @param  Feature          The port feature to set\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  PortIndex        The port index.\r
+  @param  Feature          The port feature to set.\r
 \r
-  @retval EFI_SUCCESS      The port feature is set\r
-  @retval Others           Failed to set port feature\r
+  @retval EFI_SUCCESS      The port feature is set.\r
+  @retval Others           Failed to set port feature.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -240,14 +154,14 @@ UsbHcSetRootHubPortFeature (
 \r
 \r
 /**\r
-  Clear the root hub port feature\r
+  Clear the root hub port feature.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  PortIndex        The port index\r
-  @param  Feature          The port feature to clear\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  PortIndex        The port index.\r
+  @param  Feature          The port feature to clear.\r
 \r
-  @retval EFI_SUCCESS      The port feature is clear\r
-  @retval Others           Failed to clear port feature\r
+  @retval EFI_SUCCESS      The port feature is clear.\r
+  @retval Others           Failed to clear port feature.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -270,22 +184,22 @@ UsbHcClearRootHubPortFeature (
 \r
 \r
 /**\r
-  Execute a control transfer to the device\r
-\r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The device address\r
-  @param  DevSpeed         The device speed\r
-  @param  MaxPacket        Maximum packet size of endpoint 0\r
-  @param  Request          The control transfer request\r
-  @param  Direction        The direction of data stage\r
-  @param  Data             The buffer holding data\r
-  @param  DataLength       The length of the data\r
-  @param  TimeOut          Timeout (in ms) to wait until timeout\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  UsbResult        The result of transfer\r
-\r
-  @retval EFI_SUCCESS      The control transfer finished without error\r
-  @retval Others           The control transfer failed, reason returned in UsbReslt\r
+  Execute a control transfer to the device.\r
+\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  DevAddr          The device address.\r
+  @param  DevSpeed         The device speed.\r
+  @param  MaxPacket        Maximum packet size of endpoint 0.\r
+  @param  Request          The control transfer request.\r
+  @param  Direction        The direction of data stage.\r
+  @param  Data             The buffer holding data.\r
+  @param  DataLength       The length of the data.\r
+  @param  TimeOut          Timeout (in ms) to wait until timeout.\r
+  @param  Translator       The transaction translator for low/full speed device.\r
+  @param  UsbResult        The result of transfer.\r
+\r
+  @retval EFI_SUCCESS      The control transfer finished without error.\r
+  @retval Others           The control transfer failed, reason returned in UsbReslt.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -342,25 +256,25 @@ UsbHcControlTransfer (
 \r
 \r
 /**\r
-  Execute a bulk transfer to the device's endpoint\r
+  Execute a bulk transfer to the device's endpoint.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The target device address\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  DevAddr          The target device address.\r
   @param  EpAddr           The target endpoint address, with direction encoded in\r
-                           bit 7\r
-  @param  DevSpeed         The device's speed\r
-  @param  MaxPacket        The endpoint's max packet size\r
-  @param  BufferNum        The number of data buffer\r
-  @param  Data             Array of pointers to data buffer\r
-  @param  DataLength       The length of data buffer\r
+                           bit 7.\r
+  @param  DevSpeed         The device's speed.\r
+  @param  MaxPacket        The endpoint's max packet size.\r
+  @param  BufferNum        The number of data buffer.\r
+  @param  Data             Array of pointers to data buffer.\r
+  @param  DataLength       The length of data buffer.\r
   @param  DataToggle       On input, the initial data toggle to use, also  return\r
                            the next toggle on output.\r
-  @param  TimeOut          The time to wait until timeout\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  UsbResult        The result of USB execution\r
+  @param  TimeOut          The time to wait until timeout.\r
+  @param  Translator       The transaction translator for low/full speed device.\r
+  @param  UsbResult        The result of USB execution.\r
 \r
-  @retval EFI_SUCCESS      The bulk transfer is finished without error\r
-  @retval Others           Failed to execute bulk transfer, result in UsbResult\r
+  @retval EFI_SUCCESS      The bulk transfer is finished without error.\r
+  @retval Others           Failed to execute bulk transfer, result in UsbResult.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -415,25 +329,25 @@ UsbHcBulkTransfer (
 \r
 \r
 /**\r
-  Queue or cancel an asynchronous interrupt transfer\r
+  Queue or cancel an asynchronous interrupt transfer.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The target device address\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  DevAddr          The target device address.\r
   @param  EpAddr           The target endpoint address, with direction encoded in\r
-                           bit 7\r
-  @param  DevSpeed         The device's speed\r
-  @param  MaxPacket        The endpoint's max packet size\r
+                           bit 7.\r
+  @param  DevSpeed         The device's speed.\r
+  @param  MaxPacket        The endpoint's max packet size.\r
   @param  IsNewTransfer    Whether this is a new request. If not, cancel the old\r
-                           request\r
-  @param  DataToggle       Data toggle to use on input, next toggle on output\r
-  @param  PollingInterval  The interval to poll the interrupt transfer (in ms)\r
-  @param  DataLength       The length of periodical data receive\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  Callback         Function to call when data is received\r
-  @param  Context          The context to the callback\r
+                           request.\r
+  @param  DataToggle       Data toggle to use on input, next toggle on output.\r
+  @param  PollingInterval  The interval to poll the interrupt transfer (in ms).\r
+  @param  DataLength       The length of periodical data receive.\r
+  @param  Translator       The transaction translator for low/full speed device.\r
+  @param  Callback         Function to call when data is received.\r
+  @param  Context          The context to the callback.\r
 \r
-  @retval EFI_SUCCESS      The asynchronous transfer is queued\r
-  @retval Others           Failed to queue the transfer\r
+  @retval EFI_SUCCESS      The asynchronous transfer is queued.\r
+  @retval Others           Failed to queue the transfer.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -493,24 +407,24 @@ UsbHcAsyncInterruptTransfer (
 \r
 \r
 /**\r
-  Execute a synchronous interrupt transfer to the target endpoint\r
+  Execute a synchronous interrupt transfer to the target endpoint.\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The target device address\r
+  @param  UsbBus           The USB bus driver.\r
+  @param  DevAddr          The target device address.\r
   @param  EpAddr           The target endpoint address, with direction encoded in\r
-                           bit 7\r
-  @param  DevSpeed         The device's speed\r
-  @param  MaxPacket        The endpoint's max packet size\r
-  @param  Data             Pointer to data buffer\r
-  @param  DataLength       The length of data buffer\r
+                           bit 7.\r
+  @param  DevSpeed         The device's speed.\r
+  @param  MaxPacket        The endpoint's max packet size.\r
+  @param  Data             Pointer to data buffer.\r
+  @param  DataLength       The length of data buffer.\r
   @param  DataToggle       On input, the initial data toggle to use, also  return\r
                            the next toggle on output.\r
-  @param  TimeOut          The time to wait until timeout\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  UsbResult        The result of USB execution\r
+  @param  TimeOut          The time to wait until timeout.\r
+  @param  Translator       The transaction translator for low/full speed device.\r
+  @param  UsbResult        The result of USB execution.\r
 \r
-  @retval EFI_SUCCESS      The synchronous interrupt transfer is OK\r
-  @retval Others           Failed to execute the synchronous interrupt transfer\r
+  @retval EFI_SUCCESS      The synchronous interrupt transfer is OK.\r
+  @retval Others           Failed to execute the synchronous interrupt transfer.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -565,87 +479,19 @@ UsbHcSyncInterruptTransfer (
 }\r
 \r
 \r
-/**\r
-  Execute a synchronous Isochronous USB transfer\r
 \r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The target device address\r
-  @param  EpAddr           The target endpoint address, with direction encoded in\r
-                           bit 7\r
-  @param  DevSpeed         The device's speed\r
-  @param  MaxPacket        The endpoint's max packet size\r
-  @param  BufferNum        The number of data buffer\r
-  @param  Data             Array of pointers to data buffer\r
-  @param  DataLength       The length of data buffer\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  UsbResult        The result of USB execution\r
 \r
-  @retval EFI_UNSUPPORTED  The isochronous transfer isn't supported now\r
 \r
-**/\r
-EFI_STATUS\r
-UsbHcIsochronousTransfer (\r
-  IN  USB_BUS                             *UsbBus,\r
-  IN  UINT8                               DevAddr,\r
-  IN  UINT8                               EpAddr,\r
-  IN  UINT8                               DevSpeed,\r
-  IN  UINTN                               MaxPacket,\r
-  IN  UINT8                               BufferNum,\r
-  IN  OUT VOID                            *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
-  IN  UINTN                               DataLength,\r
-  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
-  OUT UINT32                              *UsbResult\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
 \r
 \r
-/**\r
-  Queue an asynchronous isochronous transfer\r
-\r
-  @param  UsbBus           The USB bus driver\r
-  @param  DevAddr          The target device address\r
-  @param  EpAddr           The target endpoint address, with direction encoded in\r
-                           bit 7\r
-  @param  DevSpeed         The device's speed\r
-  @param  MaxPacket        The endpoint's max packet size\r
-  @param  BufferNum        The number of data buffer\r
-  @param  Data             Array of pointers to data buffer\r
-  @param  DataLength       The length of data buffer\r
-  @param  Translator       The transaction translator for low/full speed device\r
-  @param  Callback         The function to call when data is transferred\r
-  @param  Context          The context to the callback function\r
-\r
-  @retval EFI_UNSUPPORTED  The asynchronous isochronous transfer isn't supported\r
-\r
-**/\r
-EFI_STATUS\r
-UsbHcAsyncIsochronousTransfer (\r
-  IN  USB_BUS                             *UsbBus,\r
-  IN  UINT8                               DevAddr,\r
-  IN  UINT8                               EpAddr,\r
-  IN  UINT8                               DevSpeed,\r
-  IN  UINTN                               MaxPacket,\r
-  IN  UINT8                               BufferNum,\r
-  IN OUT VOID                             *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
-  IN  UINTN                               DataLength,\r
-  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
-  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK     Callback,\r
-  IN  VOID                                *Context\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
 \r
 /**\r
-  Open the USB host controller protocol BY_CHILD\r
+  Open the USB host controller protocol BY_CHILD.\r
 \r
-  @param  Bus              The USB bus driver\r
-  @param  Child            The child handle\r
+  @param  Bus              The USB bus driver.\r
+  @param  Child            The child handle.\r
 \r
-  @return The open protocol return\r
+  @return The open protocol return.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -684,12 +530,10 @@ UsbOpenHostProtoByChild (
 \r
 \r
 /**\r
-  Close the USB host controller protocol BY_CHILD\r
+  Close the USB host controller protocol BY_CHILD.\r
 \r
-  @param  Bus              The USB bus driver\r
-  @param  Child            The child handle\r
-\r
-  @return None\r
+  @param  Bus              The USB bus driver.\r
+  @param  Child            The child handle.\r
 \r
 **/\r
 VOID\r
@@ -717,13 +561,12 @@ UsbCloseHostProtoByChild (
 }\r
 \r
 \r
-\r
 /**\r
   return the current TPL, copied from the EDKII glue lib.\r
 \r
-  VOID\r
+  @param  VOID.\r
 \r
-  @return Current TPL\r
+  @return Current TPL.\r
 \r
 **/\r
 EFI_TPL\r
@@ -740,11 +583,11 @@ UsbGetCurrentTpl (
 }\r
 \r
 /**\r
-  Create a new device path which only contain the first Usb part of the DevicePath\r
+  Create a new device path which only contain the first Usb part of the DevicePath.\r
 \r
-  @param DevicePath  A full device path which contain the usb nodes\r
+  @param DevicePath  A full device path which contain the usb nodes.\r
 \r
-  @return            A new device path which only contain the Usb part of the DevicePath\r
+  @return            A new device path which only contain the Usb part of the DevicePath.\r
 \r
 **/\r
 EFI_DEVICE_PATH_PROTOCOL *\r
@@ -762,7 +605,7 @@ GetUsbDPFromFullDP (
   // Get the Usb part first Begin node in full device path\r
   //\r
   UsbDevicePathBeginPtr = DevicePath;\r
-  while ( (!EfiIsDevicePathEnd (UsbDevicePathBeginPtr))&&\r
+  while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr))&&\r
          ((UsbDevicePathBeginPtr->Type != MESSAGING_DEVICE_PATH) ||\r
          (UsbDevicePathBeginPtr->SubType != MSG_USB_DP &&\r
           UsbDevicePathBeginPtr->SubType != MSG_USB_CLASS_DP\r
@@ -776,7 +619,7 @@ GetUsbDPFromFullDP (
   // Get the Usb part first End node in full device path\r
   //\r
   UsbDevicePathEndPtr = UsbDevicePathBeginPtr;\r
-  while ((!EfiIsDevicePathEnd (UsbDevicePathEndPtr))&&\r
+  while ((!IsDevicePathEnd (UsbDevicePathEndPtr))&&\r
          (UsbDevicePathEndPtr->Type == MESSAGING_DEVICE_PATH) &&\r
          (UsbDevicePathEndPtr->SubType == MSG_USB_DP ||\r
           UsbDevicePathEndPtr->SubType == MSG_USB_CLASS_DP\r
@@ -812,11 +655,11 @@ GetUsbDPFromFullDP (
 /**\r
   Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.\r
 \r
-  @param UsbDP       a usb device path of DEVICE_PATH_LIST_ITEM\r
-  @parem UsbIoDPList a DEVICE_PATH_LIST_ITEM list\r
+  @param UsbDP       a usb device path of DEVICE_PATH_LIST_ITEM.\r
+  @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.\r
 \r
-  @retval TRUE       there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP\r
-  @retval FALSE      there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP\r
+  @retval TRUE       there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.\r
+  @retval FALSE      there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.\r
 \r
 **/\r
 BOOLEAN\r
@@ -863,11 +706,11 @@ SearchUsbDPInList (
 /**\r
   Add a usb device path into the DEVICE_PATH_LIST_ITEM list.\r
 \r
-  @param UsbDP        a usb device path of DEVICE_PATH_LIST_ITEM\r
-  @param UsbIoDPList  a DEVICE_PATH_LIST_ITEM list\r
+  @param UsbDP                   a usb device path of DEVICE_PATH_LIST_ITEM.\r
+  @param UsbIoDPList             a DEVICE_PATH_LIST_ITEM list.\r
 \r
-  @retval EFI_INVALID_PARAMETER\r
-  @retval EFI_SUCCESS\r
+  @retval EFI_INVALID_PARAMETER  If parameters are invalid, return this value.\r
+  @retval EFI_SUCCESS            If Add operation is successful, return this value.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -905,13 +748,13 @@ AddUsbDPToList (
 \r
 /**\r
   Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by\r
-  UsbClassDevicePathPtr whose is a short form usb class device path\r
+  UsbClassDevicePathPtr whose is a short form usb class device path.\r
 \r
-  @param UsbClassDevicePathPtr    a short form usb class device path\r
-  @param UsbIf                    a usb device interface\r
+  @param UsbClassDevicePathPtr    a short form usb class device path.\r
+  @param UsbIf                    a usb device interface.\r
 \r
-  @retval TRUE                    the usb device match the usb class\r
-  @retval FALSE                   the usb device does not match the usb class\r
+  @retval TRUE                    the usb device match the usb class.\r
+  @retval FALSE                   the usb device does not match the usb class.\r
 \r
 **/\r
 BOOLEAN\r
@@ -933,6 +776,7 @@ MatchUsbClass (
   }\r
 \r
   IfDesc       = UsbIf->IfDesc;\r
+  ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);\r
   ActIfDesc    = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);\r
   DevDesc      = &(UsbIf->Device->DevDesc->Desc);\r
 \r
@@ -954,12 +798,9 @@ MatchUsbClass (
       (UsbClassDevicePathPtr->ProductId == 0xffff || UsbClassDevicePathPtr->ProductId == DevDesc->IdProduct)) {\r
 \r
     //\r
-    // If class or subclass or protocol is 0, the counterparts in interface should be checked.\r
+    // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked.\r
     //\r
-    if (DevDesc->DeviceClass == 0 ||\r
-        DevDesc->DeviceSubClass == 0 ||\r
-        DevDesc->DeviceProtocol == 0) {\r
-\r
+    if (DevDesc->DeviceClass == 0) {\r
       if ((UsbClassDevicePathPtr->DeviceClass == ActIfDesc->InterfaceClass ||\r
                                           UsbClassDevicePathPtr->DeviceClass == 0xff) &&\r
           (UsbClassDevicePathPtr->DeviceSubClass == ActIfDesc->InterfaceSubClass ||\r
@@ -985,16 +826,15 @@ MatchUsbClass (
 \r
 /**\r
   Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by\r
-  UsbWWIDDevicePathPtr whose is a short form usb WWID device path\r
+  UsbWWIDDevicePathPtr whose is a short form usb WWID device path.\r
 \r
-  @param UsbClassDevicePathPtr   a short form usb WWID device path\r
-  @param UsbIf                   a usb device interface\r
+  @param UsbWWIDDevicePathPtr    a short form usb WWID device path.\r
+  @param UsbIf                   a usb device interface.\r
 \r
-  @retval TRUE                   the usb device match the usb WWID requirement\r
-  @retval FALSE                  the usb device does not match the usb WWID requirement\r
+  @retval TRUE                   the usb device match the usb WWID requirement.\r
+  @retval FALSE                  the usb device does not match the usb WWID requirement.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 MatchUsbWwid (\r
   IN USB_WWID_DEVICE_PATH       *UsbWWIDDevicePathPtr,\r
@@ -1005,7 +845,10 @@ MatchUsbWwid (
   EFI_USB_INTERFACE_DESCRIPTOR  *ActIfDesc;\r
   EFI_USB_DEVICE_DESCRIPTOR     *DevDesc;\r
   EFI_USB_STRING_DESCRIPTOR     *StrDesc;\r
-  UINT16                        *SnString;\r
+  UINT16                        Index;\r
+  CHAR16                        *CompareStr;\r
+  UINTN                         CompareLen;\r
+  UINTN                         Length;\r
 \r
   if ((UsbWWIDDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||\r
      (UsbWWIDDevicePathPtr->Header.SubType != MSG_USB_WWID_DP )){\r
@@ -1014,41 +857,69 @@ MatchUsbWwid (
   }\r
 \r
   IfDesc       = UsbIf->IfDesc;\r
+  ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);\r
   ActIfDesc    = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);\r
   DevDesc      = &(UsbIf->Device->DevDesc->Desc);\r
-  StrDesc      = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, USB_US_LAND_ID);\r
-  SnString     = (UINT16 *) ((UINT8 *)UsbWWIDDevicePathPtr + 10);\r
 \r
   //\r
-  //In addtion, hub interface is always matched for this policy.\r
+  // In addition, Hub interface is always matched for this policy.\r
   //\r
   if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&\r
       (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) {\r
     return TRUE;\r
   }\r
+\r
   //\r
-  // If connect wwid policy, determine the objective device by the serial number of\r
-  // device descriptor.\r
-  // Get serial number index from device descriptor, then get serial number by index\r
-  // and land id, compare the serial number with wwid device path node at last\r
+  // Check Vendor Id, Product Id and Interface Number.\r
   //\r
-  // BugBug: only check serial number here, should check Interface Number, Device Vendor Id, Device Product Id  in later version\r
+  if ((DevDesc->IdVendor != UsbWWIDDevicePathPtr->VendorId) ||\r
+      (DevDesc->IdProduct != UsbWWIDDevicePathPtr->ProductId) ||\r
+      (ActIfDesc->InterfaceNumber != UsbWWIDDevicePathPtr->InterfaceNumber)) {\r
+    return FALSE;\r
+  }\r
+\r
   //\r
-  if (StrDesc != NULL && !StrnCmp (StrDesc->String, SnString, StrDesc->Length)) {\r
+  // Check SerialNumber.\r
+  //\r
+  if (DevDesc->StrSerialNumber == 0) {\r
+    return FALSE;\r
+  }\r
 \r
-    return TRUE;\r
+  //\r
+  // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.\r
+  //\r
+  CompareStr = (CHAR16 *) (UINTN) (UsbWWIDDevicePathPtr + 1);\r
+  CompareLen = (DevicePathNodeLength (UsbWWIDDevicePathPtr) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);\r
+  if (CompareStr[CompareLen - 1] == L'\0') {\r
+    CompareLen--;\r
+  }\r
+\r
+  //\r
+  // Compare serial number in each supported language.\r
+  //\r
+  for (Index = 0; Index < UsbIf->Device->TotalLangId; Index++) {\r
+    StrDesc = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, UsbIf->Device->LangId[Index]);\r
+    if (StrDesc == NULL) {\r
+      continue;\r
+    }\r
+\r
+    Length = (StrDesc->Length - 2) / sizeof (CHAR16);\r
+    if ((Length >= CompareLen) &&\r
+        (CompareMem (StrDesc->String + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) {\r
+      return TRUE;\r
+    }\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
 /**\r
-  Free a DEVICE_PATH_LIST_ITEM list\r
+  Free a DEVICE_PATH_LIST_ITEM list.\r
 \r
-  @param UsbIoDPList  a DEVICE_PATH_LIST_ITEM list pointer\r
+  @param  UsbIoDPList            a DEVICE_PATH_LIST_ITEM list pointer.\r
 \r
-  @retval EFI_INVALID_PARAMETER\r
-  @retval EFI_SUCCESS\r
+  @retval EFI_INVALID_PARAMETER  If parameters are invalid, return this value.\r
+  @retval EFI_SUCCESS            If free operation is successful, return this value.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1090,14 +961,13 @@ UsbBusFreeUsbDPList (
 \r
 /**\r
   Store a wanted usb child device info (its Usb part of device path) which is indicated by\r
-  RemainingDevicePath in a Usb bus which  is indicated by UsbBusId\r
+  RemainingDevicePath in a Usb bus which  is indicated by UsbBusId.\r
 \r
-  @param UsbBusId              Point to EFI_USB_BUS_PROTOCOL interface\r
-  @param RemainingDevicePath   The remaining device patch\r
+  @param  UsbBusId               Point to EFI_USB_BUS_PROTOCOL interface.\r
+  @param  RemainingDevicePath    The remaining device patch.\r
 \r
-  @retval EFI_SUCCESS\r
-  @retval EFI_INVALID_PARAMETER\r
-  @retval EFI_OUT_OF_RESOURCES\r
+  @retval EFI_SUCCESS            Add operation is successful.\r
+  @retval EFI_INVALID_PARAMETER  The parameters are invalid.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1114,7 +984,7 @@ UsbBusAddWantedUsbIoDP (
   //\r
   // Check whether remaining device path is valid\r
   //\r
-  if (RemainingDevicePath != NULL) {\r
+  if (RemainingDevicePath != NULL && !IsDevicePathEnd (RemainingDevicePath)) {\r
     if ((RemainingDevicePath->Type    != MESSAGING_DEVICE_PATH) ||\r
         (RemainingDevicePath->SubType != MSG_USB_DP &&\r
          RemainingDevicePath->SubType != MSG_USB_CLASS_DP\r
@@ -1132,36 +1002,42 @@ UsbBusAddWantedUsbIoDP (
 \r
   if (RemainingDevicePath == NULL) {\r
     //\r
-    // RemainingDevicePath== NULL means all Usb devices in this bus are wanted.\r
+    // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.\r
     // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices\r
     // are wanted Usb devices\r
     //\r
     Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);\r
     ASSERT (!EFI_ERROR (Status));\r
     DevicePathPtr = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) &mAllUsbClassDevicePath);\r
-  } else {\r
+  } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
     //\r
+    // If RemainingDevicePath isn't the End of Device Path Node,\r
     // Create new Usb device path according to the usb part in remaining device path\r
     //\r
     DevicePathPtr = GetUsbDPFromFullDP (RemainingDevicePath);\r
+  } else {\r
+    //\r
+    // If RemainingDevicePath is the End of Device Path Node,\r
+    // skip enumerate any device and return EFI_SUCESSS\r
+    //\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   ASSERT (DevicePathPtr != NULL);\r
   Status = AddUsbDPToList (DevicePathPtr, &Bus->WantedUsbIoDPList);\r
   ASSERT (!EFI_ERROR (Status));\r
-  gBS->FreePool (DevicePathPtr);\r
+  FreePool (DevicePathPtr);\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Check whether a usb child  device is the wanted device in a bus\r
+  Check whether a usb child device is the wanted device in a bus.\r
 \r
-  @param Bus      The Usb bus's private data pointer\r
-  @param UsbIf    The usb child  device inferface\r
+  @param  Bus     The Usb bus's private data pointer.\r
+  @param  UsbIf   The usb child device inferface.\r
 \r
-  @retval EFI_SUCCESS\r
-  @retval EFI_INVALID_PARAMETER\r
-  @retval EFI_OUT_OF_RESOURCES\r
+  @retval True    If a usb child device is the wanted device in a bus.\r
+  @retval False   If a usb child device is *NOT* the wanted device in a bus.\r
 \r
 **/\r
 BOOLEAN\r
@@ -1261,13 +1137,12 @@ UsbBusIsWantedUsbIO (
 \r
 /**\r
   Recursively connnect every wanted usb child device to ensure they all fully connected.\r
-  Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device\r
+  Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.\r
 \r
-  @param UsbBusId   point to EFI_USB_BUS_PROTOCOL interface\r
+  @param  UsbBusId                  Point to EFI_USB_BUS_PROTOCOL interface.\r
 \r
-  @retval EFI_SUCCESS\r
-  @retval EFI_INVALID_PARAMETER\r
-  @retval EFI_OUT_OF_RESOURCES\r
+  @retval EFI_SUCCESS               Connect is done successfully.\r
+  @retval EFI_INVALID_PARAMETER     The parameter is invalid.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1337,14 +1212,16 @@ UsbBusRecursivelyConnectWantedUsbIo (
         //\r
         // Recursively connect the wanted Usb Io handle\r
         //\r
-        DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL before connect is %d\n", UsbGetCurrentTpl ()));\r
+        DEBUG ((EFI_D_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL before connect is %d\n", (UINT32)UsbGetCurrentTpl ()));\r
         Status            = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);\r
         UsbIf->IsManaged  = (BOOLEAN)!EFI_ERROR (Status);\r
-        DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));\r
+        DEBUG ((EFI_D_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL after connect is %d\n", (UINT32)UsbGetCurrentTpl()));\r
       }\r
     }\r
   }\r
 \r
+  FreePool (UsbIoBuffer);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r