33 for (
i = 0;
i < 10; ++
i)
43 for (
i = 0;
i < TimeOut;
i++)
62 INFO(
"CH %lu: %sble interrupts\n", ChanData->Channel,
Enable ?
"Ena" :
"Disa");
84 ERR(
"CH %lu: AHCI controller %04X:%04X is gone\n",
86 Controller->
Pci.VendorID,
87 Controller->
Pci.DeviceID);
99 INFO(
"CH %lu: Transmit a COMRESET on the interface\n", ChanData->Channel);
105 SataControl &= ~AHCI_PXCTL_DET_MASK;
112 SataControl &= ~AHCI_PXCTL_DET_MASK;
130 CmdStatus &= ~AHCI_PXCMD_ST;
151 for (
i = 0;
i < 10; ++
i)
188 CmdStatus &= ~AHCI_PXCMD_FRE;
236 WARN(
"CH %lx: Failed to start the FIS Receive DMA engine %08lx\n",
247 ULONG CmdStatus, SataControl;
249 if (!(ChanData->Controller->AhciCapabilities &
AHCI_CAP_SSS))
252 INFO(
"CH %lu: Enter listen mode\n", ChanData->Channel);
257 SataControl &= ~AHCI_PXCTL_DET_MASK;
272 if (!(ChanData->Controller->AhciCapabilities &
AHCI_CAP_SCLO))
292 ULONG CmdStatus, NewCmdStatus;
298 NewCmdStatus = CmdStatus & ~AHCI_PXCMD_ATAPI;
300 if (CmdStatus != NewCmdStatus)
310 ULONG FbsControl, NewFbsControl;
315 ChanData->LastFbsDeviceNumber = 0xFF;
324 NewFbsControl = FbsControl & ~AHCI_FBS_ENABLE;
325 ChanData->ChanInfo &= ~CHANNEL_FLAG_FBS_ENABLED;
341 INFO(
"CH %lu: FBS enabled\n", ChanData->Channel);
345 WARN(
"CH %lu: Unable to enable FIS-based switching\n", ChanData->Channel);
365 WARN(
"CH %lu: Failed to stop the command list DMA engine %08lx\n",
376 WARN(
"CH %lu: Failed to stop the FIS Receive DMA engine %08lx\n",
396 (
ULONG)(ChanData->Mem.CommandListPhys >> 32));
405 (
ULONG)(ChanData->Mem.ReceivedFisPhys >> 32));
419 CmdStatus &= ~AHCI_PXCMD_PMA;
422 CmdStatus &= ~AHCI_PXCMD_ICC_MASK;
435 if (ChanData->Controller->AhciCapabilities &
AHCI_CAP_SSS)
454 for (
i = 0;
i < 10; ++
i)
497 for (
i = 0;
i < 10; ++
i)
507 for (
i = 0;
i < TimeOut; ++
i)
519 WARN(
"CH %lu: Device is busy %08lx, trying to recover %lu\n",
539 ULONG InterruptStatus, TaskFileData;
542 ASSERT((ChanData->ActiveSlotsBitmap == 0) && (ChanData->ActiveQueuedSlotsBitmap == 0));
553 ERR(
"CH %lu: Internal request timed out\n", ChanData->Channel);
571 ERR(
"CH %lu: Failed to stop the command list DMA engine\n", ChanData->Channel);
579 ERR(
"CH %lu: Busy TFD %08lx\n", ChanData->Channel, TaskFileData);
597 TRACE(
"CH %lu: Completed internal request\n", ChanData->Channel);
599 INFO(
"CH %lu: Internal request failed %02x\n", ChanData->Channel, SrbStatus);
627 CommandHeader->
Control = (
sizeof(*H2dFis) /
sizeof(
ULONG)) |
664 CommandHeader->
Control = (
sizeof(*H2dFis) /
sizeof(
ULONG)) |
703 CommandHeader->
Control = (
sizeof(*H2dFis) /
sizeof(
ULONG)) |
738 ULONG ProductId, RevisionInfo, PortCount;
741 *PortCountResult = 0;
755 INFO(
"CH %lu: PMP %08lX:%08lX %lu ports\n",
793 *PortCountResult = PortCount;
822 WARN(
"CH %lu: Wait for ready failed %08lx\n",
841 INFO(
"CH %lu: Soft reset failed %02x\n", ChanData->Channel, SrbStatus);
852 *CheckForPmp =
FALSE;
853 INFO(
"CH %lu: Seems to have no PMP device\n", ChanData->Channel);
864 INFO(
"CH %lu: Soft reset failed %02x\n", ChanData->Channel, SrbStatus);
869 *CheckForPmp =
FALSE;
870 INFO(
"CH %lu: Seems to have no PMP device\n", ChanData->Channel);
880 INFO(
"CH %lu: Received signature %08lx\n", ChanData->Channel,
Signature);
895 for (RetryCount = 0; RetryCount < 2; ++RetryCount)
921 INFO(
"CH %lu: Device not connected %08lx\n",
929 INFO(
"CH %lu: Link up %08lx\n",
936 WARN(
"CH %lu: Unable to establish link %08lx\n",
950 WARN(
"CH %lu: Wait for ready failed %08lx\n",
958 INFO(
"CH %lu: Device is ready %08lx\n",
966 return ConnectionStatus;
974 ULONG RetryCount, PortCount;
984 ChanData->PortNotification(
AtaResetDetected, ChanData->PortContext, 0xFFFFFFFF);
986 for (RetryCount = 3; RetryCount > 0; RetryCount--)
988 ChanData->ChanInfo &= ~CHANNEL_FLAG_IS_PMP;
1004 if ((ChanData->Controller->AhciCapabilities &
AHCI_CAP_SPM) &&
1005 (RetryCount > 1) && CheckForPmp)
1007 INFO(
"CH %lu: Trying to detect PMP\n", ChanData->Channel);
1015 INFO(
"CH %lu: Discovered a Port Multiplier\n", ChanData->Channel);
1040 else if (PortCount == 0)
1060 INFO(
"CH %lu: Transmit a COMRESET on the interface\n", ChanData->Channel);
1074 SataControl &= ~AHCI_PXCTL_DET_MASK;
1107 INFO(
"CH %lu: PMP device %lu link up %08lx\n",
1117 INFO(
"CH %lu: PMP device %lu not connected %08lx\n",
1143 INFO(
"CH %lu: PMP device %lu link up %08lx\n",
1153 INFO(
"CH %lu: PMP device %lu unable to establish link %08lx\n",
1168 INFO(
"CH %lu: Reset PMP port %lu\n", ChanData->Channel,
PortNumber);
1177 return ConnectionStatus;
1181 return ConnectionStatus;
1200 return ConnectionStatus;
1203 for (RetryCount = 0; RetryCount < 2; RetryCount++)
1230 WARN(
"CH %lu: PMP port %lu soft reset failed %02x\n",
1259 return ConnectionStatus;
1267 INFO(
"CH %lu: Received signature %08lx\n", ChanData->Channel,
Signature);
1309 TaskFile->
LowLba = Fis->LbaLow;
1310 TaskFile->
MidLba = Fis->LbaMid;
1311 TaskFile->
HighLba = Fis->LbaHigh;
1318 TaskFile->
LowLbaEx = Fis->LbaLowEx;
1319 TaskFile->
MidLbaEx = Fis->LbaMidEx;
1337 ReceivedFis = ChanData->ReceivedFis;
1344 if (ProcessErrorStatus)
1377 Request->Output.Error = Fis.PioSetup->Error;
1400 ULONG CurrentCommandSlot, TaskFileData;
1401 ULONG i, CmdStatus, SlotsBitmap, FailedSlot;
1414 for (
i = 50000;
i > 0;
i--)
1425 ERR(
"CH %lu: Failed to stop the command list DMA engine %08lx\n",
1435 ERR(
"CH %lu: Busy TFD %08lx\n", ChanData->Channel, TaskFileData);
1444 if (ChanData->ActiveQueuedSlotsBitmap != 0)
1451 Request = ChanData->Slots[FailedSlot];
1461 SlotsBitmap = ChanData->ActiveSlotsBitmap;
1463 else if (ChanData->ActiveSlotsBitmap & (1 << CurrentCommandSlot))
1465 SlotsBitmap = 1 << CurrentCommandSlot;
1470 if (ChanData->ActiveSlotsBitmap != 0)
1472 ERR(
"CH %lu: Invalid slot received from the HBA %08lX --> %08lX\n",
1474 ChanData->ActiveSlotsBitmap,
1475 1 << CurrentCommandSlot);
1479 WARN(
"CH %lu: Spurious error interrupt %08lX\n",
1490 Request = ChanData->Slots[FailedSlot];
1524 WARN(
"CH %lu: Mechanical presence switch has changed %08lx\n",
1525 ChanData->Channel, CmdStatus);
1532 INFO(
"CH %lu: Device hot plug detected %08lx\n", ChanData->Channel, SataStatus);
1534 INFO(
"CH %lu: Device removal detected %08lx\n", ChanData->Channel, SataStatus);
1545 ULONG SataSpeed, SataControl;
1554 SataControl &= ~AHCI_PXCTL_SPD_MASK;
1557 WARN(
"CH %lu: Downgrading interface speed to %08lx\n", ChanData->Channel, SataControl);
1564 INFO(
"CH %lu: Unable to downgrade interface speed %08lx\n", ChanData->Channel, SataSpeed);
#define AHCI_DELAY_1_SECOND
#define AHCI_PXCMD_ICC_MASK
#define AHCI_PXTFD_STATUS_MASK
#define AHCI_PXCTL_DET_IDLE
#define IDE_COMMAND_READ_PORT_MULTIPLIER
#define AHCI_DELAY_INTERFACE_CHANGE
#define AHCI_DELAY_PMP_READY_DRIVE
#define AHCI_PXCTL_DET_RESET
#define AHCI_PXSSTS_DET_PHY_OK
#define AHCI_DELAY_PMP_DET_PRESENSE
#define AHCI_PXSSTS_DET_MASK
FORCEINLINE VOID AHCI_PORT_WRITE(_In_ PVOID PortIoBase, _In_ AHCI_PORT_REGISTER Register, _In_ ULONG Value)
#define AHCI_COMMAND_HEADER_PMP_SHIFT
#define AHCI_PXSSTS_SPD_SATA1
#define AHCI_FIS_REGISTER_HOST_TO_DEVICE
#define AHCI_PXSSTS_DET_NO_DEVICE
#define AHCI_PXIRQ_FATAL_ERROR
#define AHCI_PXCMD_CCS(Value)
enum _AHCI_PORT_REGISTER AHCI_PORT_REGISTER
#define AHCI_PXCTL_SPD_MASK
#define AHCI_PXTFD_ERROR_MASK
#define AHCI_PXCMD_ICC_IDLE
FORCEINLINE ULONG AHCI_PORT_READ(_In_ PVOID PortIoBase, _In_ AHCI_PORT_REGISTER Register)
#define AHCI_DELAY_CR_START_STOP
#define AHCI_MAX_PMP_DEVICES
#define AHCI_DELAY_CLO_CLEAR
#define AHCI_COMMAND_HEADER_CLEAR_BUSY_UPON_OK
#define AHCI_DELAY_DET_STABLE
#define AHCI_INTERNAL_SLOT
FORCEINLINE ULONG AHCI_HBA_READ(_In_ PVOID HbaIoBase, _In_ AHCI_HOST_BUS_ADAPTER_REGISTER Register)
#define AHCI_COMMAND_HEADER_RESET
#define IDE_COMMAND_WRITE_PORT_MULTIPLIER
#define AHCI_PXSSTS_SPD_MASK
#define AHCI_DELAY_DET_PRESENCE
#define AHCI_DELAY_FR_START_STOP
FORCEINLINE VOID AHCI_HBA_WRITE(_In_ PVOID HbaIoBase, _In_ AHCI_HOST_BUS_ADAPTER_REGISTER Register, _In_ ULONG Value)
#define AHCI_PXCTL_SPD_LIMIT_NONE
#define AHCI_PXTFD_ERROR_SHIFT
#define AHCI_MAX_PORT_DEVICES
#define AHCI_DELAY_READY_DRIVE
#define AHCI_PXCTL_SPD_LIMIT_LEVEL
#define AHCI_PORT_INTERRUPT_MASK
#define AHCI_PMP_CONTROL_PORT
#define AHCI_PXCMD_ICC_ACTIVE
static ATA_CONNECTION_STATUS AtaAhciPmpPhyCheckDevicePresence(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG PortNumber)
static BOOLEAN AtaAhciPmpCheckSendComReset(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG PortNumber)
static BOOLEAN AtaAhciEnterIdleState(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciWaitForDeviceReady(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG TimeOut)
ULONG AtaAhciChannelGetMaximumDeviceCount(_In_ PVOID ChannelContext)
BOOLEAN AtaAhciDowngradeInterfaceSpeed(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciStartFisReceiveProcess(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciPmpDisableSilXmitEarlyAck(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciPhyWaitForReady(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciStopCommandListProcess(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciPerformCommandListOverride(_In_ PCHANNEL_DATA_AHCI ChanData)
VOID AtaAhciStopDma(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciStartCommandListProcess(_In_ PCHANNEL_DATA_AHCI ChanData)
VOID AtaAhciHandleFatalError(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciStartFisReceiveProcessAndWait(_In_ PCHANNEL_DATA_AHCI ChanData)
static UCHAR AtaAhciPostRequestPolled(_In_ PCHANNEL_DATA_AHCI ChanData, _In_range_(>, 0) ULONG TimeOutMs)
static ATA_CONNECTION_STATUS AtaPmpCheckConnection(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG PortNumber)
static VOID AtaAhciSendComReset(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciStopFisReceiveProcess(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciFbsControl(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ BOOLEAN DoEnable)
static ATA_CONNECTION_STATUS AtaAhciPmpDetect(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ PBOOLEAN CheckForPmp)
static UCHAR AtaAhciPmpWrite(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ UCHAR PortNumber, _In_ USHORT Register, _In_ ULONG Value)
static ATA_CONNECTION_STATUS AtaAhciPmpPhyWaitForReady(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG PortNumber)
static VOID AtaAhciAtapiLedControl(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ BOOLEAN DoEnable)
static VOID AtaAhciSaveReceivedFisArea(_In_ AHCI_FIS_DEVICE_TO_HOST *__restrict Fis, _Inout_ ATA_DEVICE_REQUEST *__restrict Request)
Captures and saves a dump of the AHCI task file registers, except the values in the Fis->Status and F...
static BOOLEAN AtaAhciPollRegister(_In_ PVOID IoBase, _In_ AHCI_PORT_REGISTER Register, _In_ ULONG Mask, _In_ ULONG Value, _In_range_(>, 0) ULONG TimeOut)
static BOOLEAN AtaAhciStopCommandListProcessAndWait(_In_ PCHANNEL_DATA_AHCI ChanData)
static UCHAR AtaAhciPmpRead(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ UCHAR PortNumber, _In_ USHORT Register, _Out_ PULONG Result)
static VOID AtaAhciSetupDmaMemoryAddress(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciPmpIdentifyPmp(_In_ PCHANNEL_DATA_AHCI ChanData, _Out_ PULONG PortCountResult)
static ATA_CONNECTION_STATUS AtaAhciPmpIdentifyDeviceBehindPmp(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG PortNumber)
static BOOLEAN AtaAhciPhyCheckDevicePresence(_In_ PCHANNEL_DATA_AHCI ChanData)
static VOID AtaAhciPhyEnterListenMode(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciStopFisReceiveProcessAndWait(_In_ PCHANNEL_DATA_AHCI ChanData)
VOID AtaAhciHandlePortStateChange(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ ULONG InterruptStatus)
static VOID AtaAhciSpinUp(_In_ PCHANNEL_DATA_AHCI ChanData)
static BOOLEAN AtaAhciIsHbaHotRemoved(_In_ PCHANNEL_DATA_AHCI ChanData)
VOID AtaAhciSaveTaskFile(_In_ PCHANNEL_DATA_AHCI ChanData, _Inout_ PATA_DEVICE_REQUEST Request, _In_ BOOLEAN ProcessErrorStatus)
static UCHAR AtaAhciSendResetFis(_In_ PCHANNEL_DATA_AHCI ChanData, _In_ UCHAR PortNumber, _In_ BOOLEAN AssertSRST, _In_range_(>, 0) ULONG TimeOutMs)
static ATA_CONNECTION_STATUS AtaAhciPhyCheckConnection(_In_ PCHANNEL_DATA_AHCI ChanData)
@ CONN_STATUS_DEV_UNKNOWN
#define REQUEST_FLAG_DATA_IN
enum _ATA_CONNECTION_STATUS ATA_CONNECTION_STATUS
#define REQUEST_FLAG_SAVE_TASK_FILE
#define REQUEST_FLAG_HAS_TASK_FILE
FORCEINLINE BOOLEAN IsPowerOfTwo(_In_ ULONG x)
#define IDE_DC_RESET_CONTROLLER
_In_ PCHAR _In_ ULONG DeviceNumber
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
static const WCHAR Signature[]
#define SRB_STATUS_TIMEOUT
#define SRB_STATUS_SUCCESS
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define REQUEST_FLAG_LBA48
#define KeStallExecutionProcessor(MicroSeconds)
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
#define CHANNEL_FLAG_IS_PMP
#define CHANNEL_FLAG_FBS_ENABLED
#define DEV_NUMBER(Device)
CHANNEL_IDENTIFY_DEVICE AtaAhciIdentifyDevice
CHANNEL_ENABLE_INTERRUPTS AtaAhciEnableInterrupts
#define PORT_TIMER_TICK_MS
CHANNEL_ENUMERATE_CHANNEL AtaAhciEnumerateChannel
CHANNEL_RESET_CHANNEL AtaAhciResetChannel
#define CHANNEL_FLAG_HAS_FBS
unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask)
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaChanEnableInterruptsSync(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
AHCI_FIS_HOST_TO_DEVICE HostToDeviceFis
AHCI_FIS_DEVICE_TO_HOST DeviceToHostFis
AHCI_FIS_SET_DEVICE_BITS SetDeviceBitsFis
AHCI_FIS_PIO_SETUP PioSetupFis
struct _ATA_CONTROLLER::@1179 Pci
UCHAR MidLba
LBA bits 8-15.
UCHAR LowLbaEx
LBA bits 24-31.
UCHAR HighLba
LBA bits 16-23.
UCHAR HighLbaEx
LBA bits 40-47.
UCHAR LowLba
LBA bits 0-7.
UCHAR MidLbaEx
LBA bits 32-39.
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO