]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbEnumer.c
index 79453fed268f8e6b9dbe5fda926fedfd168df141..13edbeeec5fd9fddcfe4ae8c0eec1ee7fde075cb 100644 (file)
@@ -2,7 +2,7 @@
 \r
     Usb bus enumeration support.\r
 \r
-Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -33,9 +33,9 @@ UsbGetEndpointDesc (
   USB_ENDPOINT_DESC       *EpDesc;\r
   UINT8                   Index;\r
   UINT8                   NumEndpoints;\r
-  \r
+\r
   NumEndpoints = UsbIf->IfSetting->Desc.NumEndpoints;\r
-  \r
+\r
   for (Index = 0; Index < NumEndpoints; Index++) {\r
     EpDesc = UsbIf->IfSetting->Endpoints[Index];\r
 \r
@@ -53,28 +53,33 @@ UsbGetEndpointDesc (
 \r
   @param  UsbIf                 The USB interface to free.\r
 \r
+  @retval EFI_ACCESS_DENIED     The interface is still occupied.\r
+  @retval EFI_SUCCESS           The interface is freed.\r
 **/\r
-VOID\r
+EFI_STATUS\r
 UsbFreeInterface (\r
   IN USB_INTERFACE        *UsbIf\r
   )\r
 {\r
-  UsbCloseHostProtoByChild (UsbIf->Device->Bus, UsbIf->Handle);\r
+  EFI_STATUS              Status;\r
 \r
-  gBS->UninstallMultipleProtocolInterfaces (\r
-         UsbIf->Handle,\r
-         &gEfiDevicePathProtocolGuid,\r
-         UsbIf->DevicePath,\r
-         &gEfiUsbIoProtocolGuid,\r
-         &UsbIf->UsbIo,\r
-         NULL\r
-         );\r
+  UsbCloseHostProtoByChild (UsbIf->Device->Bus, UsbIf->Handle);\r
 \r
-  if (UsbIf->DevicePath != NULL) {\r
-    FreePool (UsbIf->DevicePath);\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  UsbIf->Handle,\r
+                  &gEfiDevicePathProtocolGuid, UsbIf->DevicePath,\r
+                  &gEfiUsbIoProtocolGuid,      &UsbIf->UsbIo,\r
+                  NULL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    if (UsbIf->DevicePath != NULL) {\r
+      FreePool (UsbIf->DevicePath);\r
+    }\r
+    FreePool (UsbIf);\r
+  } else {\r
+    UsbOpenHostProtoByChild (UsbIf->Device->Bus, UsbIf->Handle);\r
   }\r
-\r
-  FreePool (UsbIf);\r
+  return Status;\r
 }\r
 \r
 \r
@@ -274,7 +279,7 @@ UsbConnectDriver (
     // twisted TPL used. It should be no problem for us to connect\r
     // or disconnect at CALLBACK.\r
     //\r
-    \r
+\r
     //\r
     // Only recursively wanted usb child device\r
     //\r
@@ -435,7 +440,11 @@ UsbSelectConfig (
     Status = UsbConnectDriver (UsbIf);\r
 \r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "UsbSelectConfig: failed to connect driver %r, ignored\n", Status));\r
+      DEBUG ((\r
+        DEBUG_WARN,\r
+        "UsbSelectConfig: failed to connect driver %r, ignored\n",\r
+        Status\r
+        ));\r
     }\r
   }\r
 \r
@@ -484,13 +493,13 @@ UsbDisconnectDriver (
     if (!EFI_ERROR (Status)) {\r
       UsbIf->IsManaged = FALSE;\r
     }\r
-    \r
+\r
     DEBUG (( EFI_D_INFO, "UsbDisconnectDriver: TPL after disconnect is %d, %d\n", (UINT32)UsbGetCurrentTpl(), Status));\r
     ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);\r
 \r
     gBS->RaiseTPL (OldTpl);\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
@@ -515,7 +524,7 @@ UsbRemoveConfig (
   // Remove each interface of the device\r
   //\r
   ReturnStatus = EFI_SUCCESS;\r
-  for (Index = 0; Index < Device->NumOfInterface; Index++) {    \r
+  for (Index = 0; Index < Device->NumOfInterface; Index++) {\r
     ASSERT (Index < USB_MAX_INTERFACE);\r
     UsbIf = Device->Interfaces[Index];\r
 \r
@@ -525,7 +534,13 @@ UsbRemoveConfig (
 \r
     Status = UsbDisconnectDriver (UsbIf);\r
     if (!EFI_ERROR (Status)) {\r
-      UsbFreeInterface (UsbIf);\r
+      Status = UsbFreeInterface (UsbIf);\r
+      if (EFI_ERROR (Status)) {\r
+        UsbConnectDriver (UsbIf);\r
+      }\r
+    }\r
+\r
+    if (!EFI_ERROR (Status)) {\r
       Device->Interfaces[Index] = NULL;\r
     } else {\r
       ReturnStatus = Status;\r
@@ -643,6 +658,7 @@ UsbFindChild (
 \r
   @param  HubIf                 The HUB that has the device connected.\r
   @param  Port                  The port index of the hub (started with zero).\r
+  @param  ResetIsNeeded         The boolean to control whether skip the reset of the port.\r
 \r
   @retval EFI_SUCCESS           The device is enumerated (added or removed).\r
   @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the device.\r
@@ -652,7 +668,8 @@ UsbFindChild (
 EFI_STATUS\r
 UsbEnumerateNewDev (\r
   IN USB_INTERFACE        *HubIf,\r
-  IN UINT8                Port\r
+  IN UINT8                Port,\r
+  IN BOOLEAN              ResetIsNeeded\r
   )\r
 {\r
   USB_BUS                 *Bus;\r
@@ -666,27 +683,29 @@ UsbEnumerateNewDev (
 \r
   Parent  = HubIf->Device;\r
   Bus     = Parent->Bus;\r
-  HubApi  = HubIf->HubApi;  \r
+  HubApi  = HubIf->HubApi;\r
   Address = Bus->MaxDevices;\r
 \r
   gBS->Stall (USB_WAIT_PORT_STABLE_STALL);\r
-  \r
+\r
   //\r
   // Hub resets the device for at least 10 milliseconds.\r
   // Host learns device speed. If device is of low/full speed\r
   // and the hub is a EHCI root hub, ResetPort will release\r
   // the device to its companion UHCI and return an error.\r
   //\r
-  Status = HubApi->ResetPort (HubIf, Port);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));\r
+  if (ResetIsNeeded) {\r
+    Status = HubApi->ResetPort (HubIf, Port);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));\r
 \r
-    return Status;\r
+      return Status;\r
+    }\r
+    DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d is reset\n", Port));\r
+  } else {\r
+    DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d reset is skipped\n", Port));\r
   }\r
 \r
-  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d is reset\n", Port));\r
-\r
   Child = UsbCreateDevice (HubIf, Port);\r
 \r
   if (Child == NULL) {\r
@@ -908,68 +927,72 @@ UsbEnumeratePort (
   // connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.\r
   // ENABLE/RESET is used to reset port. SUSPEND isn't supported.\r
   //\r
-  \r
-  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {     \r
+\r
+  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {\r
 \r
     if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {\r
       //\r
       // Case1:\r
-      //   Both OverCurrent and OverCurrentChange set, means over current occurs, \r
+      //   Both OverCurrent and OverCurrentChange set, means over current occurs,\r
       //   which probably is caused by short circuit. It has to wait system hardware\r
       //   to perform recovery.\r
       //\r
       DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: Critical Over Current\n", Port));\r
       return EFI_DEVICE_ERROR;\r
-      \r
-    } \r
+\r
+    }\r
     //\r
     // Case2:\r
-    //   Only OverCurrentChange set, means system has been recoveried from \r
+    //   Only OverCurrentChange set, means system has been recoveried from\r
     //   over current. As a result, all ports are nearly power-off, so\r
-    //   it's necessary to detach and enumerate all ports again. \r
+    //   it's necessary to detach and enumerate all ports again.\r
     //\r
-    DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port)); \r
+    DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port));\r
   }\r
 \r
-  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {  \r
+  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {\r
     //\r
     // Case3:\r
     //   1.1 roothub port reg doesn't reflect over-current state, while its counterpart\r
-    //   on 2.0 roothub does. When over-current has influence on 1.1 device, the port \r
+    //   on 2.0 roothub does. When over-current has influence on 1.1 device, the port\r
     //   would be disabled, so it's also necessary to detach and enumerate again.\r
     //\r
     DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 1.1 device Recovery Over Current\n", Port));\r
   }\r
-  \r
+\r
   if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {\r
     //\r
     // Case4:\r
-    //   Device connected or disconnected normally. \r
+    //   Device connected or disconnected normally.\r
     //\r
     DEBUG ((EFI_D_INFO, "UsbEnumeratePort: Device Connect/Disconnect Normally\n", Port));\r
   }\r
 \r
-  // \r
+  //\r
   // Following as the above cases, it's safety to remove and create again.\r
   //\r
   Child = UsbFindChild (HubIf, Port);\r
-  \r
+\r
   if (Child != NULL) {\r
     DEBUG (( EFI_D_INFO, "UsbEnumeratePort: device at port %d removed from root hub %p\n", Port, HubIf));\r
     UsbRemoveDevice (Child);\r
   }\r
-  \r
+\r
   if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {\r
     //\r
-    // Now, new device connected, enumerate and configure the device \r
+    // Now, new device connected, enumerate and configure the device\r
     //\r
     DEBUG (( EFI_D_INFO, "UsbEnumeratePort: new device connected at port %d\n", Port));\r
-    Status = UsbEnumerateNewDev (HubIf, Port);\r
-  \r
+    if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
+      Status = UsbEnumerateNewDev (HubIf, Port, FALSE);\r
+    } else {\r
+      Status = UsbEnumerateNewDev (HubIf, Port, TRUE);\r
+    }\r
+\r
   } else {\r
     DEBUG (( EFI_D_INFO, "UsbEnumeratePort: device disconnected event on port %d\n", Port));\r
   }\r
-  \r
+\r
   HubApi->ClearPortChange (HubIf, Port);\r
   return Status;\r
 }\r
@@ -994,7 +1017,7 @@ UsbHubEnumeration (
   UINT8                   Bit;\r
   UINT8                   Index;\r
   USB_DEVICE              *Child;\r
-  \r
+\r
   ASSERT (Context != NULL);\r
 \r
   HubIf = (USB_INTERFACE *) Context;\r
@@ -1059,7 +1082,7 @@ UsbRootHubEnumeration (
       DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from root hub %p, try again\n", Index, RootHub));\r
       UsbRemoveDevice (Child);\r
     }\r
-    \r
+\r
     UsbEnumeratePort (RootHub, Index);\r
   }\r
 }\r