]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/AtaAtapiPassThru: Error handling enhancement for uninstalling protocol...
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AtaAtapiPassThru.c
index 35477d886257285b4ea8d796eaa95dde05bc35d6..c397a04cf702b65334138e299e7929d821f4d6db 100644 (file)
@@ -870,53 +870,17 @@ AtaAtapiPassThruStop (
 \r
   Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (AtaPassThru);\r
 \r
-  //\r
-  // Close Non-Blocking timer and free Task list.\r
-  //\r
-  if (Instance->TimerEvent != NULL) {\r
-    gBS->CloseEvent (Instance->TimerEvent);\r
-    Instance->TimerEvent = NULL;\r
-  }\r
-  DestroyAsynTaskList (Instance, FALSE);\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  Controller,\r
+                  &gEfiAtaPassThruProtocolGuid, &(Instance->AtaPassThru),\r
+                  &gEfiExtScsiPassThruProtocolGuid, &(Instance->ExtScsiPassThru),\r
+                  NULL\r
+                  );\r
 \r
-  //\r
-  // Disable this ATA host controller.\r
-  //\r
-  PciIo  = Instance->PciIo;\r
-  Status = PciIo->Attributes (\r
-                    PciIo,\r
-                    EfiPciIoAttributeOperationSupported,\r
-                    0,\r
-                    &Supports\r
-                    );\r
-  if (!EFI_ERROR (Status)) {\r
-    Supports &= EFI_PCI_DEVICE_ENABLE;\r
-    PciIo->Attributes (\r
-             PciIo,\r
-             EfiPciIoAttributeOperationDisable,\r
-             Supports,\r
-             NULL\r
-             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  //\r
-  // Restore original PCI attributes\r
-  //\r
-  Status = PciIo->Attributes (\r
-                    PciIo,\r
-                    EfiPciIoAttributeOperationSet,\r
-                    Instance->OriginalPciAttributes,\r
-                    NULL\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  gBS->UninstallMultipleProtocolInterfaces (\r
-         Controller,\r
-         &gEfiAtaPassThruProtocolGuid, &(Instance->AtaPassThru),\r
-         &gEfiExtScsiPassThruProtocolGuid, &(Instance->ExtScsiPassThru),\r
-         NULL\r
-         );\r
-\r
   //\r
   // Close protocols opened by AtaAtapiPassThru controller driver\r
   //\r
@@ -927,15 +891,25 @@ AtaAtapiPassThruStop (
          Controller\r
          );\r
 \r
+  //\r
+  // Close Non-Blocking timer and free Task list.\r
+  //\r
+  if (Instance->TimerEvent != NULL) {\r
+    gBS->CloseEvent (Instance->TimerEvent);\r
+    Instance->TimerEvent = NULL;\r
+  }\r
+  DestroyAsynTaskList (Instance, FALSE);\r
   //\r
   // Free allocated resource\r
   //\r
-  DestroyDeviceInfoList(Instance);\r
+  DestroyDeviceInfoList (Instance);\r
 \r
   //\r
   // If the current working mode is AHCI mode, then pre-allocated resource\r
   // for AHCI initialization should be released.\r
   //\r
+  PciIo = Instance->PciIo;\r
+\r
   if (Instance->Mode == EfiAtaAhciMode) {\r
     AhciRegisters = &Instance->AhciRegisters;\r
     PciIo->Unmap (\r
@@ -966,6 +940,37 @@ AtaAtapiPassThruStop (
              AhciRegisters->AhciRFis\r
              );\r
   }\r
+\r
+  //\r
+  // Disable this ATA host controller.\r
+  //\r
+  Status = PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationSupported,\r
+                    0,\r
+                    &Supports\r
+                    );\r
+  if (!EFI_ERROR (Status)) {\r
+    Supports &= EFI_PCI_DEVICE_ENABLE;\r
+    PciIo->Attributes (\r
+             PciIo,\r
+             EfiPciIoAttributeOperationDisable,\r
+             Supports,\r
+             NULL\r
+             );\r
+  }\r
+\r
+  //\r
+  // Restore original PCI attributes\r
+  //\r
+  Status = PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationSet,\r
+                    Instance->OriginalPciAttributes,\r
+                    NULL\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   FreePool (Instance);\r
 \r
   return Status;\r
@@ -1764,7 +1769,10 @@ AtaPassThruResetPort (
   IN UINT16                     Port\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  //\r
+  // Return success directly then upper layer driver could think reset port operation is done.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -1806,7 +1814,21 @@ AtaPassThruResetDevice (
   IN UINT16                     PortMultiplierPort\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  ATA_ATAPI_PASS_THRU_INSTANCE    *Instance;\r
+  LIST_ENTRY                      *Node;\r
+\r
+  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);\r
+\r
+  if (Node == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Return success directly then upper layer driver could think reset device operation is done.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -2274,7 +2296,10 @@ ExtScsiPassThruResetChannel (
   IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  //\r
+  // Return success directly then upper layer driver could think reset channel operation is done.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -2304,7 +2329,41 @@ ExtScsiPassThruResetTargetLun (
   IN UINT64                             Lun\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  ATA_ATAPI_PASS_THRU_INSTANCE    *Instance;\r
+  LIST_ENTRY                      *Node;\r
+  UINT8                           Port;\r
+  UINT8                           PortMultiplier;\r
+\r
+  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);\r
+  //\r
+  // For ATAPI device, doesn't support multiple LUN device.\r
+  //\r
+  if (Lun != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // The layout of Target array:\r
+  //  ________________________________________________________________________\r
+  // |       Byte 0        |       Byte 1        | ... | TARGET_MAX_BYTES - 1 |\r
+  // |_____________________|_____________________|_____|______________________|\r
+  // |                     | The port multiplier |     |                      |\r
+  // |   The port number   |    port number      | N/A |         N/A          |\r
+  // |_____________________|_____________________|_____|______________________|\r
+  //\r
+  // For ATAPI device, 2 bytes is enough to represent the location of SCSI device.\r
+  //\r
+  Port           = Target[0];\r
+  PortMultiplier = Target[1];\r
+\r
+  Node = SearchDeviceInfoList(Instance, Port, PortMultiplier, EfiIdeCdrom);\r
+  if (Node == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Return success directly then upper layer driver could think reset target LUN operation is done.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r