[UNIATA] Update to version 0.47a. CORE-15930
[reactos.git] / drivers / storage / ide / uniata / id_sata.cpp
index 9996852..2c67131 100644 (file)
@@ -1,12 +1,12 @@
 /*++
 
-Copyright (c) 2008-2014 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2008-2019 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_probe.cpp
 
 Abstract:
-    This module handles SATA-related staff
+    This module handles SATA- and AHCI-related staff
 
 Author:
     Alexander A. Telyatnikov (Alter)
@@ -29,6 +29,12 @@ Notes:
 
 Revision History:
 
+    SATA support
+    AHCI support
+
+Licence:
+    GPLv2
+
 --*/
 
 #include "stdafx.h"
@@ -576,7 +582,7 @@ UniataSataIdentifyPM(
 
 } // end UniataSataIdentifyPM()
 
-#ifdef DBG
+#ifdef _DEBUG
 VOID
 NTAPI
 UniataDumpAhciRegs(
@@ -631,7 +637,7 @@ UniataDumpAhciPortRegs(
     }
     return;
 } // end UniataDumpAhciPortRegs()
-#endif //DBG
+#endif //_DEBUG
 
 
 BOOLEAN
@@ -645,9 +651,7 @@ UniataAhciInit(
     PHW_CHANNEL chan;
     ULONG offs;
     ULONG BaseMemAddress;
-#ifdef DBG
     ULONG PI;
-#endif //DBG
     ULONG CAP;
     ULONG CAP2;
     ULONG BOHC;
@@ -656,9 +660,9 @@ UniataAhciInit(
 
     KdPrint2((PRINT_PREFIX "  UniataAhciInit:\n"));
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciRegs(deviceExtension);
-#endif //DBG
+#endif //_DEBUG
 
     CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
     if(CAP2 & AHCI_CAP2_BOH) {
@@ -730,12 +734,20 @@ UniataAhciInit(
     }
 
     /* re-enable AHCI mode */
+    /* Linux: Some controllers need AHCI_EN to be written multiple times.
+     * Try a few times before giving up.
+     */
     GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
-    if(!(GHC & AHCI_GHC_AE)) {
-        KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
-        UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
-            GHC | AHCI_GHC_AE);
-        GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+    for(i=0; i<5; i++) {
+        if(!(GHC & AHCI_GHC_AE)) {
+            KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
+            UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
+                GHC | AHCI_GHC_AE);
+            AtapiStallExecution(1000);
+            GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+        } else {
+            break;
+        }
     }
     KdPrint2((PRINT_PREFIX "  AHCI GHC %#x\n", GHC));
     if(!(GHC & AHCI_GHC_AE)) {
@@ -757,11 +769,15 @@ UniataAhciInit(
     if(CAP & AHCI_CAP_SAM) {
         KdPrint2((PRINT_PREFIX "  AHCI legasy SATA\n"));
     }
-#ifdef DBG
+
     /* get the number of HW channels */
     PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
+    deviceExtension->AHCI_PI = PI;
     KdPrint2((PRINT_PREFIX "  AHCI PI %#x\n", PI));
-#endif //DBG
+    KdPrint2((PRINT_PREFIX "  AHCI PI mask %#x\n", deviceExtension->AHCI_PI_mask));
+    deviceExtension->AHCI_PI = PI = PI & deviceExtension->AHCI_PI_mask;
+    KdPrint2((PRINT_PREFIX "  masked AHCI PI %#x\n", PI));
+
     CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
     if(CAP2 & AHCI_CAP2_BOH) {
         KdPrint2((PRINT_PREFIX "  retry BOHC\n"));
@@ -853,11 +869,12 @@ UniAtaAhciValidateVersion(
     case 0x00010100:
     case 0x00010200:
     case 0x00010300:
+    case 0x00010301:
         break;
     default:
         KdPrint2((PRINT_PREFIX "  Unknown AHCI revision\n"));
         if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", Strict)) {
-            KdPrint(("  AHCI revision excluded\n"));
+            KdPrint(("  AHCI revision excluded %#x\n", version));
             return FALSE;
         }
     }
@@ -878,17 +895,19 @@ UniataAhciDetect(
     ULONG version;
     ULONG i, n;
     ULONG PI;
+    //ULONG PI_ex_mask=0;
     ULONG CAP;
     ULONG CAP2;
     ULONG GHC, GHC0;
-#ifdef DBG
+#ifdef _DEBUG
     ULONG BOHC;
     ULONG v_Mn, v_Mj;
-#endif //DBG
+#endif //_DEBUG
     ULONG NumberChannels;
-    ULONG BaseMemAddress;
+    ULONG_PTR BaseMemAddress;
     BOOLEAN MemIo = FALSE;
     BOOLEAN found = FALSE;
+    ULONG BarId=5;
 
     KdPrint2((PRINT_PREFIX "  UniataAhciDetect:\n"));
 
@@ -896,22 +915,28 @@ UniataAhciDetect(
         KdPrint(("  AHCI excluded\n"));
         return FALSE;
     }
+    switch(deviceExtension->DevID) {
+    case 0xa01c0031:
+      KdPrint2((PRINT_PREFIX "  Cavium uses BAR(0)\n"));
+      BarId = 0;
+      break;
+    }
     BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
-                            5, 0, 0x10);
+                          BarId, 0, 0x10);
     if(!BaseMemAddress) {
         KdPrint2((PRINT_PREFIX "  AHCI init failed - no IoRange\n"));
         return FALSE;
     }
-    if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
+    if((*ConfigInfo->AccessRanges)[BarId].RangeInMemory) {
         KdPrint2((PRINT_PREFIX "MemIo\n"));
         MemIo = TRUE;
     }
     deviceExtension->BaseIoAHCI_0.Addr  = BaseMemAddress;
     deviceExtension->BaseIoAHCI_0.MemIo = MemIo;
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciRegs(deviceExtension);
-#endif //DBG
+#endif //_DEBUG
 
     GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
     if(GHC & AHCI_GHC_HR) {
@@ -946,17 +971,17 @@ UniataAhciDetect(
 
     CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
     CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
-    KdPrint2((PRINT_PREFIX "  AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
+    KdPrint2((PRINT_PREFIX "  AHCI CAP %#x, CAP2 %#x, ver %#x\n", CAP, CAP2, version));
     if(CAP & AHCI_CAP_S64A) {
         KdPrint2((PRINT_PREFIX "  64bit"));
         //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
     }
-#ifdef DBG
+#ifdef _DEBUG
     if(CAP2 & AHCI_CAP2_BOH) {
         BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
         KdPrint2((PRINT_PREFIX "  BOHC %#x", BOHC));
     }
-#endif //DBG
+#endif //_DEBUG
     if(CAP & AHCI_CAP_NCQ) {
         KdPrint2((PRINT_PREFIX "  NCQ"));
     }
@@ -969,26 +994,75 @@ UniataAhciDetect(
     KdPrint2((PRINT_PREFIX "\n"));
 
     /* get the number of HW channels */
+    
+    /* CAP.NOP sometimes indicate the index of the last enabled
+     * port, at other times, that of the last possible port, so
+     * determining the maximum port number requires looking at
+     * both CAP.NOP and PI.
+     */
     PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
-    deviceExtension->AHCI_PI = PI;
+    deviceExtension->AHCI_PI = deviceExtension->AHCI_PI_mask = PI;
     KdPrint2((PRINT_PREFIX "  AHCI PI %#x\n", PI));
+
+    for(i=PI, n=0; i; n++, i=i>>1) {
+        if(AtapiRegCheckDevValue(deviceExtension, n, DEVNUM_NOT_SPECIFIED, L"Exclude", 0)) {
+            KdPrint2((PRINT_PREFIX "Channel %d excluded\n", n));
+            deviceExtension->AHCI_PI &= ~((ULONG)1 << n);
+            deviceExtension->AHCI_PI_mask &= ~((ULONG)1 << n);
+            //PI_ex_mask |= ((ULONG)1 << n);
+        }
+    }
+    deviceExtension->AHCI_PI_mask = 
+        AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortMask", deviceExtension->AHCI_PI_mask);
+    KdPrint2((PRINT_PREFIX "Force PortMask %#x\n", deviceExtension->AHCI_PI_mask));
+
     for(i=PI, n=0; i; n++, i=i>>1);
     NumberChannels =
         max((CAP & AHCI_CAP_NOP_MASK)+1, n);
 
+    if(!PI && ((CAP & AHCI_CAP_NOP_MASK)+1)) {
+        /* Enable ports. 
+         * The spec says that BIOS sets up bits corresponding to
+         * available ports. On platforms where this information
+         * is missing, the driver can define available ports on its own.
+         */
+        KdPrint2((PRINT_PREFIX "PI=0 -> Enable ports (mask) %#x\n", deviceExtension->AHCI_PI_mask));
+        n = NumberChannels;
+        deviceExtension->AHCI_PI = ((ULONG)1 << n)-1;
+
+        if(deviceExtension->AHCI_PI_mask) {
+            // we have some forced port mask
+            PI = deviceExtension->AHCI_PI_mask;
+        } else {
+            // construct mask
+            PI = deviceExtension->AHCI_PI = (((ULONG)1 << n)-1);
+            deviceExtension->AHCI_PI_mask = (((ULONG)1 << n)-1);
+        }
+        KdPrint2((PRINT_PREFIX "Enable ports final PI %#x\n", PI));
+        UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_PI, PI);
+    }
+
     KdPrint2((PRINT_PREFIX "  CommandSlots %d\n", (CAP & AHCI_CAP_NCS_MASK)>>8 ));
-    KdPrint2((PRINT_PREFIX "  Channels %d\n", n));
+    KdPrint2((PRINT_PREFIX "  Detected Channels %d / %d\n", NumberChannels, n));
 
     switch(deviceExtension->DevID) {
-    case ATA_M88SX6111:
+    case 0x2361197b:
+        KdPrint2((PRINT_PREFIX "  JMicron JMB361 -> 1\n"));
+        NumberChannels = 1;
+        break;
+    case ATA_M88SE6111:
+        KdPrint2((PRINT_PREFIX "  Marvell M88SE6111 -> 1\n"));
         NumberChannels = 1;
         break;
-    case ATA_M88SX6121:
-        NumberChannels = 2;
+    case ATA_M88SE6121:
+        KdPrint2((PRINT_PREFIX "  Marvell M88SE6121 -> 2\n"));
+        NumberChannels = min(NumberChannels, 2);
         break;
-    case ATA_M88SX6141:
-    case ATA_M88SX6145:
-        NumberChannels = 4;
+    case ATA_M88SE6141:
+    case ATA_M88SE6145:
+    case ATA_M88SE9123:
+        KdPrint2((PRINT_PREFIX "  Marvell M88SE614x/9123 -> 4\n"));
+        NumberChannels = min(NumberChannels, 4);
         break;
     } // switch()
 
@@ -997,16 +1071,17 @@ UniataAhciDetect(
         found = FALSE;
         goto exit_detect;
     }
+    KdPrint2((PRINT_PREFIX "  Adjusted Channels %d\n", NumberChannels));
 
-#ifdef DBG
+#ifdef _DEBUG
     v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
     v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
 
-    KdPrint2((PRINT_PREFIX "  AHCI version %#x.%02x controller with %d ports (mask %#x) detected\n",
+    KdPrint2((PRINT_PREFIX "  AHCI version %x.%02x controller with %d ports (mask %#x) detected\n",
                  v_Mj, v_Mn,
                  NumberChannels, PI));
     KdPrint(("  AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) ));
-#endif //DBG
+#endif //_DEBUG
 
     if(CAP & AHCI_CAP_SPM) {
         KdPrint2((PRINT_PREFIX "  PM supported\n"));
@@ -1105,9 +1180,9 @@ UniataAhciStatus(
     KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI));
     chan->AhciLastIS = IS.Reg;
     if(CI & (1 << tag)) {
-#ifdef DBG
+#ifdef _DEBUG
         UniataDumpAhciPortRegs(chan);
-#endif //DBG
+#endif //_DEBUG
         //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
         if(IS.Reg &
             (ATA_AHCI_P_IX_OF | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF |
@@ -1205,8 +1280,6 @@ UniataAhciSetupFIS_H2D(
         if(((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp|ATA_CMD_FLAG_FUA)) == ATA_CMD_FLAG_LBAIOsupp) &&
            CheckIfBadBlock(chan->lun[DeviceNumber], lba, count)) {
             KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
-            //return IDE_STATUS_ERROR;
-            //return SRB_STATUS_ERROR;
             return 0;
         }
 
@@ -1246,22 +1319,15 @@ UniataAhciSetupFIS_H2D(
 
             chan->ChannelCtrlFlags |= CTRFLAGS_LBA48;
         } else {
-//#ifdef _MSC_VER
-//#pragma warning(push)
-//#pragma warning(disable:4333) // right shift by too large amount, data loss
-//#endif
             fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
             chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
-//#ifdef _MSC_VER
-//#pragma warning(pop)
-//#endif
         }
 
         //fis[14] = 0x00;
 
     }
 
-    KdDump(fis, 20);
+    //KdDump(fis, 20);
 
     return 20;
 } // end UniataAhciSetupFIS_H2D()
@@ -1405,7 +1471,7 @@ UniataAhciWaitCommandReady(
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
 
     if (timeout && (i >= timeout)) {
-#ifdef DBG
+#ifdef _DEBUG
         ULONG TFD;
 
         SError = AtapiReadPort4(chan, IDX_SATA_SError);
@@ -1413,7 +1479,7 @@ UniataAhciWaitCommandReady(
 
         TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
         KdPrint2(("  TFD %#x\n", TFD));
-#endif //DBG
+#endif //_DEBUG
         
         return IDE_STATUS_WRONG;
     }
@@ -1499,9 +1565,9 @@ UniataAhciSendPIOCommand(
         KdPrint(("  length/DEV_BSIZE != bcount\n"));
     }
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(!Srb) {
         Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
@@ -1557,15 +1623,15 @@ UniataAhciSendPIOCommand(
 
     AtaReq->ahci.io_cmd_flags = ahci_flags;
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(wait_flags == ATA_IMMEDIATE) {
         statusByte = 0;
@@ -1612,9 +1678,9 @@ UniataAhciSendPIOCommandDirect(
 //        KdPrint(("  length/DEV_BSIZE != bcount\n"));
 //    }
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(!Srb) {
         KdPrint(("  !Srb\n"));
@@ -1667,15 +1733,15 @@ UniataAhciSendPIOCommandDirect(
 
     AtaReq->ahci.io_cmd_flags = ahci_flags;
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(wait_flags == ATA_IMMEDIATE) {
         statusByte = 0;
@@ -1767,6 +1833,13 @@ UniataAhciSoftReset(
 
     KdDump(RCV_FIS, sizeof(chan->AhciCtlBlock->rcv_fis.rfis));
 
+    if(deviceExtension->HwFlags & UNIATA_AHCI_ALT_SIG) {
+        ULONG signature;
+        signature = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
+        KdPrint(("  alt sig: %#x\n", signature));
+        return signature;
+    }
+
     return UniataAhciUlongFromRFIS(RCV_FIS);
 
 } // end UniataAhciSoftReset()
@@ -1830,9 +1903,9 @@ UniataAhciHardReset(
     }
     KdPrint(("  TFD %#x\n", TFD));
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
     KdPrint(("  sig: %#x\n", *signature));
@@ -1955,6 +2028,7 @@ UniataAhciStartFR(
     CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
     KdPrint2(("  CMD %#x\n", CMD));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD | ATA_AHCI_P_CMD_FRE);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStartFR()
@@ -2014,6 +2088,7 @@ UniataAhciStart(
         CMD |
         ATA_AHCI_P_CMD_ST |
         ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStart()
@@ -2143,10 +2218,10 @@ UniataAhciBeginTransaction(
         return 0;
     }
 
-#ifdef DBG
+#ifdef _DEBUG
     KdPrint2(("  prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags, 
             AHCI_CL->cmd_table_phys));
-#endif // DBG
+#endif // _DEBUG
 
     CMD0 = CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
     KdPrint2(("  CMD %#x\n", CMD));
@@ -2162,15 +2237,28 @@ UniataAhciBeginTransaction(
     if(CMD0 != CMD) {
         KdPrint2(("  send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
         UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
+        CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
     }
 
     /* issue command to controller */
-    //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
+    //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag); // Used for NCQ
+    KdPrint2(("  Set CI\n"));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag);
     chan->AhciPrevCI |= 0x01 << tag;
 
+    //CMD0 = CMD;
+    CMD |= ATA_AHCI_P_CMD_ST |
+          ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0);
+    if(CMD != CMD0) {
+      KdPrint2(("  Send CMD START (%#x != %#x)\n", CMD, CMD0));
+      UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
+      CMD0 = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
+    } else {
+      KdPrint2(("  No CMD START, already active\n"));
+    }
+
     if(!ATAPI_DEVICE(chan, DeviceNumber)) {
-        // TODO: check if we send ATA_RESET and wait for ready of so.
+        // TODO: check if we send ATAPI_RESET and wait for ready of so.
         if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
             ULONG  TFD;
             ULONG  i;
@@ -2249,6 +2337,7 @@ UniataAhciEndTransaction(
                                 ((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
     }
     AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
+
 /*
     if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
         KdPrint2(("RCV:\n"));
@@ -2269,13 +2358,13 @@ UniataAhciEndTransaction(
         KdPrint2(("  Incomplete command, CI %#x, ACT %#x\n", CI, ACT));
         KdPrint2(("  FIS status %#x, error %#x\n", RCV_FIS[2], RCV_FIS[3]));
 
-#if DBG
+#ifdef _DEBUG
         UniataDumpAhciPortRegs(chan);
 #endif
         if(!UniataAhciAbortOperation(chan)) {
             KdPrint2(("  Abort failed, need RESET\n"));
         }
-#if DBG
+#ifdef _DEBUG
         UniataDumpAhciPortRegs(chan);
 #endif
         chan->AhciPrevCI = CI & ~((ULONG)1 << tag);
@@ -2302,9 +2391,9 @@ UniataAhciResume(
 
     KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     /* Disable port interrupts */
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE, 0);
@@ -2340,17 +2429,18 @@ UniataAhciResume(
             (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
             (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
             );
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciStartFR(chan);
     UniataAhciStart(chan);
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     return;
 } // end UniataAhciResume()
@@ -2374,6 +2464,7 @@ UniataAhciSuspend(
     UniataAhciStop(chan);
     UniataAhciStopFR(chan);
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, 0);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     /* Allow everything including partial and slumber modes. */
     UniataSataWritePort4(chan, IDX_SATA_SControl, 0, 0);
@@ -2525,9 +2616,9 @@ IN OUT PATA_REQ AtaReq
         PUCHAR prd_base0;
         ULONGLONG prd_base64_0;
     };
-#ifdef DBG
+#ifdef _DEBUG
     ULONG d;
-#endif // DBG
+#endif // _DEBUG
 
     prd_base64_0 = prd_base64 = 0;
     prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
@@ -2535,10 +2626,10 @@ IN OUT PATA_REQ AtaReq
 
     prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
 
-#ifdef DBG
+#ifdef _DEBUG
     d = (ULONG)(prd_base64 - prd_base64_0);
     KdPrint2((PRINT_PREFIX "  AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
-#endif // DBG
+#endif // _DEBUG
 
     AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64;
     KdPrint2((PRINT_PREFIX "  ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr));