]> 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 2d2bd2a154dd5671e689dc11e90318d27c453b1d..8559992d27430335f6c23551be3457254d65a0aa 100644 (file)
@@ -2,14 +2,8 @@
 \r
     Wrapper function for usb host controller interface.\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
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -90,90 +84,12 @@ 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
-  @retval EFI_SUCCESS           The reset operation succeeded.\r
-  @retval EFI_INVALID_PARAMETER Attributes is not valid.\r
-  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is\r
-                                not currently supported by the host controller.\r
-  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.\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
@@ -563,78 +479,10 @@ 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
@@ -928,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
@@ -949,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
@@ -999,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
@@ -1008,29 +857,57 @@ 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) == 0)) {\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
@@ -1107,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
@@ -1125,24 +1002,31 @@ 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
@@ -1328,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", (UINT32)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", (UINT32)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