From 0a2326aff75d4581dfc526f9011ad004d8b7af72 Mon Sep 17 00:00:00 2001 From: Feng Tian Date: Fri, 10 Jan 2014 07:15:52 +0000 Subject: =?UTF-8?q?MdeModulePkg/NvmExpressDxe:=20Fix=20a=20bug=20in=20NvmE?= =?UTF-8?q?xpressDxe=20driver=E2=80=99s=20Unload()=20that=20forget=20to=20?= =?UTF-8?q?uninstall=20the=20DriverSupportedEfiVersionProtocol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Feng Tian Reviewed-by: Elvin Li git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15090 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c | 125 ++++++++++++------------ 1 file changed, 65 insertions(+), 60 deletions(-) (limited to 'MdeModulePkg/Bus/Pci') diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c index 4f187e3abb..ee40ba05c9 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c @@ -928,97 +928,102 @@ NvmExpressUnload ( EFI_HANDLE *DeviceHandleBuffer; UINTN DeviceHandleCount; UINTN Index; - EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; EFI_COMPONENT_NAME_PROTOCOL *ComponentName; EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; // - // Get the list of all the handles in the handle database. - // If there is an error getting the list, then the unload - // operation fails. + // Get the list of the device handles managed by this driver. + // If there is an error getting the list, then means the driver + // doesn't manage any device. At this way, we would only close + // those protocols installed at image handle. // + DeviceHandleBuffer = NULL; Status = gBS->LocateHandleBuffer ( - AllHandles, - NULL, + ByProtocol, + &gEfiCallerIdGuid, NULL, &DeviceHandleCount, &DeviceHandleBuffer ); - if (EFI_ERROR (Status)) { - return Status; + if (!EFI_ERROR (Status)) { + // + // Disconnect the driver specified by ImageHandle from all + // the devices in the handle database. + // + for (Index = 0; Index < DeviceHandleCount; Index++) { + Status = gBS->DisconnectController ( + DeviceHandleBuffer[Index], + ImageHandle, + NULL + ); + if (EFI_ERROR (Status)) { + goto EXIT; + } + } } // - // Disconnect the driver specified by ImageHandle from all - // the devices in the handle database. + // Uninstall all the protocols installed in the driver entry point // - for (Index = 0; Index < DeviceHandleCount; Index++) { - Status = gBS->DisconnectController ( - DeviceHandleBuffer[Index], - ImageHandle, - NULL - ); + Status = gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gNvmExpressDriverBinding, + &gEfiDriverSupportedEfiVersionProtocolGuid, + &gNvmExpressDriverSupportedEfiVersion, + NULL + ); + + if (EFI_ERROR (Status)) { + goto EXIT; } // - // Uninstall all the protocols installed in the driver entry point + // Note we have to one by one uninstall the following protocols. + // It's because some of them are optionally installed based on + // the following PCD settings. + // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable + // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable + // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable + // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable // - for (Index = 0; Index < DeviceHandleCount; Index++) { - Status = gBS->HandleProtocol ( - DeviceHandleBuffer[Index], - &gEfiDriverBindingProtocolGuid, - (VOID **) &DriverBinding - ); - - if (EFI_ERROR (Status)) { - continue; - } - - if (DriverBinding->ImageHandle != ImageHandle) { - continue; - } - + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiComponentNameProtocolGuid, + (VOID **) &ComponentName + ); + if (!EFI_ERROR (Status)) { gBS->UninstallProtocolInterface ( ImageHandle, - &gEfiDriverBindingProtocolGuid, - DriverBinding + &gEfiComponentNameProtocolGuid, + ComponentName ); + } - Status = gBS->HandleProtocol ( - DeviceHandleBuffer[Index], - &gEfiComponentNameProtocolGuid, - (VOID **) &ComponentName - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentNameProtocolGuid, - ComponentName - ); - } - - Status = gBS->HandleProtocol ( - DeviceHandleBuffer[Index], - &gEfiComponentName2ProtocolGuid, - (VOID **) &ComponentName2 - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentName2ProtocolGuid, - ComponentName2 - ); - } + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiComponentName2ProtocolGuid, + (VOID **) &ComponentName2 + ); + if (!EFI_ERROR (Status)) { + gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiComponentName2ProtocolGuid, + ComponentName2 + ); } + Status = EFI_SUCCESS; + +EXIT: // // Free the buffer containing the list of handles from the handle database // if (DeviceHandleBuffer != NULL) { gBS->FreePool (DeviceHandleBuffer); } - return EFI_SUCCESS; + return Status; } /** -- cgit v1.2.3