]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
1. fix AtaPassThru.PassThru() sct failure
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AhciMode.c
index 92449f40c6b602da49db3c234fb0a7cbbef6eada..40012d7978c8f8fea3eb246a30e26efe1f3a7bcb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The file for AHCI mode of ATA host controller.\r
   \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
   which accompanies this distribution.  The full text of the license may be found at        \r
@@ -256,6 +256,42 @@ AhciClearPortStatus (
   AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));\r
 }\r
 \r
+/**\r
+  This function is used to dump the Status Registers and if there is ERR bit set\r
+  in the Status Register, the Error Register's value is also be dumped.\r
+\r
+  @param  PciIo            The PCI IO protocol instance.\r
+  @param  Port             The number of port.\r
+  @param  AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AhciDumpPortStatus (\r
+  IN     EFI_PCI_IO_PROTOCOL        *PciIo,\r
+  IN     UINT8                      Port,\r
+  IN OUT EFI_ATA_STATUS_BLOCK       *AtaStatusBlock\r
+  )\r
+{\r
+  UINT32               Offset;\r
+  UINT32               Data;\r
+\r
+  ASSERT (PciIo != NULL);\r
+\r
+  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
+  Data   = AhciReadReg (PciIo, Offset);\r
+\r
+  if (AtaStatusBlock != NULL) {\r
+    ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));\r
+\r
+    AtaStatusBlock->AtaStatus  = (UINT8)Data;\r
+    if ((AtaStatusBlock->AtaStatus & BIT0) != 0) {\r
+      AtaStatusBlock->AtaError = (UINT8)(Data >> 8);\r
+    }\r
+  }\r
+}\r
+\r
+\r
 /**\r
   Enable the FIS running for giving port.\r
     \r
@@ -621,7 +657,7 @@ AhciPioTransfer (
   //\r
   Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
   do {\r
-    Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);\r
+    Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);\r
 \r
     if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_PIO_SETUP) {\r
       break;\r
@@ -686,6 +722,8 @@ Exit:
     Map\r
     );\r
 \r
+  AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);\r
+\r
   return Status;\r
 }\r
 \r
@@ -855,6 +893,8 @@ Exit:
            Map\r
            );  \r
   \r
+  AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);\r
+\r
   return Status;\r
 }\r
 \r
@@ -942,7 +982,7 @@ AhciNonDataTransfer (
   //\r
   Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
   do {\r
-    Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);\r
+    Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);\r
 \r
     if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {\r
       break;\r
@@ -984,6 +1024,8 @@ Exit:
     Timeout\r
     );\r
 \r
+  AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);\r
+\r
   return Status;\r
 }\r
 \r
@@ -1082,17 +1124,6 @@ AhciStartCommand (
     return Status;\r
   }\r
 \r
-  //\r
-  // Setting the command\r
-  //\r
-  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;\r
-  AhciAndReg (PciIo, Offset, 0);\r
-  AhciOrReg (PciIo, Offset, CmdSlotBit);\r
-\r
-  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;\r
-  AhciAndReg (PciIo, Offset, 0);\r
-  AhciOrReg (PciIo, Offset, CmdSlotBit);\r
-\r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
   PortStatus = AhciReadReg (PciIo, Offset);\r
   \r
@@ -1124,6 +1155,17 @@ AhciStartCommand (
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
   AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);\r
 \r
+  //\r
+  // Setting the command\r
+  //\r
+  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;\r
+  AhciAndReg (PciIo, Offset, 0);\r
+  AhciOrReg (PciIo, Offset, CmdSlotBit);\r
+\r
+  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;\r
+  AhciAndReg (PciIo, Offset, 0);\r
+  AhciOrReg (PciIo, Offset, CmdSlotBit);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r