]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/AtaAtapiPassThru: disable only BM-DMA at ExitBootServices()
authorLaszlo Ersek <lersek@redhat.com>
Thu, 26 Oct 2017 13:48:31 +0000 (15:48 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 27 Oct 2017 16:05:07 +0000 (18:05 +0200)
Clearing I/O port decoding in the PCI command register at
ExitBootServices() breaks IDE boot in Windows, on QEMU's "pc" (i440fx)
machine type. (AHCI boot on "q35" is unaffected.) Windows seems repeatedly
stuck, apparently waiting for a timeout of sorts.

This is arguably a Windows bug; a native OS driver should not expect the
firmware to leave the PCI command register in any particular state.

Strictly speaking, we only need to disable BM-DMA at ExitBootServices(),
in order to abort pending transfers to/from RAM, which is soon to be owned
by the OS. BM-DMA is also the only bit that's explicitly named by the UEFI
Driver Writers' Guide, for clearing at ExitBootServices().

I've verified that clearing only BM-DMA fixes the issue (boot time) on
i440fx, and does not regress q35/AHCI.

Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Dann Frazier <dannf@ubuntu.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Reported-by: Aleksei Kovura <alex3kov@zoho.com>
Reported-by: Dann Frazier <dannf@ubuntu.com>
Reported-by: https://launchpad.net/~cjkrupp
Bisected-by: Dann Frazier <dannf@ubuntu.com>
Bisected-by: https://launchpad.net/~cjkrupp
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Suggested-by: Star Zeng <star.zeng@intel.com>
Ref: https://bugs.launchpad.net/ubuntu/+source/edk2/+bug/1725560
Fixes: 6fb8ddd36bde45614b0a069528cdc97077835a74
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Tested-by: Aleksei Kovura <alex3kov@zoho.com>
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h

index 09064dda18b70753d6a100ad21e9855c90291e78..e10e0d4e65f6b2fb3af03b781adbd1851e622850 100644 (file)
@@ -480,8 +480,7 @@ InitializeAtaAtapiPassThru (
 }\r
 \r
 /**\r
-  Disable the device (especially Bus Master DMA) when exiting the boot\r
-  services.\r
+  Disable Bus Master DMA on the device when exiting the boot services.\r
 \r
   @param[in] Event    Event for which this notification function is being\r
                       called.\r
@@ -506,7 +505,7 @@ AtaPassThruExitBootServices (
   PciIo->Attributes (\r
            PciIo,\r
            EfiPciIoAttributeOperationDisable,\r
-           Instance->EnabledPciAttributes,\r
+           Instance->EnabledPciAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,\r
            NULL\r
            );\r
 }\r
index 8d6eac706c0b7a4294d19b1a80e806ef0f07732e..92c5bf2001cdb30603fb703cf808806c6919d101 100644 (file)
@@ -123,8 +123,7 @@ typedef struct {
   LIST_ENTRY                        NonBlockingTaskList;\r
 \r
   //\r
-  // For disabling the device (especially Bus Master DMA) at\r
-  // ExitBootServices().\r
+  // For disabling Bus Master DMA on the device at ExitBootServices().\r
   //\r
   EFI_EVENT                         ExitBootEvent;\r
 } ATA_ATAPI_PASS_THRU_INSTANCE;\r