]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/AtaAtapiPassThru: disable the device at ExitBootServices()
authorLaszlo Ersek <lersek@redhat.com>
Sun, 3 Sep 2017 13:21:59 +0000 (15:21 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 8 Sep 2017 18:22:38 +0000 (20:22 +0200)
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>
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h

index a48b295d26aad4182641887eac68d5f74ebb1d3b..09064dda18b70753d6a100ad21e9855c90291e78 100644 (file)
@@ -104,7 +104,8 @@ ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
   {                   // NonBlocking TaskList\r
     NULL,\r
     NULL\r
-  }\r
+  },\r
+  NULL,               // ExitBootEvent\r
 };\r
 \r
 ATAPI_DEVICE_PATH    mAtapiDevicePathTemplate = {\r
@@ -478,6 +479,38 @@ InitializeAtaAtapiPassThru (
   return Status;\r
 }\r
 \r
+/**\r
+  Disable the device (especially Bus Master DMA) when exiting the boot\r
+  services.\r
+\r
+  @param[in] Event    Event for which this notification function is being\r
+                      called.\r
+  @param[in] Context  Pointer to the ATA_ATAPI_PASS_THRU_INSTANCE that\r
+                      represents the HBA.\r
+**/\r
+VOID\r
+EFIAPI\r
+AtaPassThruExitBootServices (\r
+  IN EFI_EVENT Event,\r
+  IN VOID      *Context\r
+  )\r
+{\r
+  ATA_ATAPI_PASS_THRU_INSTANCE *Instance;\r
+  EFI_PCI_IO_PROTOCOL          *PciIo;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));\r
+\r
+  Instance = Context;\r
+  PciIo = Instance->PciIo;\r
+\r
+  PciIo->Attributes (\r
+           PciIo,\r
+           EfiPciIoAttributeOperationDisable,\r
+           Instance->EnabledPciAttributes,\r
+           NULL\r
+           );\r
+}\r
+\r
 /**\r
   Tests to see if this driver supports a given controller. If a child device is provided,\r
   it further tests to see if this driver supports creating a handle for the specified child device.\r
@@ -757,6 +790,17 @@ AtaAtapiPassThruStart (
   InitializeListHead(&Instance->DeviceList);\r
   InitializeListHead(&Instance->NonBlockingTaskList);\r
 \r
+  Status = gBS->CreateEvent (\r
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  TPL_CALLBACK,\r
+                  AtaPassThruExitBootServices,\r
+                  Instance,\r
+                  &Instance->ExitBootEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
   Instance->TimerEvent = NULL;\r
 \r
   Status = gBS->CreateEvent (\r
@@ -810,6 +854,10 @@ ErrorExit:
     gBS->CloseEvent (Instance->TimerEvent);\r
   }\r
 \r
+  if ((Instance != NULL) && (Instance->ExitBootEvent != NULL)) {\r
+    gBS->CloseEvent (Instance->ExitBootEvent);\r
+  }\r
+\r
   //\r
   // Remove all inserted ATA devices.\r
   //\r
@@ -908,6 +956,15 @@ AtaAtapiPassThruStop (
     Instance->TimerEvent = NULL;\r
   }\r
   DestroyAsynTaskList (Instance, FALSE);\r
+\r
+  //\r
+  // Close event signaled at gBS->ExitBootServices().\r
+  //\r
+  if (Instance->ExitBootEvent != NULL) {\r
+    gBS->CloseEvent (Instance->ExitBootEvent);\r
+    Instance->ExitBootEvent = NULL;\r
+  }\r
+\r
   //\r
   // Free allocated resource\r
   //\r
index 85e5a555395347966015fb10f0e9aa45cef1a268..8d6eac706c0b7a4294d19b1a80e806ef0f07732e 100644 (file)
@@ -121,6 +121,12 @@ typedef struct {
   //\r
   EFI_EVENT                         TimerEvent;\r
   LIST_ENTRY                        NonBlockingTaskList;\r
+\r
+  //\r
+  // For disabling the device (especially Bus Master DMA) at\r
+  // ExitBootServices().\r
+  //\r
+  EFI_EVENT                         ExitBootEvent;\r
 } ATA_ATAPI_PASS_THRU_INSTANCE;\r
 \r
 //\r