17 600, 383, 240, 180, 120,
26 120, 80, 60, 45, 30, 20, 15
32 { 70, 290, 240, 165, 150 },
33 { 50, 290, 93, 125, 100 },
34 { 30, 290, 40, 100, 90 },
35 { 30, 80, 70, 80, 70 },
36 { 25, 70, 25, 70, 25 },
39 { 120, 0, 0, 480, 480 },
40 { 90, 0, 0, 240, 240 },
41 { 60, 0, 0, 120, 120 },
44 { 60, 0, 0, 215, 215 },
57 return ((TimingValueNs * 1000) + ClockPeriodPs - 1) / ClockPeriodPs;
68 ATATIM DataCycleTime, CmdCycleTime;
79 DataCycleTime =
Device->MinMwDmaCycleTime;
81 DataCycleTime =
Device->MinSwDmaCycleTime;
84 DataCycleTime =
Device->MinPioCycleTime;
88 CmdCycleTime =
max(DataCycleTime, 330);
98 DataCycleTime =
AtaGetClocks(DataCycleTime, ClockPeriodPs);
99 if ((Timing->DataActive + Timing->DataRecovery) < DataCycleTime)
101 Timing->DataActive += (DataCycleTime - (Timing->DataActive + Timing->DataRecovery)) / 2;
102 Timing->DataRecovery = DataCycleTime - Timing->DataActive;
106 CmdCycleTime =
AtaGetClocks(CmdCycleTime, ClockPeriodPs);
107 if ((Timing->CmdActive + Timing->CmdRecovery) < CmdCycleTime)
109 Timing->CmdActive += (CmdCycleTime - (Timing->CmdActive + Timing->CmdRecovery)) / 2;
110 Timing->CmdRecovery = CmdCycleTime - Timing->CmdActive;
161 Timings[0].AddressSetup =
max(Timings[0].AddressSetup, Timings[1].AddressSetup);
163 Timings[1].AddressSetup = Timings[0].AddressSetup;
167 Timings[0].CmdActive =
max(Timings[0].CmdActive, Timings[1].CmdActive);
168 Timings[0].CmdRecovery =
max(Timings[0].CmdRecovery, Timings[1].CmdRecovery);
170 Timings[1].CmdActive = Timings[0].CmdActive;
171 Timings[1].CmdRecovery = Timings[0].CmdRecovery;
175 Timings[0].DataActive =
max(Timings[0].DataActive, Timings[1].DataActive);
176 Timings[0].DataRecovery =
max(Timings[0].DataRecovery, Timings[1].DataRecovery);
178 Timings[1].DataActive = Timings[0].DataActive;
179 Timings[1].DataRecovery = Timings[0].DataRecovery;
239 INFO(
"Failed to find mode for %ld ns cycle time from %lu in 0x%08lX\n",
242 SupportedModesBitmap);
290 &NewMode.
Drive[
i].PioSpeed,
300 &NewMode.
Drive[
i].DmaSpeed,
306 NewMode.
ModeFlags &= ~IDE_ACPI_TIMING_MODE_FLAG_UDMA(
i);
327 NewMode.
Drive[0].DmaSpeed =
max(NewMode.
Drive[0].DmaSpeed, NewMode.
Drive[1].DmaSpeed);
330 NewMode.
Drive[1].DmaSpeed = NewMode.
Drive[0].DmaSpeed;
333 NewMode.
Drive[0].PioSpeed =
max(NewMode.
Drive[0].PioSpeed, NewMode.
Drive[1].PioSpeed);
336 NewMode.
Drive[1].PioSpeed = NewMode.
Drive[0].PioSpeed;
340 INFO(
"CH %lu: Old timings %-2lX 0:%-3ld 0:%-3ld 1:%-3ld 1:%-3ld\n",
348 INFO(
"CH %lu: New timings %-2lX 0:%-3ld 0:%-3ld 1:%-3ld 1:%-3ld\n",
409 if (!(ChanData->ChanInfo & DmaFlags))
501 sizeof(*ChanData->
PrdTable) * ChanData->MaximumPhysicalPages,
502 PrdTablePhysicalAddress,
521 BlockSize =
sizeof(*ChanData->
PrdTable) * ChanData->MaximumPhysicalPages;
574 INFO(
"PCI bus mastering disabled\n");
581 INFO(
"Non DMA capable controller detected\n");
595 ERR(
"Failed to map bus master registers");
597 INFO(
"No bus master registers");
601 for (
i = 0;
i < Controller->MaxChannels; ++
i)
623 for (
i = 0;
i < Controller->MaxChannels; ++
i)
629 if (!(ChanData->TransferModeSupported & ~
PIO_ALL))
637 WARN(
"CH %lu: %p DMA 0x%02X\n", ChanData->Channel, ChanData->
Regs.
Dma, DmaStatus);
638 ChanData->TransferModeSupported &=
PIO_ALL;
642 INFO(
"CH %lu: %p DMA 0x%02X\n", ChanData->Channel, ChanData->
Regs.
Dma, DmaStatus);
645 if ((
i == 0) && (Controller->MaxChannels > 1))
674 Registers->
Data = (
PVOID)(CommandPortBase + 0 * CommandBlockSpare);
675 Registers->
Error = (
PVOID)(CommandPortBase + 1 * CommandBlockSpare);
677 Registers->
LbaLow = (
PVOID)(CommandPortBase + 3 * CommandBlockSpare);
678 Registers->
LbaMid = (
PVOID)(CommandPortBase + 4 * CommandBlockSpare);
679 Registers->
LbaHigh = (
PVOID)(CommandPortBase + 5 * CommandBlockSpare);
680 Registers->
Device = (
PVOID)(CommandPortBase + 6 * CommandBlockSpare);
681 Registers->
Status = (
PVOID)(CommandPortBase + 7 * CommandBlockSpare);
693 PVOID CommandPortBase, ControlPortBase;
694 const ULONG BarIndex = ChanData->Channel * 2;
699 if (!CommandPortBase)
703 if (!ControlPortBase)
749 if ((Desc->
u.
Port.Start.QuadPart == 0x640))
751 CommandPortDesc = Desc;
754 else if ((Desc->
u.
Port.Start.QuadPart == 0x74C))
756 ControlPortDesc = Desc;
762 if (!ControlPortDesc)
763 ControlPortDesc = Desc;
767 if (!CommandPortDesc)
768 CommandPortDesc = Desc;
777 InterruptDesc = Desc;
786 if (!CommandPortDesc || !ControlPortDesc || !InterruptDesc)
795 RtlCopyMemory(&ChanData->InterruptDesc, InterruptDesc,
sizeof(*InterruptDesc));
858 ASSERT(ChanData->Channel < 2);
866 ERR(
"CH %lu: Failed to assign I/O resources 0x%lx\n", ChanData->Channel,
Status);
884 if (ChanData->InterruptObject)
889 ChanData->InterruptObject =
NULL;
933 if (!(Controller->AccessRange[BarIndex + 1].Flags &
RANGE_IS_VALID))
938 if (Controller->ChannelEnableBits)
943 return Controller->ChannelEnabledTest(Controller,
Channel);
972 INFO(
"CH %lu: %sable interrupts\n", ChanData->Channel,
Enable ?
"En" :
"Dis");
992 ChanData->LastAtaBankId = 0xFF;
1026 InterruptDesc = &ChanData->InterruptDesc;
1047 ERR(
"Could not connect to interrupt %lu, status 0x%lx\n",
1080 ASSERT(Controller->MaxChannels != 0);
1087 Controller->ChanDataBlock = ChanData;
1088 Controller->ChannelBitmap =
NUM_TO_BITMAP(Controller->MaxChannels);
1090 for (
i = 0;
i < Controller->MaxChannels; ++
i)
1092 Controller->Channels[
i] = ChanData;
1094 ChanData->Channel =
i;
1095 ChanData->Controller = Controller;
1132 switch (Controller->Pci.VendorID)
1176 ERR(
"Unsupported controller\n");
1180 WARN(
"%04X:%04X.%02X: Using generic PCI IDE minidriver\n",
1181 Controller->Pci.VendorID,
1182 Controller->Pci.DeviceID,
1183 Controller->Pci.RevisionID);
1190 for (
i = 0;
i < Controller->MaxChannels; ++
i)
1194 ChanData->ChanInfo &= ~CHANNEL_FLAG_IO32;
1211 Controller->Flags &= ~CTRL_FLAG_NATIVE_PCI;
1219 ERR(
"No interrupt resource\n");
1226 for (
i = 0;
i < Controller->MaxChannels; ++
i)
1230 ChanData->TransferModeSupported &=
PIO_ALL;
1236 WARN(
"Sync access for hardware is required\n");
1239 if (!Controller->HwSyncObject)
BOOLEAN AtaAcpiGetTimingMode(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode)
NTSTATUS AtaAcpiSetTimingMode(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode, _In_opt_ PIDENTIFY_DEVICE_DATA IdBlock1, _In_opt_ PIDENTIFY_DEVICE_DATA IdBlock2)
NTSTATUS AmdGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
#define IDE_ACPI_TIMING_MODE_NOT_SUPPORTED
#define IDE_ACPI_TIMING_MODE_FLAG_UDMA(Drive)
#define IDE_ACPI_TIMING_MODE_FLAG_INDEPENDENT_TIMINGS
#define NUM_TO_BITMAP(num)
#define IDE_DC_DISABLE_INTERRUPTS
#define IDE_DC_REENABLE_CONTROLLER
NTSTATUS AtiGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
PCONTROLLER_OBJECT NTAPI IoCreateController(IN ULONG Size)
#define NT_SUCCESS(StatCode)
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
NTSTATUS CmdGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
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 ATA_WRITE(Port, Value)
NTSTATUS IntelGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
#define _Out_writes_all_(s)
#define UNREFERENCED_PARAMETER(P)
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
#define STATUS_DEVICE_CONFIGURATION_ERROR
#define PCIIDE_DMA_STATUS_RESERVED1
#define PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE
#define PCIIDE_DMA_STATUS
#define SHARED_DATA_TIMINGS
#define PCIIDE_DMA_STATUS_RESERVED2
#define PCIIDE_DMA_STATUS_DRIVE1_DMA_CAPABLE
#define SHARED_CMD_TIMINGS
#define PCIIDE_LEGACY_SECONDARY_COMMAND_BASE
#define PCIIDE_PROGIF_DMA_CAPABLE
#define PCIIDE_DMA_SECONDARY_CHANNEL_OFFSET
#define PCIIDE_DMA_IO_BAR
#define PCIIDE_COMMAND_IO_RANGE_LENGTH
#define PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE
#define PCIIDE_LEGACY_COMMAND_IO_RANGE_LENGTH
#define PCIIDE_LEGACY_CONTROL_IO_RANGE_LENGTH
#define PCIIDE_CONTROL_IO_RANGE_LENGTH
#define PCIIDE_DMA_STATUS_SIMPLEX
#define PCIIDE_DMA_IO_RANGE_LENGTH
#define PCIIDE_CONTROL_IO_BAR_OFFSET
#define PCIIDE_DMA_STATUS_DRIVE0_DMA_CAPABLE
#define SHARED_ADDR_TIMINGS
#define PCIIDE_LEGACY_PRIMARY_COMMAND_BASE
#define PCI_VEN_SERVERWORKS
static VOID PciIdeGenericSetTransferMode(_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
static VOID PataClaimLegacyAddressRanges(_In_ PCHANNEL_DATA_PATA ChanData)
VOID AtaSelectTimings(_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList, _Out_writes_all_(MAX_IDE_DEVICE) PATA_TIMING Timings, _In_range_(>, 0) ULONG ClockPeriodPs, _In_ ULONG Flags)
NTSTATUS PciIdeParseResources(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
static ATATIM AtaGetClocks(_In_ ATATIM TimingValueNs, _In_ ULONG ClockPeriodPs)
static const ULONG AtapModeToCycleTime[]
static BOOLEAN PciIdeControllerInitDma(_In_ PATA_CONTROLLER Controller)
static const ATA_TIMING AtapTimingTable[]
IDE_CHANNEL_STATE PciIdeGetChannelState(_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel)
static VOID PciIdeAcpiSetTransferMode(_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
static NTSTATUS PciIdeAssignNativeResources(_In_ PATA_CONTROLLER Controller, _In_ PCHANNEL_DATA_PATA ChanData)
NTSTATUS PciIdeConnectInterrupt(_In_ PVOID ChannelContext)
VOID PciIdeFreeResources(_In_ PVOID ChannelContext)
static VOID AtaCalculateTimings(_In_ PCHANNEL_DEVICE_CONFIG Device, _Out_ PATA_TIMING Timing, _In_ ULONG Mode, _In_ ULONG ClockPeriodPs)
static NTSTATUS PciIdeAllocateMemory(_In_ PVOID ChannelContext)
static VOID PataReleaseLegacyAddressRanges(_In_ PCHANNEL_DATA_PATA ChanData)
static VOID PciIdeFreeMemory(_In_ PVOID ChannelContext)
static VOID AtaAcpiFindModeForCycleTime(_In_ ULONG GtmCycleTime, _In_ ULONG SupportedModesBitmap, _In_ ULONG CurrentModesBitmap, _In_ ULONG MinimumMode, _In_ ULONG MaximumMode, _Out_ PULONG BestCycleTime, _Out_ PULONG BestMode)
NTSTATUS PciIdeCreateChannelData(_In_ PATA_CONTROLLER Controller, _In_ ULONG HwExtensionSize)
static NTSTATUS PciIdeAssignLegacyResources(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
static VOID PciIdeBiosSetTransferMode(_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
static VOID PataEnableInterrupts(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
static BOOLEAN PciIdeIsDmaStatusValid(_In_ UCHAR DmaStatus)
NTSTATUS PciIdeGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
VOID PciIdeInitTaskFileIoResources(_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG_PTR CommandPortBase, _In_ ULONG_PTR ControlPortBase, _In_ ULONG CommandBlockSpare)
#define WRITE_PORT_UCHAR(p, d)
CHANNEL_PREPARE_IO PataPrepareIo
#define CTRL_FLAG_NATIVE_PCI
FORCEINLINE UCHAR PciRead8(_In_ PATA_CONTROLLER Controller, _In_ ULONG ConfigDataOffset)
#define CHANNEL_FLAG_MRES_TF
CHANNEL_LOAD_TASK_FILE PataLoadTaskFile
#define CHANNEL_FLAG_MRES_DMA
#define CHANNEL_FLAG_MRES_CTRL
KDEFERRED_ROUTINE PataPollingTimerDpc
CHANNEL_START_IO PataStartIo
#define CTRL_FLAG_USE_TEST_FUNCTION
#define CHANNEL_FLAG_IO32
#define CHANNEL_FLAG_DRIVE0_DMA_CAPABLE
#define CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED
#define IS_PRIMARY_CHANNEL(PdoExtension)
KSERVICE_ROUTINE PciIdeChannelIsr
CHANNEL_SAVE_TASK_FILE PataSaveTaskFile
#define CTRL_FLAG_MANUAL_RES
CONTROLLER_ATTACH_CHANNEL_EX PciIdeAttachChannel
KSERVICE_ROUTINE PataChannelIsr
#define CHANNEL_FLAG_SECONDARY_ADDRESS_CLAIMED
#define CHANNEL_FLAG_CBUS
#define CHANNEL_FLAG_DRIVE1_DMA_CAPABLE
#define CTRL_FLAG_DMA_INTERRUPT
CHANNEL_SET_MODE_EX SataSetTransferMode
CHANNEL_CHECK_INTERRUPT PciIdeCheckInterrupt
CHANNEL_READ_STATUS PataReadStatus
CHANNEL_PREPARE_PRD_TABLE PciIdePreparePrdTable
#define CHANNEL_FLAG_HAS_ACPI_GTM
#define CTRL_FLAG_IS_SIMPLEX
NTSTATUS PcTechGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
#define CmResourceTypeMemory
#define CmResourceTypePort
#define CM_RESOURCE_INTERRUPT_LATCHED
#define CmResourceTypeInterrupt
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask)
NTSTATUS Sil680GetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaChanEnableInterruptsSync(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
PVOID AtaCtrlPciMapBar(_In_ PATA_CONTROLLER Controller, _In_range_(0, PCI_TYPE0_ADDRESSES) ULONG Index, _In_ ULONG MinimumIoLength)
CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDesc
PCHANNEL_CHECK_INTERRUPT CheckInterrupt
PCHANNEL_READ_STATUS ReadStatus
ULONG PrdTablePhysicalAddress
PPCIIDE_PRD_TABLE_ENTRY PrdTable
PCHANNEL_SAVE_TASK_FILE SaveTaskFile
PCHANNEL_LOAD_TASK_FILE LoadTaskFile
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@387 Interrupt
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@386 Port
PALLOCATE_COMMON_BUFFER AllocateCommonBuffer
PFREE_COMMON_BUFFER FreeCommonBuffer
struct _IDE_ACPI_TIMING_MODE_BLOCK::@1699 Drive[2]
IDE_REG LbaLow
LBA bits 0-7, 24-31.
IDE_REG LbaMid
LBA bits 8-15, 32-39.
IDE_REG LbaHigh
LBA bits 16-23, 40-47.
NTSTATUS SvwPataGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
NTSTATUS SvwSataGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
NTSTATUS ToshibaGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define STATUS_INSUFFICIENT_RESOURCES
NTSTATUS ViaGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
_Must_inspect_result_ _In_ WDFDEVICE Device
_In_ WDFCMRESLIST _In_ WDFCMRESLIST ResourcesTranslated
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_In_ WDF_WMI_PROVIDER_CONTROL Control
_Must_inspect_result_ _In_ ULONG Flags
#define PCI_ENABLE_BUS_MASTER
#define PCI_CLASS_MASS_STORAGE_CTLR
#define PCI_SUBCLASS_MSC_IDE_CTLR
#define PCI_SUBCLASS_MSC_RAID_CTLR
KSERVICE_ROUTINE * PKSERVICE_ROUTINE