Revision: 14819
http://sourceforge.net/p/edk2/code/14819
Author: erictian
Date: 2013-10-30 03:49:24 +0000 (Wed, 30 Oct 2013)
Log Message:
-----------
MdeMdeModulePkg/UsbBusDxe: If DisconnectController() returns an error the USB
Bus Driver would retry the DisconnectController() from a timer event until it
succeeds
Signed-off-by: Feng Tian <[email protected]>
Reviewed-by: Ruiyu Ni <[email protected]>
Modified Paths:
--------------
trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
Modified: trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
===================================================================
--- trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h 2013-10-30 03:10:30 UTC
(rev 14818)
+++ trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h 2013-10-30 03:49:24 UTC
(rev 14819)
@@ -198,6 +198,7 @@
USB_INTERFACE *ParentIf;
UINT8 ParentPort; // Start at 0
UINT8 Tier;
+ BOOLEAN DisconnectFail;
};
//
Modified: trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
===================================================================
--- trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c 2013-10-30
03:10:30 UTC (rev 14818)
+++ trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c 2013-10-30
03:49:24 UTC (rev 14819)
@@ -450,7 +450,7 @@
@param UsbIf The interface to disconnect driver from.
**/
-VOID
+EFI_STATUS
UsbDisconnectDriver (
IN USB_INTERFACE *UsbIf
)
@@ -462,8 +462,9 @@
// Release the hub if it's a hub controller, otherwise
// disconnect the driver if it is managed by other drivers.
//
+ Status = EFI_SUCCESS;
if (UsbIf->IsHub) {
- UsbIf->HubApi->Release (UsbIf);
+ Status = UsbIf->HubApi->Release (UsbIf);
} else if (UsbIf->IsManaged) {
//
@@ -479,13 +480,17 @@
gBS->RestoreTPL (TPL_CALLBACK);
Status = gBS->DisconnectController (UsbIf->Handle, NULL, NULL);
- UsbIf->IsManaged = FALSE;
-
+ if (!EFI_ERROR (Status)) {
+ UsbIf->IsManaged = FALSE;
+ }
+
DEBUG (( EFI_D_INFO, "UsbDisconnectDriver: TPL after disconnect is %d,
%d\n", (UINT32)UsbGetCurrentTpl(), Status));
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
gBS->RaiseTPL (OldTpl);
}
+
+ return Status;
}
@@ -495,17 +500,20 @@
@param Device The USB device to remove configuration from.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
)
{
USB_INTERFACE *UsbIf;
UINTN Index;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
//
// Remove each interface of the device
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 0; Index < Device->NumOfInterface; Index++) {
ASSERT (Index < USB_MAX_INTERFACE);
UsbIf = Device->Interfaces[Index];
@@ -514,13 +522,17 @@
continue;
}
- UsbDisconnectDriver (UsbIf);
- UsbFreeInterface (UsbIf);
- Device->Interfaces[Index] = NULL;
+ Status = UsbDisconnectDriver (UsbIf);
+ if (!EFI_ERROR (Status)) {
+ UsbFreeInterface (UsbIf);
+ Device->Interfaces[Index] = NULL;
+ } else {
+ ReturnStatus = Status;
+ }
}
Device->ActiveConfig = NULL;
- Device->NumOfInterface = 0;
+ return ReturnStatus;
}
@@ -540,6 +552,7 @@
USB_BUS *Bus;
USB_DEVICE *Child;
EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
UINTN Index;
Bus = Device->Bus;
@@ -548,6 +561,7 @@
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 1; Index < Bus->MaxDevices; Index++) {
Child = Bus->Devices[Index];
@@ -557,21 +571,31 @@
Status = UsbRemoveDevice (Child);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "UsbRemoveDevice: failed to remove child, ignore
error\n"));
+ if (!EFI_ERROR (Status)) {
Bus->Devices[Index] = NULL;
+ } else {
+ Bus->Devices[Index]->DisconnectFail = TRUE;
+ ReturnStatus = Status;
+ DEBUG ((EFI_D_INFO, "UsbRemoveDevice: failed to remove child %p at
parent %p\n", Child, Device));
}
}
- UsbRemoveConfig (Device);
+ if (EFI_ERROR (ReturnStatus)) {
+ return ReturnStatus;
+ }
- DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n",
Device->Address));
+ Status = UsbRemoveConfig (Device);
- ASSERT (Device->Address < Bus->MaxDevices);
- Bus->Devices[Device->Address] = NULL;
- UsbFreeDevice (Device);
+ if (!EFI_ERROR (Status)) {
+ DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n",
Device->Address));
- return EFI_SUCCESS;
+ ASSERT (Device->Address < Bus->MaxDevices);
+ Bus->Devices[Device->Address] = NULL;
+ UsbFreeDevice (Device);
+ } else {
+ Bus->Devices[Device->Address]->DisconnectFail = TRUE;
+ }
+ return Status;
}
@@ -968,11 +992,20 @@
UINT8 Byte;
UINT8 Bit;
UINT8 Index;
-
+ USB_DEVICE *Child;
+
ASSERT (Context != NULL);
HubIf = (USB_INTERFACE *) Context;
+ for (Index = 0; Index < HubIf->NumOfPort; Index++) {
+ Child = UsbFindChild (HubIf, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at
port %d from hub %p, try again\n", Index, HubIf));
+ UsbRemoveDevice (Child);
+ }
+ }
+
if (HubIf->ChangeMap == NULL) {
return ;
}
@@ -1015,10 +1048,17 @@
{
USB_INTERFACE *RootHub;
UINT8 Index;
+ USB_DEVICE *Child;
RootHub = (USB_INTERFACE *) Context;
for (Index = 0; Index < RootHub->NumOfPort; Index++) {
+ Child = UsbFindChild (RootHub, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at
port %d from root hub %p, try again\n", Index, RootHub));
+ UsbRemoveDevice (Child);
+ }
+
UsbEnumeratePort (RootHub, Index);
}
}
Modified: trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
===================================================================
--- trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h 2013-10-30
03:10:30 UTC (rev 14818)
+++ trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h 2013-10-30
03:49:24 UTC (rev 14819)
@@ -151,7 +151,7 @@
@return None.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
);
Modified: trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
===================================================================
--- trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c 2013-10-30 03:10:30 UTC
(rev 14818)
+++ trunk/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c 2013-10-30 03:49:24 UTC
(rev 14819)
@@ -988,6 +988,10 @@
for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
if (!EFI_ERROR (Status) &&
USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
gBS->Stall (USB_SET_PORT_RECOVERY_STALL);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits