]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/AtaAtapiPassThru: disable the device at ExitBootServices()
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AtaAtapiPassThru.c
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