120 TaskFile->
Error =
ATA_READ(ChanData->Regs.Error, ChanData, MRES_TF);
122 TaskFile->
LowLba =
ATA_READ(ChanData->Regs.LbaLow, ChanData, MRES_TF);
123 TaskFile->
MidLba =
ATA_READ(ChanData->Regs.LbaMid, ChanData, MRES_TF);
124 TaskFile->
HighLba =
ATA_READ(ChanData->Regs.LbaHigh, ChanData, MRES_TF);
126 TaskFile->
Command =
ATA_READ(ChanData->Regs.Command, ChanData, MRES_TF);
149 return ATA_READ(ChanData->Regs.Status, ChanData, MRES_TF);
170 ChanData->SaveTaskFile(ChanData,
Request);
175 Request->Output.Status = IdeStatus;
176 Request->Output.Error =
ATA_READ(ChanData->Regs.Error, ChanData, MRES_TF);
189 ChanData->SaveTaskFile(ChanData,
Request);
210 PUCHAR IoBase = ChanData->Regs.Dma;
220 ChanData->PrdTablePhysicalAddress,
250 PUCHAR IoBase = ChanData->Regs.Dma;
280 ChanData->IsPollingActive =
TRUE;
285 ChanData->IsPollingActive =
FALSE;
288 TRACE(
"Interrupt mode %s\n",
Control ?
"disable" :
"enable");
296 if (ChanData->Controller->Pci.VendorID ==
PCI_VEN_VIA)
336 TRACE(
"Read block %lu %lu %p\n",
337 ByteCount, ChanData->BytesToTransfer, ChanData->DataBuffer);
344 (
PULONG)ChanData->DataBuffer,
387 TRACE(
"Write block %lu %lu %p\n",
388 ByteCount, ChanData->BytesToTransfer, ChanData->DataBuffer);
395 (
PULONG)ChanData->DataBuffer,
437 UCHAR SrbStatus, InterruptReason;
440 InterruptReason =
ATA_READ(ChanData->Regs.InterruptReason, ChanData, MRES_TF);
454 WARN(
"Not fully compliant ATAPI device %02x %02x\n", IdeStatus, InterruptReason);
458 InterruptReason =
ATA_READ(ChanData->Regs.InterruptReason, ChanData, MRES_TF);
463 switch (InterruptReason)
469 WARN(
"Invalid interrupt reason %02x %02x, flags %08lx\n",
472 ChanData->CommandFlags);
477 ChanData->CommandFlags &= ~CMD_FLAG_AWAIT_CDB;
496 WARN(
"Invalid interrupt reason %02x %02x, flags %08lx\n",
499 ChanData->CommandFlags);
517 WARN(
"Invalid interrupt reason %02x %02x, flags %08lx\n",
520 ChanData->CommandFlags);
539 WARN(
"Invalid interrupt reason %02x %02x, flags %08lx\n",
542 ChanData->CommandFlags);
555 else if (ChanData->BytesToTransfer != 0)
558 ASSERT(
Request->DataTransferLength >= ChanData->BytesToTransfer);
559 Request->DataTransferLength -= ChanData->BytesToTransfer;
572 WARN(
"Invalid interrupt reason %02x %02x, flags %08lx\n",
575 ChanData->CommandFlags);
597 ERR(
"DRQ not cleared, status 0x%02x\n", IdeStatus);
611 IdeStatus &= ~IDE_STATUS_DRQ;
615 ERR(
"DRQ not cleared, status 0x%02x\n", IdeStatus);
629 if ((IdeStatus == 0) &&
645 WARN(
"Not fully compliant ATA device %02x\n", IdeStatus);
660 ERR(
"DRQ not set, status 0x%02x\n", IdeStatus);
669 if (ChanData->BytesToTransfer != 0)
679 ERR(
"DRQ not cleared, status 0x%02x\n", IdeStatus);
690 if (ChanData->BytesToTransfer == 0)
694 ERR(
"DRQ not cleared, status 0x%02x\n", IdeStatus);
705 ERR(
"DRQ not set, status 0x%02x %lu/%lu\n",
707 ChanData->BytesToTransfer,
729 TRACE(
"%u Status 0x%02x, DMA 0x%02x, REQ 0x%lx\n",
733 ChanData->CommandFlags);
784 ATA_WRITE(ChanData->Regs.Features,
Request->TaskFile.FeatureEx, ChanData, MRES_TF);
785 ATA_WRITE(ChanData->Regs.SectorCount,
Request->TaskFile.SectorCountEx, ChanData, MRES_TF);
786 ATA_WRITE(ChanData->Regs.LbaLow,
Request->TaskFile.LowLbaEx, ChanData, MRES_TF);
787 ATA_WRITE(ChanData->Regs.LbaMid,
Request->TaskFile.MidLbaEx, ChanData, MRES_TF);
788 ATA_WRITE(ChanData->Regs.LbaHigh,
Request->TaskFile.HighLbaEx, ChanData, MRES_TF);
792 ATA_WRITE(ChanData->Regs.Features,
Request->TaskFile.Feature, ChanData, MRES_TF);
793 ATA_WRITE(ChanData->Regs.SectorCount,
Request->TaskFile.SectorCount, ChanData, MRES_TF);
794 ATA_WRITE(ChanData->Regs.LbaLow,
Request->TaskFile.LowLba, ChanData, MRES_TF);
795 ATA_WRITE(ChanData->Regs.LbaMid,
Request->TaskFile.MidLba, ChanData, MRES_TF);
796 ATA_WRITE(ChanData->Regs.LbaHigh,
Request->TaskFile.HighLba, ChanData, MRES_TF);
800 ATA_WRITE(ChanData->Regs.Device,
Request->TaskFile.DriveSelect, ChanData, MRES_TF);
818 ChanData->CommandFlags = CommandFlags;
835 ATA_WRITE(ChanData->Regs.Features, Features, ChanData, MRES_TF);
852 ULONG CommandFlags, BlockCount;
857 ChanData->LoadTaskFile(ChanData,
Request);
859 ATA_WRITE(ChanData->Regs.Command,
Request->TaskFile.Command, ChanData, MRES_TF);
879 BlockCount =
Device->MultiSectorCount;
882 ChanData->DrqByteCount = BlockCount *
Device->SectorSize;
913 WARN(
"Device is busy 0x%02x\n", IdeStatus);
939 if (!IsPollingNeeded)
949 ERR(
"BSY timeout, status 0x%02x\n", IdeStatus);
985 ULONG DescriptorNumber = 0;
993 for (
i = 0;
i <
SgList->NumberOfElements; ++
i)
1008 ULONG TransferLength;
1012 TransferLength =
min(TransferLength,
Length);
1018 ASSERT(DescriptorNumber < ChanData->MaximumPhysicalPages);
1027 Length -= TransferLength;
1063 UCHAR IdeStatus, DmaStatus;
1101 WARN(
"Spurious bus-master interrupt %02x, %02x, flags %08lx\n",
1134 WARN(
"Spurious IDE interrupt %02x, flags %08lx\n", IdeStatus, ChanData->
CommandFlags);
1179 if (IsRequestCompleted)
1183 return IsRequestCompleted;
1207 IsRequestCompleted =
FALSE;
1211 IsRequestCompleted =
PataPoll(ChanData);
1216 if (!IsRequestCompleted)
#define WRITE_REGISTER_ULONG(r, v)
#define IDE_STATUS_DEVICE_FAULT
#define REQUEST_FLAG_DATA_IN
#define DEVICE_IS_NEC_CDR260
_In_ PATA_DEVICE_REQUEST _In_ BOOLEAN Allocate
#define DEVICE_HAS_CDB_INTERRUPT
#define REQUEST_FLAG_DATA_OUT
#define REQUEST_FLAG_HAS_SG_LIST
#define REQUEST_FLAG_SAVE_TASK_FILE
#define REQUEST_FLAG_POLL
#define REQUEST_FLAG_HAS_TASK_FILE
#define ATA_MIN_BUFFER_ALIGNMENT
#define IDE_HIGH_ORDER_BYTE
#define IDE_COMMAND_ATAPI_IDENTIFY
#define IDE_COMMAND_IDENTIFY
#define IDE_COMMAND_ATAPI_PACKET
#define IDE_DC_DISABLE_INTERRUPTS
#define WRITE_PORT_BUFFER_ULONG(port, buffer, count)
#define WRITE_PORT_BUFFER_USHORT(port, buffer, count)
#define READ_PORT_BUFFER_ULONG(port, buffer, count)
#define READ_PORT_BUFFER_USHORT(port, buffer, count)
static BOOLEAN WarningsGiven[5]
#define DECLSPEC_ALIGN(x)
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
#define SRB_STATUS_BUS_RESET
#define SRB_STATUS_DATA_OVERRUN
#define SRB_STATUS_PENDING
#define SRB_STATUS_SELECTION_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
VOID NTAPI WRITE_PORT_ULONG(IN PULONG Port, IN ULONG Value)
#define ATAPI_INT_REASON_STATUS_NEC
#define REQUEST_FLAG_LBA48
#define ATA_WRITE_BLOCK_16(Port, Buffer, Count)
#define ATA_TIME_DRQ_ASSERT
150 us
#define ATAPI_INT_REASON_IO
#define ATAPI_INT_REASON_COD
#define ATA_TIME_BUSY_POLL
5 s
#define ATAPI_INT_REASON_STATUS
#define REQUEST_FLAG_READ_WRITE_MULTIPLE
#define ATAPI_INT_REASON_MASK
#define REQUEST_FLAG_PACKET_COMMAND
#define ATA_TIME_DRQ_CLEAR
10 ms
#define ATA_WRITE(Port, Value)
#define ATAPI_INT_REASON_AWAIT_CDB
#define ATA_READ_BLOCK_16(Port, Buffer, Count)
#define ATA_READ_BLOCK_32(Port, Buffer, Count)
#define ATAPI_INT_REASON_DATA_IN
#define ATA_TIME_BUSY_SELECT
20 ms
#define REQUEST_FLAG_SET_DEVICE_REGISTER
#define ATA_WRITE_BLOCK_32(Port, Buffer, Count)
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
#define UNREFERENCED_PARAMETER(P)
_In_ ULONG _In_ ULONG _In_ ULONG Length
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
#define ATAPI_MAX_DRQ_DATA_BLOCK
#define CMD_FLAG_TRANSFER_MASK
#define PCIIDE_PRD_END_OF_TABLE
#define PATA_CHANNEL_SLOT
#define PCIIDE_DMA_STATUS
#define CMD_FLAG_ATAPI_PIO_TRANSFER
#define PCIIDE_DMA_STATUS_INTERRUPT
#define PCIIDE_PRD_LENGTH_MASK
#define CMD_FLAG_ATA_PIO_TRANSFER
#define CMD_FLAG_AWAIT_CDB
#define PCIIDE_DMA_COMMAND_START
#define CMD_FLAG_DMA_TRANSFER
#define PCIIDE_DMA_COMMAND
#define PCIIDE_DMA_COMMAND_READ_FROM_SYSTEM_MEMORY
#define PCIIDE_DMA_COMMAND_WRITE_TO_SYSTEM_MEMORY
FORCEINLINE VOID ATA_SELECT_DEVICE(_In_ PCHANNEL_DATA_PATA ChanData, _In_ UCHAR DeviceNumber, _In_ UCHAR DeviceSelect)
#define ATA_TIME_BUSY_NORMAL
500 ms
#define PCIIDE_DMA_COMMAND_STOP
#define ATA_WRITE_ULONG(Port, Value, Ctx, MmioFlag)
FORCEINLINE UCHAR ATA_WAIT(_In_ PCHANNEL_DATA_PATA ChanData, _In_range_(>, 0) ULONG Timeout, _In_ UCHAR Mask, _In_ UCHAR Value)
#define PCIIDE_DMA_STATUS_ERROR
#define ATAPI_INT_REASON_DATA_OUT
#define CMD_FLAG_DATA_OUT
#define CMD_FLAG_AWAIT_INTERRUPT
#define PCIIDE_DMA_PRDT_PHYSICAL_ADDRESS
static UCHAR PciIdeDmaReadStatus(_In_ PCHANNEL_DATA_PATA ChanData)
VOID AtaWritePortUchar(_In_ PUCHAR Port, _In_ UCHAR Value, _In_ ULONG MmioFlags)
static VOID PataPioDataOut(_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG ByteCount)
static VOID PciIdeDmaPrepare(_In_ PCHANNEL_DATA_PATA ChanData)
static BOOLEAN PataPoll(_In_ PCHANNEL_DATA_PATA ChanData)
static VOID PciIdeDmaClearInterrupt(_In_ PCHANNEL_DATA_PATA ChanData, _In_ UCHAR DmaStatus)
static BOOLEAN PataProcessRequest(_In_ PCHANNEL_DATA_PATA ChanData, _In_ UCHAR IdeStatus, _In_ UCHAR DmaStatus)
static VOID PataPioDataIn(_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG ByteCount)
VOID AtaWritePortUlong(_In_ PULONG Port, _In_ ULONG Value, _In_ ULONG MmioFlags)
static VOID PataSendCdb(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_DEVICE_REQUEST Request)
static BOOLEAN PataExecutePacketCommand(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_IO_CONTEXT_COMMON Device, _In_ PATA_DEVICE_REQUEST Request)
static VOID PciIdeDmaStart(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_DEVICE_REQUEST Request)
VOID AtaReadBlock16(_In_ PUSHORT Port, _In_ PUSHORT Buffer, _In_ ULONG Count, _In_ ULONG MmioFlags)
static UCHAR PataProcessAtaRequest(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
static VOID PataCompleteCommand(_In_ PCHANNEL_DATA_PATA ChanData, _In_ UCHAR IdeStatus, _In_ UCHAR SrbStatus)
VOID AtaWriteBlock16(_In_ PUSHORT Port, _In_ PUSHORT Buffer, _In_ ULONG Count, _In_ ULONG MmioFlags)
VOID AtaReadBlock32(_In_ PULONG Port, _In_ PULONG Buffer, _In_ ULONG Count, _In_ ULONG MmioFlags)
VOID PciIdeDmaStop(_In_ PCHANNEL_DATA_PATA ChanData)
static UCHAR PataProcessAtapiRequest(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR IdeStatus)
UCHAR AtaReadPortUchar(_In_ PUCHAR Port, _In_ ULONG MmioFlags)
static VOID PataChangeInterruptMode(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_IO_CONTEXT_COMMON Device, _In_ PATA_DEVICE_REQUEST Request)
VOID AtaWriteBlock32(_In_ PULONG Port, _In_ PULONG Buffer, _In_ ULONG Count, _In_ ULONG MmioFlags)
static BOOLEAN PataExecuteAtaCommand(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PATA_IO_CONTEXT_COMMON Device, _In_ PATA_DEVICE_REQUEST Request)
#define READ_PORT_UCHAR(p)
#define WRITE_PORT_UCHAR(p, d)
CHANNEL_PREPARE_IO PataPrepareIo
CHANNEL_LOAD_TASK_FILE PataLoadTaskFile
KDEFERRED_ROUTINE PataPollingTimerDpc
CHANNEL_START_IO PataStartIo
#define DEV_NUMBER(Device)
#define CHANNEL_FLAG_IO32
KSERVICE_ROUTINE PciIdeChannelIsr
CHANNEL_SAVE_TASK_FILE PataSaveTaskFile
#define CHANNEL_FLAG_DMA_BEFORE_CMD
CHANNEL_ALLOCATE_SLOT PataAllocateSlot
KSERVICE_ROUTINE PataChannelIsr
CHANNEL_CHECK_INTERRUPT PciIdeCheckInterrupt
CHANNEL_READ_STATUS PataReadStatus
CHANNEL_PREPARE_PRD_TABLE PciIdePreparePrdTable
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
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.
PCHANNEL_CHECK_INTERRUPT CheckInterrupt
PCHANNEL_READ_STATUS ReadStatus
PPCIIDE_PRD_TABLE_ENTRY PrdTable
ULONG Length
0 means 0x10000 bytes
_Must_inspect_result_ _In_ WDFDEVICE Device
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION _In_ PSCATTER_GATHER_LIST SgList
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ WDF_WMI_PROVIDER_CONTROL Control
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
NTKERNELAPI VOID NTAPI READ_REGISTER_BUFFER_USHORT(IN PUSHORT Register, IN PUSHORT Buffer, IN ULONG Count)
NTKERNELAPI VOID NTAPI READ_REGISTER_BUFFER_ULONG(IN PULONG Register, IN PULONG Buffer, IN ULONG Count)
NTKERNELAPI VOID NTAPI WRITE_REGISTER_BUFFER_ULONG(IN PULONG Register, IN PULONG Buffer, IN ULONG Count)
NTKERNELAPI VOID NTAPI WRITE_REGISTER_BUFFER_USHORT(IN PUSHORT Register, IN PUSHORT Buffer, IN ULONG Count)
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
_In_opt_ PVOID DeferredContext
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2