EFI_HANDLE *DeviceHandleBuffer;\r
UINTN DeviceHandleCount;\r
UINTN Index;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;\r
\r
//\r
- // Get the list of all the handles in the handle database.\r
- // If there is an error getting the list, then the unload\r
- // operation fails.\r
+ // Get the list of the device handles managed by this driver.\r
+ // If there is an error getting the list, then means the driver\r
+ // doesn't manage any device. At this way, we would only close\r
+ // those protocols installed at image handle.\r
//\r
+ DeviceHandleBuffer = NULL;\r
Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
+ ByProtocol,\r
+ &gEfiCallerIdGuid,\r
NULL,\r
&DeviceHandleCount,\r
&DeviceHandleBuffer\r
);\r
\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Disconnect the driver specified by ImageHandle from all\r
+ // the devices in the handle database.\r
+ //\r
+ for (Index = 0; Index < DeviceHandleCount; Index++) {\r
+ Status = gBS->DisconnectController (\r
+ DeviceHandleBuffer[Index],\r
+ ImageHandle,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto EXIT;\r
+ }\r
+ }\r
}\r
\r
//\r
- // Disconnect the driver specified by ImageHandle from all\r
- // the devices in the handle database.\r
+ // Uninstall all the protocols installed in the driver entry point\r
//\r
- for (Index = 0; Index < DeviceHandleCount; Index++) {\r
- Status = gBS->DisconnectController (\r
- DeviceHandleBuffer[Index],\r
- ImageHandle,\r
- NULL\r
- );\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ ImageHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ &gNvmExpressDriverBinding,\r
+ &gEfiDriverSupportedEfiVersionProtocolGuid,\r
+ &gNvmExpressDriverSupportedEfiVersion,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto EXIT;\r
}\r
\r
//\r
- // Uninstall all the protocols installed in the driver entry point\r
+ // Note we have to one by one uninstall the following protocols.\r
+ // It's because some of them are optionally installed based on\r
+ // the following PCD settings.\r
+ // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable\r
+ // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable\r
+ // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable\r
+ // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable\r
//\r
- for (Index = 0; Index < DeviceHandleCount; Index++) {\r
- Status = gBS->HandleProtocol (\r
- DeviceHandleBuffer[Index],\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBinding\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (DriverBinding->ImageHandle != ImageHandle) {\r
- continue;\r
- }\r
-\r
+ Status = gBS->HandleProtocol (\r
+ ImageHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ (VOID **) &ComponentName\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
gBS->UninstallProtocolInterface (\r
ImageHandle,\r
- &gEfiDriverBindingProtocolGuid,\r
- DriverBinding\r
+ &gEfiComponentNameProtocolGuid,\r
+ ComponentName\r
);\r
+ }\r
\r
- Status = gBS->HandleProtocol (\r
- DeviceHandleBuffer[Index],\r
- &gEfiComponentNameProtocolGuid,\r
- (VOID **) &ComponentName\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- gBS->UninstallProtocolInterface (\r
- ImageHandle,\r
- &gEfiComponentNameProtocolGuid,\r
- ComponentName\r
- );\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- DeviceHandleBuffer[Index],\r
- &gEfiComponentName2ProtocolGuid,\r
- (VOID **) &ComponentName2\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- gBS->UninstallProtocolInterface (\r
- ImageHandle,\r
- &gEfiComponentName2ProtocolGuid,\r
- ComponentName2\r
- );\r
- }\r
+ Status = gBS->HandleProtocol (\r
+ ImageHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ (VOID **) &ComponentName2\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->UninstallProtocolInterface (\r
+ ImageHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ ComponentName2\r
+ );\r
}\r
\r
+ Status = EFI_SUCCESS;\r
+\r
+EXIT:\r
//\r
// Free the buffer containing the list of handles from the handle database\r
//\r
if (DeviceHandleBuffer != NULL) {\r
gBS->FreePool (DeviceHandleBuffer);\r
}\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
/**\r