summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2017-09-03 15:21:59 +0200
committerLaszlo Ersek <lersek@redhat.com>2017-09-08 20:22:38 +0200
commit6fb8ddd36bde45614b0a069528cdc97077835a74 (patch)
treeab2cb3039ac3d50e50aa67f434cdc2152810f84b /MdeModulePkg/Bus
parent509daa658b79b21eb1ccd6230065867e22707a42 (diff)
downloadedk2-6fb8ddd36bde45614b0a069528cdc97077835a74.tar.gz
edk2-6fb8ddd36bde45614b0a069528cdc97077835a74.tar.bz2
edk2-6fb8ddd36bde45614b0a069528cdc97077835a74.zip
MdeModulePkg/AtaAtapiPassThru: disable the device at ExitBootServices()
The AtaAtapiPassThru driver maps three system memory regions for Bus Master Common Buffer operation on the following call path, if the controller has PCI_CLASS_MASS_STORAGE_SATADPA class code: AtaAtapiPassThruStart() EnumerateAttachedDevice() AhciModeInitialization() AhciCreateTransferDescriptor() The device is disabled (including Bus Master DMA) when the controller is unbound, in AtaAtapiPassThruStop(). Then the regions are unmapped. The former step should also be done when we exit the boot services, and the OS gains ownership of system memory. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Star Zeng <star.zeng@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c59
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h6
2 files changed, 64 insertions, 1 deletions
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
index a48b295d26..09064dda18 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
@@ -104,7 +104,8 @@ ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
{ // NonBlocking TaskList
NULL,
NULL
- }
+ },
+ NULL, // ExitBootEvent
};
ATAPI_DEVICE_PATH mAtapiDevicePathTemplate = {
@@ -479,6 +480,38 @@ InitializeAtaAtapiPassThru (
}
/**
+ Disable the device (especially Bus Master DMA) when exiting the boot
+ services.
+
+ @param[in] Event Event for which this notification function is being
+ called.
+ @param[in] Context Pointer to the ATA_ATAPI_PASS_THRU_INSTANCE that
+ represents the HBA.
+**/
+VOID
+EFIAPI
+AtaPassThruExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
+
+ Instance = Context;
+ PciIo = Instance->PciIo;
+
+ PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationDisable,
+ Instance->EnabledPciAttributes,
+ NULL
+ );
+}
+
+/**
Tests to see if this driver supports a given controller. If a child device is provided,
it further tests to see if this driver supports creating a handle for the specified child device.
@@ -757,6 +790,17 @@ AtaAtapiPassThruStart (
InitializeListHead(&Instance->DeviceList);
InitializeListHead(&Instance->NonBlockingTaskList);
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ AtaPassThruExitBootServices,
+ Instance,
+ &Instance->ExitBootEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
Instance->TimerEvent = NULL;
Status = gBS->CreateEvent (
@@ -810,6 +854,10 @@ ErrorExit:
gBS->CloseEvent (Instance->TimerEvent);
}
+ if ((Instance != NULL) && (Instance->ExitBootEvent != NULL)) {
+ gBS->CloseEvent (Instance->ExitBootEvent);
+ }
+
//
// Remove all inserted ATA devices.
//
@@ -908,6 +956,15 @@ AtaAtapiPassThruStop (
Instance->TimerEvent = NULL;
}
DestroyAsynTaskList (Instance, FALSE);
+
+ //
+ // Close event signaled at gBS->ExitBootServices().
+ //
+ if (Instance->ExitBootEvent != NULL) {
+ gBS->CloseEvent (Instance->ExitBootEvent);
+ Instance->ExitBootEvent = NULL;
+ }
+
//
// Free allocated resource
//
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
index 85e5a55539..8d6eac706c 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
@@ -121,6 +121,12 @@ typedef struct {
//
EFI_EVENT TimerEvent;
LIST_ENTRY NonBlockingTaskList;
+
+ //
+ // For disabling the device (especially Bus Master DMA) at
+ // ExitBootServices().
+ //
+ EFI_EVENT ExitBootEvent;
} ATA_ATAPI_PASS_THRU_INSTANCE;
//