/*++
-Copyright (c) 2008-2012 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)
Revision History:
+ SATA support
+ AHCI support
+
+Licence:
+ GPLv2
+
--*/
#include "stdafx.h"
} // end UniataSataIdentifyPM()
-#ifdef DBG
+#ifdef _DEBUG
VOID
NTAPI
UniataDumpAhciRegs(
}
return;
} // end UniataDumpAhciPortRegs()
-#endif //DBG
+#endif //_DEBUG
BOOLEAN
PHW_CHANNEL chan;
ULONG offs;
ULONG BaseMemAddress;
-#ifdef DBG
ULONG PI;
-#endif //DBG
ULONG CAP;
+ ULONG CAP2;
+ ULONG BOHC;
ULONG GHC;
BOOLEAN MemIo = FALSE;
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) {
+ BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
+ KdPrint2((PRINT_PREFIX " stage 1 BOHC %#x\n", BOHC));
+ UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
+ BOHC | AHCI_BOHC_OOS);
+ for(i=0; i<50; i++) {
+ AtapiStallExecution(500);
+ BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
+ KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
+ if(BOHC & AHCI_BOHC_BB) {
+ break;
+ }
+ if(!(BOHC & AHCI_BOHC_BOS)) {
+ break;
+ }
+ }
+ KdPrint2((PRINT_PREFIX " stage 2 BOHC %#x\n", BOHC));
+ if(BOHC & AHCI_BOHC_BB) {
+ for(i=0; i<2000; i++) {
+ AtapiStallExecution(1000);
+ BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
+ KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
+ if(!(BOHC & AHCI_BOHC_BOS)) {
+ break;
+ }
+ }
+ }
+ KdPrint2((PRINT_PREFIX " final BOHC %#x\n", BOHC));
+ }
/* disable AHCI interrupts, for MSI compatibility issue
see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
}
/* 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)) {
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"));
+ BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
+ KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC));
+ UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC,
+ BOHC | AHCI_BOHC_OOS);
+ }
/* clear interrupts */
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS,
UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS));
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;
}
}
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"));
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) {
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"));
}
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_M88SX6121:
- NumberChannels = 2;
+ case ATA_M88SE6111:
+ KdPrint2((PRINT_PREFIX " Marvell M88SE6111 -> 1\n"));
+ NumberChannels = 1;
break;
- case ATA_M88SX6141:
- case ATA_M88SX6145:
- NumberChannels = 4;
+ case ATA_M88SE6121:
+ KdPrint2((PRINT_PREFIX " Marvell M88SE6121 -> 2\n"));
+ NumberChannels = min(NumberChannels, 2);
+ break;
+ case ATA_M88SE6141:
+ case ATA_M88SE6145:
+ case ATA_M88SE9123:
+ KdPrint2((PRINT_PREFIX " Marvell M88SE614x/9123 -> 4\n"));
+ NumberChannels = min(NumberChannels, 4);
break;
} // switch()
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"));
}
chan->AhciCompleteCI = (chan->AhciPrevCI ^ CI) & chan->AhciPrevCI; // only 1->0 states
chan->AhciPrevCI = CI;
+ chan->AhciLastSError = SError.Reg;
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 |
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;
}
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()
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
if (timeout && (i >= timeout)) {
-#ifdef DBG
+#ifdef _DEBUG
ULONG TFD;
SError = AtapiReadPort4(chan, IDX_SATA_SError);
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
KdPrint2((" TFD %#x\n", TFD));
-#endif //DBG
+#endif //_DEBUG
return IDE_STATUS_WRONG;
}
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);
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;
// KdPrint((" length/DEV_BSIZE != bcount\n"));
// }
-#ifdef DBG
+#ifdef _DEBUG
//UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
if(!Srb) {
KdPrint((" !Srb\n"));
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;
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()
}
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));
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()
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()
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));
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;
((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
}
AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
+
/*
if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
KdPrint2(("RCV:\n"));
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);
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);
(((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()
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);
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);
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));