--- /dev/null
+/** @file\r
+ EFI Driver Model Library.\r
+\r
+ Copyright (c) 2006, Intel Corporation<BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ Module Name: UefiDriverModelLib.c\r
+\r
+**/\r
+\r
+\r
+\r
+/**\r
+ The constructor function installs the standard EFI Driver Model Protocols.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The constructor always return EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiDriverModelLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_HANDLE DriverBindingHandle;\r
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
+\r
+ //\r
+ // If no Driver Binding Protocols are advertised by the driver then simply return\r
+ //\r
+ if (_gDriverModelProtocolListEntries == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Install the first Driver Bindng Protocol onto ImageHandle\r
+ //\r
+ DriverBindingHandle = ImageHandle;\r
+\r
+ //\r
+ // See if onle one Driver Binding Protocol is advertised by the driver\r
+ //\r
+ if (_gDriverModelProtocolListEntries == 1) {\r
+ //\r
+ // The Driver Binding Protocol must never be NULL\r
+ //\r
+ ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);\r
+\r
+ //\r
+ // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol\r
+ // These are all checks against const pointers, so the optimizing compiler will only select one of the\r
+ // calls to InstallMultipleProtocolInterfaces()\r
+ //\r
+ if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {\r
+ if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ NULL\r
+ );\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // ASSERT if the call to InstallMultipleProtocolInterfaces() failed\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol\r
+ //\r
+ DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding;\r
+ DriverBinding->ImageHandle = ImageHandle;\r
+ DriverBinding->DriverBindingHandle = DriverBindingHandle;\r
+\r
+ } else {\r
+ for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {\r
+ //\r
+ // The Driver Binding Protocol must never be NULL\r
+ //\r
+ ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);\r
+\r
+ //\r
+ // Install the Driver Binding Protocol and ASSERT() if the installation fails\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol\r
+ //\r
+ DriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding;\r
+ DriverBinding->ImageHandle = ImageHandle;\r
+ DriverBinding->DriverBindingHandle = DriverBindingHandle;\r
+\r
+ //\r
+ // If Component Name Protocol is specified then install it and ASSERT() if the installation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].ComponentName != NULL) {\r
+ Status = gBS->InstallProtocolInterface (\r
+ &DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // If Driver Configuration Protocol is specified then install it and ASSERT() if the installation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {\r
+ Status = gBS->InstallProtocolInterface (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverConfigurationProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // If Driver Diagnostics Protocol is specified then install it and ASSERT() if the installation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {\r
+ Status = gBS->InstallProtocolInterface (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverDiagnosticsProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Install subsequent Driver Bindng Protocols onto new handles\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ The destructor function uninstalls the standard EFI Driver Model Protocols.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The destructor always return EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiDriverModelLibDestructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_HANDLE DriverBindingHandle;\r
+\r
+ //\r
+ // If no Driver Binding Protocols are advertised by the driver then simply return\r
+ //\r
+ if (_gDriverModelProtocolListEntries == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // See if onle one Driver Binding Protocol is advertised by the driver\r
+ //\r
+ if (_gDriverModelProtocolListEntries == 1) {\r
+ //\r
+ // The Driver Binding Protocol must never be NULL\r
+ //\r
+ ASSERT(_gDriverModelProtocolList[0].DriverBinding != NULL);\r
+\r
+ //\r
+ // Retrieve the DriverBindingHandle from the Driver Binding Protocol\r
+ //\r
+ DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;\r
+\r
+ //\r
+ // Check for all 8 possible combinations of the ComponentName, DriverConfiguration, and DriverDiagnostics Protocol\r
+ // These are all checks against const pointers, so the optimizing compiler will only select one of the\r
+ // calls to InstallMultipleProtocolInterfaces()\r
+ //\r
+ if (_gDriverModelProtocolList[0].DriverDiagnostics == NULL) {\r
+ if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ NULL\r
+ );\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].DriverConfiguration == NULL) {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ }\r
+ } else {\r
+ if (_gDriverModelProtocolList[0].ComponentName == NULL) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ &DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid, (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[0].DriverBinding,\r
+ &gEfiComponentNameProtocolGuid, (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[0].ComponentName,\r
+ &gEfiDriverConfigurationProtocolGuid, (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[0].DriverConfiguration,\r
+ &gEfiDriverDiagnosticsProtocolGuid, (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[0].DriverDiagnostics,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // ASSERT if the call to UninstallMultipleProtocolInterfaces() failed\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+ } else {\r
+ for (Index = 0; Index < _gDriverModelProtocolListEntries; Index++) {\r
+ //\r
+ // The Driver Binding Protocol must never be NULL\r
+ //\r
+ ASSERT(_gDriverModelProtocolList[Index].DriverBinding != NULL);\r
+\r
+ //\r
+ // Retrieve the DriverBindingHandle from the Driver Binding Protocol\r
+ //\r
+ DriverBindingHandle = _gDriverModelProtocolList[0].DriverBinding->DriverBindingHandle;\r
+\r
+ //\r
+ // Uninstall the Driver Binding Protocol and ASSERT() if the installation fails\r
+ //\r
+ Status = gBS->UninstallProtocolInterface (\r
+ DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ (EFI_DRIVER_BINDING_PROTOCOL *)_gDriverModelProtocolList[Index].DriverBinding\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // If Component Name Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_COMPONENT_NAME_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].ComponentName != NULL) {\r
+ Status = gBS->UninstallProtocolInterface (\r
+ DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ (EFI_COMPONENT_NAME_PROTOCOL *)_gDriverModelProtocolList[Index].ComponentName\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // If Driver Configuration Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_CONFIGURATION_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].DriverConfiguration != NULL) {\r
+ Status = gBS->UninstallProtocolInterface (\r
+ DriverBindingHandle,\r
+ &gEfiDriverConfigurationProtocolGuid,\r
+ (EFI_DRIVER_CONFIGURATION_PROTOCOL *)_gDriverModelProtocolList[Index].DriverConfiguration\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // If Driver Diagnostics Protocol is specified then uninstall it and ASSERT() if the uninstallation fails\r
+ //\r
+ if ((_gDriverModelProtocolBitmask & UEFI_DRIVER_MODEL_LIBRARY_DRIVER_DIAGNOSTICS_PROTOCOL_ENABLED) != 0) {\r
+ if (_gDriverModelProtocolList[Index].DriverDiagnostics != NULL) {\r
+ Status = gBS->UninstallProtocolInterface (\r
+ DriverBindingHandle,\r
+ &gEfiDriverDiagnosticsProtocolGuid,\r
+ (EFI_DRIVER_DIAGNOSTICS_PROTOCOL *)_gDriverModelProtocolList[Index].DriverDiagnostics\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r