From e2f27a8c5363f7be96db1abcf261c7d0265f5308 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 29 Apr 2013 12:16:46 +0200 Subject: [PATCH] Enforce disabling of firmware disk drivers when native drivers kick in. --- ChangeLog | 4 ++++ grub-core/bus/usb/ehci.c | 4 ++++ grub-core/bus/usb/ohci.c | 4 ++++ grub-core/bus/usb/uhci.c | 2 ++ grub-core/disk/ahci.c | 13 +------------ grub-core/disk/efi/efidisk.c | 19 ++++++++++++------- grub-core/disk/ieee1275/ofdisk.c | 18 ++++++++++-------- grub-core/disk/pata.c | 8 +------- include/grub/disk.h | 14 ++++++++++++++ 9 files changed, 52 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ba588d32..1dea1aa8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-29 Vladimir Serbinenko + + Enforce disabling of firmware disk drivers when native drivers kick in. + 2013-04-29 Vladimir Serbinenko * grub-core/commands/nativedisk.c: Customize the list of modules on diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c index d18a87f8e..9294445d3 100644 --- a/grub-core/bus/usb/ehci.c +++ b/grub-core/bus/usb/ehci.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -1909,6 +1910,9 @@ GRUB_MOD_INIT (ehci) { COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_td) == 64); COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_qh) == 96); + + grub_stop_disk_firmware (); + grub_boot_time ("Initing EHCI hardware"); grub_ehci_inithw (); grub_boot_time ("Registering EHCI driver"); diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 2f3fd91fb..3be5c8d73 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -1442,6 +1443,9 @@ GRUB_MOD_INIT(ohci) { COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_td) == 32); COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_ed) == 16); + + grub_stop_disk_firmware (); + grub_ohci_inithw (); grub_usb_controller_dev_register (&usb_controller); fini_hnd = grub_loader_register_preboot_hook (grub_ohci_fini_hw, diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index a31463735..c2e2e7efe 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -866,6 +866,8 @@ static struct grub_usb_controller_dev usb_controller = GRUB_MOD_INIT(uhci) { + grub_stop_disk_firmware (); + grub_uhci_inithw (); grub_usb_controller_dev_register (&usb_controller); grub_dprintf ("uhci", "registered\n"); diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index e6170426e..554fcc55f 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -183,11 +183,6 @@ grub_ahci_pciinit (grub_pci_device_t dev, if (class >> 8 != 0x010601) return 0; -#ifdef GRUB_MACHINE_QEMU - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, 0x107); -#endif - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG5); #ifdef GRUB_MACHINE_QEMU @@ -1102,13 +1097,7 @@ static struct grub_preboot *fini_hnd; GRUB_MOD_INIT(ahci) { - /* To prevent two drivers operating on the same disks. */ - grub_disk_firmware_is_tainted = 1; - if (grub_disk_firmware_fini) - { - grub_disk_firmware_fini (); - grub_disk_firmware_fini = NULL; - } + grub_stop_disk_firmware (); /* AHCI initialization. */ grub_ahci_initialize (); diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index e168d07fa..ebd906e7c 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -623,22 +623,27 @@ static struct grub_disk_dev grub_efidisk_dev = .next = 0 }; -void -grub_efidisk_init (void) -{ - enumerate_disks (); - grub_disk_dev_register (&grub_efidisk_dev); -} - void grub_efidisk_fini (void) { free_devices (fd_devices); free_devices (hd_devices); free_devices (cd_devices); + fd_devices = 0; + hd_devices = 0; + cd_devices = 0; grub_disk_dev_unregister (&grub_efidisk_dev); } +void +grub_efidisk_init (void) +{ + grub_disk_firmware_fini = grub_efidisk_fini; + + enumerate_disks (); + grub_disk_dev_register (&grub_efidisk_dev); +} + /* Some utility functions to map GRUB devices with EFI devices. */ grub_efi_handle_t grub_efidisk_get_device_handle (grub_disk_t disk) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index ec92c4d10..2a31ecdb1 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -549,14 +549,6 @@ insert_bootpath (void) grub_free (bootpath); } -void -grub_ofdisk_init (void) -{ - insert_bootpath (); - - grub_disk_dev_register (&grub_ofdisk_dev); -} - void grub_ofdisk_fini (void) { @@ -568,6 +560,16 @@ grub_ofdisk_fini (void) grub_disk_dev_unregister (&grub_ofdisk_dev); } +void +grub_ofdisk_init (void) +{ + grub_disk_firmware_fini = grub_ofdisk_fini; + + insert_bootpath (); + + grub_disk_dev_register (&grub_ofdisk_dev); +} + grub_err_t grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size) { diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 75e5deb61..8c4b27b7e 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -530,13 +530,7 @@ static struct grub_ata_dev grub_pata_dev = GRUB_MOD_INIT(ata_pthru) { - /* To prevent two drivers operating on the same disks. */ - grub_disk_firmware_is_tainted = 1; - if (grub_disk_firmware_fini) - { - grub_disk_firmware_fini (); - grub_disk_firmware_fini = NULL; - } + grub_stop_disk_firmware (); /* ATA initialization. */ grub_pata_initialize (); diff --git a/include/grub/disk.h b/include/grub/disk.h index d19b1ac96..8fa09a6df 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -25,6 +25,8 @@ #include #include #include +/* For NULL. */ +#include /* These are used to set a device id. When you add a new disk device, you must define a new id for it here. */ @@ -205,6 +207,18 @@ EXPORT_FUNC(grub_disk_cache_get_performance) (unsigned long *hits, unsigned long extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void); extern int EXPORT_VAR(grub_disk_firmware_is_tainted); +static inline void +grub_stop_disk_firmware (void) +{ + /* To prevent two drivers operating on the same disks. */ + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) + { + grub_disk_firmware_fini (); + grub_disk_firmware_fini = NULL; + } +} + #if defined (GRUB_UTIL) void grub_lvm_init (void); void grub_ldm_init (void);