]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeMdeModulePkg/UsbBusDxe: If DisconnectController() returns an error the USB Bus...
authorFeng Tian <feng.tian@intel.com>
Wed, 30 Oct 2013 03:49:24 +0000 (03:49 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 30 Oct 2013 03:49:24 +0000 (03:49 +0000)
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14819 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c

index d503a278a496f1c1facb5dc2ed22570ecb1c4bf2..9ede83ab7e611b09922c8d2653d73ac07140d4ff 100644 (file)
@@ -198,6 +198,7 @@ struct _USB_DEVICE {
   USB_INTERFACE             *ParentIf;\r
   UINT8                     ParentPort;       // Start at 0\r
   UINT8                     Tier;\r
+  BOOLEAN                   DisconnectFail;\r
 };\r
 \r
 //\r
index 79635cb1862cc01389161501cca8a6007c852547..430f5aa3dc643934e0c7a5415040da20c4167c9c 100644 (file)
@@ -450,7 +450,7 @@ UsbSelectConfig (
   @param  UsbIf                 The interface to disconnect driver from.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 UsbDisconnectDriver (\r
   IN USB_INTERFACE        *UsbIf\r
   )\r
@@ -462,8 +462,9 @@ UsbDisconnectDriver (
   // Release the hub if it's a hub controller, otherwise\r
   // disconnect the driver if it is managed by other drivers.\r
   //\r
+  Status = EFI_SUCCESS;\r
   if (UsbIf->IsHub) {\r
-    UsbIf->HubApi->Release (UsbIf);\r
+    Status = UsbIf->HubApi->Release (UsbIf);\r
 \r
   } else if (UsbIf->IsManaged) {\r
     //\r
@@ -479,13 +480,17 @@ UsbDisconnectDriver (
     gBS->RestoreTPL (TPL_CALLBACK);\r
 \r
     Status = gBS->DisconnectController (UsbIf->Handle, NULL, NULL);\r
-    UsbIf->IsManaged = FALSE;\r
-\r
+    if (!EFI_ERROR (Status)) {\r
+      UsbIf->IsManaged = FALSE;\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
+  return Status;\r
 }\r
 \r
 \r
@@ -495,17 +500,20 @@ UsbDisconnectDriver (
   @param  Device                The USB device to remove configuration from.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 UsbRemoveConfig (\r
   IN USB_DEVICE           *Device\r
   )\r
 {\r
   USB_INTERFACE           *UsbIf;\r
   UINTN                   Index;\r
+  EFI_STATUS              Status;\r
+  EFI_STATUS              ReturnStatus;\r
 \r
   //\r
   // Remove each interface of the device\r
   //\r
+  ReturnStatus = EFI_SUCCESS;\r
   for (Index = 0; Index < Device->NumOfInterface; Index++) {    \r
     ASSERT (Index < USB_MAX_INTERFACE);\r
     UsbIf = Device->Interfaces[Index];\r
@@ -514,13 +522,17 @@ UsbRemoveConfig (
       continue;\r
     }\r
 \r
-    UsbDisconnectDriver (UsbIf);\r
-    UsbFreeInterface (UsbIf);\r
-    Device->Interfaces[Index] = NULL;\r
+    Status = UsbDisconnectDriver (UsbIf);\r
+    if (!EFI_ERROR (Status)) {\r
+      UsbFreeInterface (UsbIf);\r
+      Device->Interfaces[Index] = NULL;\r
+    } else {\r
+      ReturnStatus = Status;\r
+    }\r
   }\r
 \r
   Device->ActiveConfig    = NULL;\r
-  Device->NumOfInterface  = 0;\r
+  return ReturnStatus;\r
 }\r
 \r
 \r
@@ -540,6 +552,7 @@ UsbRemoveDevice (
   USB_BUS                 *Bus;\r
   USB_DEVICE              *Child;\r
   EFI_STATUS              Status;\r
+  EFI_STATUS              ReturnStatus;\r
   UINTN                   Index;\r
 \r
   Bus = Device->Bus;\r
@@ -548,6 +561,7 @@ UsbRemoveDevice (
   // Remove all the devices on its downstream ports. Search from devices[1].\r
   // Devices[0] is the root hub.\r
   //\r
+  ReturnStatus = EFI_SUCCESS;\r
   for (Index = 1; Index < Bus->MaxDevices; Index++) {\r
     Child = Bus->Devices[Index];\r
 \r
@@ -557,21 +571,31 @@ UsbRemoveDevice (
 \r
     Status = UsbRemoveDevice (Child);\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "UsbRemoveDevice: failed to remove child, ignore error\n"));\r
+    if (!EFI_ERROR (Status)) {\r
       Bus->Devices[Index] = NULL;\r
+    } else {\r
+      Bus->Devices[Index]->DisconnectFail = TRUE;\r
+      ReturnStatus = Status;\r
+      DEBUG ((EFI_D_INFO, "UsbRemoveDevice: failed to remove child %p at parent %p\n", Child, Device));\r
     }\r
   }\r
 \r
-  UsbRemoveConfig (Device);\r
+  if (EFI_ERROR (ReturnStatus)) {\r
+    return ReturnStatus;\r
+  }\r
 \r
-  DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));\r
+  Status = UsbRemoveConfig (Device);\r
 \r
-  ASSERT (Device->Address < Bus->MaxDevices);\r
-  Bus->Devices[Device->Address] = NULL;\r
-  UsbFreeDevice (Device);\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));\r
 \r
-  return EFI_SUCCESS;\r
+    ASSERT (Device->Address < Bus->MaxDevices);\r
+    Bus->Devices[Device->Address] = NULL;\r
+    UsbFreeDevice (Device);\r
+  } else {\r
+    Bus->Devices[Device->Address]->DisconnectFail = TRUE;\r
+  }\r
+  return Status;\r
 }\r
 \r
 \r
@@ -968,11 +992,20 @@ UsbHubEnumeration (
   UINT8                   Byte;\r
   UINT8                   Bit;\r
   UINT8                   Index;\r
-\r
+  USB_DEVICE              *Child;\r
+  \r
   ASSERT (Context != NULL);\r
 \r
   HubIf = (USB_INTERFACE *) Context;\r
 \r
+  for (Index = 0; Index < HubIf->NumOfPort; Index++) {\r
+    Child = UsbFindChild (HubIf, Index);\r
+    if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {\r
+      DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from hub %p, try again\n", Index, HubIf));\r
+      UsbRemoveDevice (Child);\r
+    }\r
+  }\r
+\r
   if (HubIf->ChangeMap == NULL) {\r
     return ;\r
   }\r
@@ -1015,10 +1048,17 @@ UsbRootHubEnumeration (
 {\r
   USB_INTERFACE           *RootHub;\r
   UINT8                   Index;\r
+  USB_DEVICE              *Child;\r
 \r
   RootHub = (USB_INTERFACE *) Context;\r
 \r
   for (Index = 0; Index < RootHub->NumOfPort; Index++) {\r
+    Child = UsbFindChild (RootHub, Index);\r
+    if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {\r
+      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
     UsbEnumeratePort (RootHub, Index);\r
   }\r
 }\r
index 288d38f634393cafacf97732faeae656a44e6e10..ef7d4409173f4735f0801bc00a401a68b10be96e 100644 (file)
@@ -151,7 +151,7 @@ UsbSelectConfig (
   @return None.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 UsbRemoveConfig (\r
   IN USB_DEVICE           *Device\r
   );\r
index 9e5299c0ef81ec6003bec64db0bae0f0a8dfdae3..2fcacad46e468d2f0fc5f90bf3d06d696ac33509 100644 (file)
@@ -988,6 +988,10 @@ UsbHubResetPort (
   for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {\r
     Status = UsbHubGetPortStatus (HubIf, Port, &PortState);\r
 \r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
     if (!EFI_ERROR (Status) &&\r
         USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
       gBS->Stall (USB_SET_PORT_RECOVERY_STALL);\r