Revision: 16537
          http://sourceforge.net/p/edk2/code/16537
Author:   vanjeff
Date:     2014-12-18 07:16:05 +0000 (Thu, 18 Dec 2014)
Log Message:
-----------
MdeModulePkg/AtaAtapiPassThru:

When D2H FIS received at PIO DATA-IN transfer, check PxTFD.Error register to 
confirm if there is
a real error for better device compatibilities with Qemu and Marvel9230 sata 
controllers.

(Sync patch r16225 from main trunk.)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Reza Jelveh <[email protected]>
Signed-off-by: Feng Tian <[email protected]>
Reviewed-by: A. Sava <[email protected]>
Reviewed-by: Star Zeng <[email protected]>

Revision Links:
--------------
    http://sourceforge.net/p/edk2/code/16225

Modified Paths:
--------------
    branches/UDK2014.SP1/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c

Modified: branches/UDK2014.SP1/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
===================================================================
--- branches/UDK2014.SP1/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c       
2014-12-18 06:13:36 UTC (rev 16536)
+++ branches/UDK2014.SP1/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c       
2014-12-18 07:16:05 UTC (rev 16537)
@@ -704,6 +704,8 @@
   UINT32                        PortTfd;
   UINT32                        PrdCount;
   BOOLEAN                       InfiniteWait;
+  BOOLEAN                       PioFisReceived;
+  BOOLEAN                       D2hFisReceived;
 
   if (Timeout == 0) {
     InfiniteWait = TRUE;
@@ -780,15 +782,31 @@
     Status = EFI_TIMEOUT;
     Delay  = DivU64x32 (Timeout, 1000) + 1;
     do {
+      PioFisReceived = FALSE;
+      D2hFisReceived = FALSE;
       Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;
-
       Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, 
EFI_AHCI_FIS_PIO_SETUP, NULL);
       if (!EFI_ERROR (Status)) {
+        PioFisReceived = TRUE;
+      }
+      //
+      // According to SATA 2.6 spec section 11.7, D2h FIS means an error 
encountered.
+      // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS 
from device
+      // after the transaction is finished successfully.
+      // To get better device compatibilities, we further check if the PxTFD's 
ERR bit is set.
+      // By this way, we can know if there is a real error happened.
+      //
+      Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
+      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, 
EFI_AHCI_FIS_REGISTER_D2H, NULL);
+      if (!EFI_ERROR (Status)) {
+        D2hFisReceived = TRUE;
+      }
+
+      if (PioFisReceived || D2hFisReceived) {
         Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + 
EFI_AHCI_PORT_TFD;
         PortTfd = AhciReadReg (PciIo, (UINT32) Offset);
         //
         // PxTFD will be updated if there is a D2H or SetupFIS received. 
-        // For PIO IN transfer, D2H means a device error. Therefore we only 
need to check the TFD after receiving a SetupFIS.
         //
         if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
           Status = EFI_DEVICE_ERROR;
@@ -797,23 +815,20 @@
 
         PrdCount = *(volatile UINT32 *) 
(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
         if (PrdCount == DataCount) {
+          Status = EFI_SUCCESS;
           break;
         }
       }
 
-      Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
-      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, 
EFI_AHCI_FIS_REGISTER_D2H, NULL);
-      if (!EFI_ERROR (Status)) {
-        Status = EFI_DEVICE_ERROR;
-        break;
-      }
-
       //
       // Stall for 100 microseconds.
       //
       MicroSecondDelay(100);
 
       Delay--;
+      if (Delay == 0) {
+        Status = EFI_TIMEOUT;
+      }
     } while (InfiniteWait || (Delay > 0));
   } else {
     //
@@ -1325,10 +1340,6 @@
   //
   // Setting the command
   //
-  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + 
EFI_AHCI_PORT_SACT;
-  AhciAndReg (PciIo, Offset, 0);
-  AhciOrReg (PciIo, Offset, CmdSlotBit);
-
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + 
EFI_AHCI_PORT_CI;
   AhciAndReg (PciIo, Offset, 0);
   AhciOrReg (PciIo, Offset, CmdSlotBit);


------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to