]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbBus.c
index e8f9ed5018dc3c64bf110334b7eb8a9f4484fd8f..d4002c48d74e1a7908e68cf0da000c422cb5e57a 100644 (file)
@@ -2,14 +2,8 @@
 \r
     Usb Bus Driver Binding and Bus IO Protocol.\r
 \r
-Copyright (c) 2004 - 2011, 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
-\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) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -76,6 +70,7 @@ UsbIoControlTransfer (
   USB_ENDPOINT_DESC       *EpDesc;\r
   EFI_TPL                 OldTpl;\r
   EFI_STATUS              Status;\r
+  UINTN                   RequestedDataLength;\r
 \r
   if (UsbStatus == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -86,6 +81,7 @@ UsbIoControlTransfer (
   UsbIf  = USB_INTERFACE_FROM_USBIO (This);\r
   Dev    = UsbIf->Device;\r
 \r
+  RequestedDataLength = DataLength;\r
   Status = UsbHcControlTransfer (\r
              Dev->Bus,\r
              Dev->Address,\r
@@ -99,6 +95,18 @@ UsbIoControlTransfer (
              &Dev->Translator,\r
              UsbStatus\r
              );\r
+  //\r
+  // If the request completed sucessfully and the Direction of the request is\r
+  // EfiUsbDataIn or EfiUsbDataOut, then make sure the actual number of bytes\r
+  // transfered is the same as the number of bytes requested.  If a different\r
+  // number of bytes were transfered, then return EFI_DEVICE_ERROR.\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    if (Direction != EfiUsbNoData && DataLength != RequestedDataLength) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
 \r
   if (EFI_ERROR (Status) || (*UsbStatus != EFI_USB_NOERROR)) {\r
     //\r
@@ -813,6 +821,7 @@ UsbIoPortReset (
   USB_DEVICE              *Dev;\r
   EFI_TPL                 OldTpl;\r
   EFI_STATUS              Status;\r
+  UINT8                   DevAddress;\r
 \r
   OldTpl = gBS->RaiseTPL (USB_BUS_TPL);\r
 \r
@@ -834,15 +843,20 @@ UsbIoPortReset (
     goto ON_EXIT;\r
   }\r
 \r
+  HubIf->HubApi->ClearPortChange (HubIf, Dev->ParentPort);\r
+\r
   //\r
   // Reset the device to its current address. The device now has an address\r
   // of ZERO after port reset, so need to set Dev->Address to the device again for\r
   // host to communicate with it.\r
   //\r
-  Status  = UsbSetAddress (Dev, Dev->Address);\r
+  DevAddress   = Dev->Address;\r
+  Dev->Address = 0;\r
+  Status  = UsbSetAddress (Dev, DevAddress);\r
+  Dev->Address = DevAddress;\r
 \r
   gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     //\r
     // It may fail due to device disconnection or other reasons.\r
@@ -964,14 +978,12 @@ UsbBusBuildProtocol (
     // The EFI_USB2_HC_PROTOCOL is produced for XHCI support.\r
     // Then its max supported devices are 256. Otherwise it's 128.\r
     //\r
+    ASSERT (UsbBus->Usb2Hc != NULL);\r
     if (UsbBus->Usb2Hc->MajorRevision == 0x3) {\r
       UsbBus->MaxDevices = 256;\r
     }\r
   }\r
 \r
-  UsbHcReset (UsbBus, EFI_USB_HC_RESET_GLOBAL);\r
-  UsbHcSetState (UsbBus, EfiUsbHcStateOperational);\r
-\r
   //\r
   // Install an EFI_USB_BUS_PROTOCOL to host controller to identify it.\r
   //\r
@@ -1019,6 +1031,15 @@ UsbBusBuildProtocol (
   RootIf->Device          = RootHub;\r
   RootIf->DevicePath      = UsbBus->DevicePath;\r
 \r
+  //\r
+  // Report Status Code here since we will enumerate the USB devices\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT),\r
+    UsbBus->DevicePath\r
+    );\r
+\r
   Status                  = mUsbRootHubApi.Init (RootIf);\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -1130,7 +1151,7 @@ UsbBusControllerDriverSupported (
   //\r
   if (RemainingDevicePath != NULL) {\r
     //\r
-    // Check if RemainingDevicePath is the End of Device Path Node, \r
+    // Check if RemainingDevicePath is the End of Device Path Node,\r
     // if yes, go on checking other conditions\r
     //\r
     if (!IsDevicePathEnd (RemainingDevicePath)) {\r
@@ -1139,13 +1160,13 @@ UsbBusControllerDriverSupported (
       // check its validation\r
       //\r
       DevicePathNode.DevPath = RemainingDevicePath;\r
-      \r
+\r
       if ((DevicePathNode.DevPath->Type    != MESSAGING_DEVICE_PATH) ||\r
           (DevicePathNode.DevPath->SubType != MSG_USB_DP &&\r
            DevicePathNode.DevPath->SubType != MSG_USB_CLASS_DP\r
            && DevicePathNode.DevPath->SubType != MSG_USB_WWID_DP\r
            )) {\r
-      \r
+\r
         return EFI_UNSUPPORTED;\r
       }\r
     }\r
@@ -1181,7 +1202,7 @@ UsbBusControllerDriverSupported (
     if (Status == EFI_ALREADY_STARTED) {\r
       return EFI_SUCCESS;\r
     }\r
-  \r
+\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -1208,7 +1229,7 @@ UsbBusControllerDriverSupported (
            Controller\r
            );\r
   }\r
\r
+\r
   //\r
   // Open the EFI Device Path protocol needed to perform the supported test\r
   //\r
@@ -1265,6 +1286,26 @@ UsbBusControllerDriverStart (
 {\r
   EFI_USB_BUS_PROTOCOL          *UsbBusId;\r
   EFI_STATUS                    Status;\r
+  EFI_DEVICE_PATH_PROTOCOL      *ParentDevicePath;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Report Status Code here since we will initialize the host controller\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_USB | EFI_IOB_PC_INIT),\r
+    ParentDevicePath\r
+    );\r
 \r
   //\r
   // Locate the USB bus protocol, if it is found, USB bus\r
@@ -1315,7 +1356,7 @@ UsbBusControllerDriverStart (
         //\r
         // If RemainingDevicePath is the End of Device Path Node,\r
         // skip enumerate any device and return EFI_SUCESSS\r
-        // \r
+        //\r
         return EFI_SUCCESS;\r
       }\r
     }\r
@@ -1366,6 +1407,7 @@ UsbBusControllerDriverStop (
   EFI_TPL               OldTpl;\r
   UINTN                 Index;\r
   EFI_STATUS            Status;\r
+  EFI_STATUS            ReturnStatus;\r
 \r
   Status  = EFI_SUCCESS;\r
 \r
@@ -1375,6 +1417,7 @@ UsbBusControllerDriverStop (
     //\r
     OldTpl   = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
+    ReturnStatus = EFI_SUCCESS;\r
     for (Index = 0; Index < NumberOfChildren; Index++) {\r
       Status = gBS->OpenProtocol (\r
                       ChildHandleBuffer[Index],\r
@@ -1398,11 +1441,11 @@ UsbBusControllerDriverStop (
       UsbIf   = USB_INTERFACE_FROM_USBIO (UsbIo);\r
       UsbDev  = UsbIf->Device;\r
 \r
-      UsbRemoveDevice (UsbDev);\r
+      ReturnStatus = UsbRemoveDevice (UsbDev);\r
     }\r
 \r
     gBS->RestoreTPL (OldTpl);\r
-    return EFI_SUCCESS;\r
+    return ReturnStatus;\r
   }\r
 \r
   DEBUG (( EFI_D_INFO, "UsbBusStop: usb bus stopped on %p\n", Controller));\r
@@ -1435,53 +1478,60 @@ UsbBusControllerDriverStop (
   RootHub = Bus->Devices[0];\r
   RootIf  = RootHub->Interfaces[0];\r
 \r
-  mUsbRootHubApi.Release (RootIf);\r
-\r
   ASSERT (Bus->MaxDevices <= 256);\r
+  ReturnStatus = EFI_SUCCESS;\r
   for (Index = 1; Index < Bus->MaxDevices; Index++) {\r
     if (Bus->Devices[Index] != NULL) {\r
-      UsbRemoveDevice (Bus->Devices[Index]);\r
+      Status = UsbRemoveDevice (Bus->Devices[Index]);\r
+      if (EFI_ERROR (Status)) {\r
+        ReturnStatus = Status;\r
+      }\r
     }\r
   }\r
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  gBS->FreePool   (RootIf);\r
-  gBS->FreePool   (RootHub);\r
-  Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);\r
-  ASSERT (!EFI_ERROR (Status));\r
+  if (!EFI_ERROR (ReturnStatus)) {\r
+    mUsbRootHubApi.Release (RootIf);\r
+    gBS->FreePool   (RootIf);\r
+    gBS->FreePool   (RootHub);\r
 \r
-  //\r
-  // Uninstall the bus identifier and close USB_HC/USB2_HC protocols\r
-  //\r
-  gBS->UninstallProtocolInterface (Controller, &gEfiCallerIdGuid, &Bus->BusId);\r
+    Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);\r
+    ASSERT (!EFI_ERROR (Status));\r
 \r
-  if (Bus->Usb2Hc != NULL) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsb2HcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-  }\r
+    //\r
+    // Uninstall the bus identifier and close USB_HC/USB2_HC protocols\r
+    //\r
+    gBS->UninstallProtocolInterface (Controller, &gEfiCallerIdGuid, &Bus->BusId);\r
 \r
-  if (Bus->UsbHc != NULL) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-  }\r
+    if (Bus->Usb2Hc != NULL) {\r
+      Status = gBS->CloseProtocol (\r
+                      Controller,\r
+                      &gEfiUsb2HcProtocolGuid,\r
+                      This->DriverBindingHandle,\r
+                      Controller\r
+                      );\r
+    }\r
 \r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiDevicePathProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
+    if (Bus->UsbHc != NULL) {\r
+      Status = gBS->CloseProtocol (\r
+                      Controller,\r
+                      &gEfiUsbHcProtocolGuid,\r
+                      This->DriverBindingHandle,\r
+                      Controller\r
+                      );\r
+    }\r
 \r
-  gBS->FreePool (Bus);\r
+    if (!EFI_ERROR (Status)) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiDevicePathProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
 \r
+      gBS->FreePool (Bus);\r
+    }\r
+  }\r
   return Status;\r
 }\r