summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/prefix/efidrvprefix.c
diff options
context:
space:
mode:
authorMichael Brown2015-04-13 13:06:59 +0200
committerMichael Brown2015-04-13 13:06:59 +0200
commit755d2b8f6be681a2e620534b237471b75f28ed8c (patch)
tree588c9462c8ba38b25a99350eb3494ba07ccc02d5 /src/arch/x86/prefix/efidrvprefix.c
parent[crypto] Add SHA-512/224 algorithm (diff)
downloadipxe-755d2b8f6be681a2e620534b237471b75f28ed8c.tar.gz
ipxe-755d2b8f6be681a2e620534b237471b75f28ed8c.tar.xz
ipxe-755d2b8f6be681a2e620534b237471b75f28ed8c.zip
[efi] Ensure drivers are disconnected when ExitBootServices() is called
We hook the UEFI ExitBootServices() event and use it to trigger a call to shutdown_boot(). This does not automatically cause drivers to be disconnected from their devices, since device enumeration is now handled by the UEFI core rather than by iPXE. (Under the old and dubiously compatible device model, iPXE used to perform its own device enumeration and so the call to shutdown_boot() would indeed have caused drivers to be disconnected.) Fix by replicating parts of the dummy "EFI root device" from efiprefix.c to efidrvprefix.c, so that the call to shutdown_boot() will call efi_driver_disconnect_all(). Originally-fixed-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/x86/prefix/efidrvprefix.c')
-rw-r--r--src/arch/x86/prefix/efidrvprefix.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/arch/x86/prefix/efidrvprefix.c b/src/arch/x86/prefix/efidrvprefix.c
index 3daefd00..4fbb19ff 100644
--- a/src/arch/x86/prefix/efidrvprefix.c
+++ b/src/arch/x86/prefix/efidrvprefix.c
@@ -21,7 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdlib.h>
#include <ipxe/init.h>
+#include <ipxe/device.h>
#include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_driver.h>
/**
* EFI entry point
@@ -44,3 +46,36 @@ EFI_STATUS EFIAPI _efidrv_start ( EFI_HANDLE image_handle,
return 0;
}
+
+/**
+ * Probe EFI root bus
+ *
+ * @v rootdev EFI root device
+ */
+static int efi_probe ( struct root_device *rootdev __unused ) {
+
+ /* Do nothing */
+ return 0;
+}
+
+/**
+ * Remove EFI root bus
+ *
+ * @v rootdev EFI root device
+ */
+static void efi_remove ( struct root_device *rootdev __unused ) {
+
+ efi_driver_disconnect_all();
+}
+
+/** EFI root device driver */
+static struct root_driver efi_root_driver = {
+ .probe = efi_probe,
+ .remove = efi_remove,
+};
+
+/** EFI root device */
+struct root_device efi_root_device __root_device = {
+ .dev = { .name = "EFI" },
+ .driver = &efi_root_driver,
+};