@param UsbIf The interface to disconnect driver from.\r
\r
**/\r
-VOID\r
+EFI_STATUS\r
UsbDisconnectDriver (\r
IN USB_INTERFACE *UsbIf\r
)\r
// 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
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
@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
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
USB_BUS *Bus;\r
USB_DEVICE *Child;\r
EFI_STATUS Status;\r
+ EFI_STATUS ReturnStatus;\r
UINTN Index;\r
\r
Bus = Device->Bus;\r
// 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
\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
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
{\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