From 0f58371b5df22ca7894b0febd09d0c95b02da1f0 Mon Sep 17 00:00:00 2001 From: Feng Tian Date: Tue, 3 Dec 2013 07:04:08 +0000 Subject: [PATCH] MdeModulePkg/Usb: All h/w related stop operation at DriverBindingStop() should be behind s/w related stop operation, which could avoid h/w not working if s/w stop operation fails. Signed-off-by: Feng Tian Reviewed-by: Elvin Li git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14927 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c | 14 ++--- MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c | 17 ++++-- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 25 ++++---- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c | 81 ++++++++++++++----------- 4 files changed, 75 insertions(+), 62 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index 59891b814a..700e69e495 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -2049,13 +2049,6 @@ EhcDriverBindingStop ( Ehc = EHC_FROM_THIS (Usb2Hc); PciIo = Ehc->PciIo; - // - // Stop AsyncRequest Polling timer then stop the EHCI driver - // and uninstall the EHCI protocl. - // - gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL); - EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); - Status = gBS->UninstallProtocolInterface ( Controller, &gEfiUsb2HcProtocolGuid, @@ -2066,6 +2059,13 @@ EhcDriverBindingStop ( return Status; } + // + // Stop AsyncRequest Polling timer then stop the EHCI driver + // and uninstall the EHCI protocl. + // + gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL); + EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); + if (Ehc->PollTimer != NULL) { gBS->CloseEvent (Ehc->PollTimer); } diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c index 00a1094376..a3a28f3edc 100644 --- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c +++ b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c @@ -1550,19 +1550,24 @@ UhciCleanDevUp ( ) { USB_HC_DEV *Uhc; + EFI_STATUS Status; // // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller // Uhc = UHC_FROM_USB2_HC_PROTO (This); - UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - &Uhc->Usb2Hc - ); + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiUsb2HcProtocolGuid, + &Uhc->Usb2Hc + ); + if (EFI_ERROR (Status)) { + return ; + } + + UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); UhciFreeAllAsyncReq (Uhc); UhciDestoryFrameList (Uhc); diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c index 5ca58fbb9e..7546143ba5 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c @@ -2129,6 +2129,16 @@ XhcDriverBindingStop ( return Status; } + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiUsb2HcProtocolGuid, + Usb2Hc + ); + + if (EFI_ERROR (Status)) { + return Status; + } + Xhc = XHC_FROM_THIS (Usb2Hc); PciIo = Xhc->PciIo; @@ -2154,19 +2164,6 @@ XhcDriverBindingStop ( } } - XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - XhcClearBiosOwnership (Xhc); - - Status = gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - Usb2Hc - ); - - if (EFI_ERROR (Status)) { - return Status; - } - if (Xhc->PollTimer != NULL) { gBS->CloseEvent (Xhc->PollTimer); } @@ -2175,6 +2172,8 @@ XhcDriverBindingStop ( gBS->CloseEvent (Xhc->ExitBootServiceEvent); } + XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); + XhcClearBiosOwnership (Xhc); XhciDelAllAsyncIntTransfers (Xhc); XhcFreeSched (Xhc); diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c index ff6b99c87f..ef002f53bb 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c @@ -1402,6 +1402,7 @@ UsbBusControllerDriverStop ( EFI_TPL OldTpl; UINTN Index; EFI_STATUS Status; + EFI_STATUS ReturnStatus; Status = EFI_SUCCESS; @@ -1411,6 +1412,7 @@ UsbBusControllerDriverStop ( // OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + ReturnStatus = EFI_SUCCESS; for (Index = 0; Index < NumberOfChildren; Index++) { Status = gBS->OpenProtocol ( ChildHandleBuffer[Index], @@ -1434,11 +1436,11 @@ UsbBusControllerDriverStop ( UsbIf = USB_INTERFACE_FROM_USBIO (UsbIo); UsbDev = UsbIf->Device; - UsbRemoveDevice (UsbDev); + ReturnStatus = UsbRemoveDevice (UsbDev); } gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; + return ReturnStatus; } DEBUG (( EFI_D_INFO, "UsbBusStop: usb bus stopped on %p\n", Controller)); @@ -1471,53 +1473,60 @@ UsbBusControllerDriverStop ( RootHub = Bus->Devices[0]; RootIf = RootHub->Interfaces[0]; - mUsbRootHubApi.Release (RootIf); - ASSERT (Bus->MaxDevices <= 256); + ReturnStatus = EFI_SUCCESS; for (Index = 1; Index < Bus->MaxDevices; Index++) { if (Bus->Devices[Index] != NULL) { - UsbRemoveDevice (Bus->Devices[Index]); + Status = UsbRemoveDevice (Bus->Devices[Index]); + if (EFI_ERROR (Status)) { + ReturnStatus = Status; + } } } gBS->RestoreTPL (OldTpl); - gBS->FreePool (RootIf); - gBS->FreePool (RootHub); - Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList); - ASSERT (!EFI_ERROR (Status)); + if (!EFI_ERROR (ReturnStatus)) { + mUsbRootHubApi.Release (RootIf); + gBS->FreePool (RootIf); + gBS->FreePool (RootHub); - // - // Uninstall the bus identifier and close USB_HC/USB2_HC protocols - // - gBS->UninstallProtocolInterface (Controller, &gEfiCallerIdGuid, &Bus->BusId); + Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList); + ASSERT (!EFI_ERROR (Status)); - if (Bus->Usb2Hc != NULL) { - gBS->CloseProtocol ( - Controller, - &gEfiUsb2HcProtocolGuid, - This->DriverBindingHandle, - Controller - ); - } + // + // Uninstall the bus identifier and close USB_HC/USB2_HC protocols + // + gBS->UninstallProtocolInterface (Controller, &gEfiCallerIdGuid, &Bus->BusId); - if (Bus->UsbHc != NULL) { - gBS->CloseProtocol ( - Controller, - &gEfiUsbHcProtocolGuid, - This->DriverBindingHandle, - Controller - ); - } + if (Bus->Usb2Hc != NULL) { + Status = gBS->CloseProtocol ( + Controller, + &gEfiUsb2HcProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); + if (Bus->UsbHc != NULL) { + Status = gBS->CloseProtocol ( + Controller, + &gEfiUsbHcProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } - gBS->FreePool (Bus); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->FreePool (Bus); + } + } return Status; } -- 2.39.2