27#define ATAPORT_TAG 'PedI'
29#define IDE_DRIVE_SELECT 0xA0
31#define ATA_READ(Port) READ_PORT_UCHAR((Port))
32#define ATA_WRITE(Port, Value) WRITE_PORT_UCHAR((Port), (Value))
33#define ATA_IO_WAIT() KeStallExecutionProcessor(1)
35#define ATA_TIME_BUSY_SELECT 3000
36#define ATA_TIME_BUSY_IDENTIFY 500000
37#define ATA_TIME_DRQ_CLEAR 1000
38#define ATA_TIME_RESET_SELECT 200000
39#define ATA_TIME_BUSY_RESET 1000000
66 IdeStatus =
ATA_READ(Registers->Status);
70 if (IdeStatus == 0xFF)
106 DPRINT(
"Timeout, status 0x%02x\n", IdeStatus);
124 DPRINT(
"Timeout, status 0x%02x\n", IdeStatus);
129 DPRINT(
"Command 0x%02x aborted, status 0x%02x, error 0x%02x\n",
137 DPRINT1(
"DRQ not set, status 0x%02x\n", IdeStatus);
151 DPRINT1(
"DRQ not cleared, status 0x%02x\n", IdeStatus);
184 ATA_WRITE(Registers->ByteCountLow, 0xAA);
185 ATA_WRITE(Registers->ByteCountLow, 0x55);
186 ATA_WRITE(Registers->ByteCountLow, 0xAA);
187 if (
ATA_READ(Registers->ByteCountLow) == 0xAA)
194 DPRINT(
"Selection timeout\n");
203 DPRINT1(
"Timeout, status 0x%02x\n", IdeStatus);
217 UCHAR IdeStatus, SignatureLow, SignatureHigh;
224 IdeStatus =
ATA_READ(Registers->Status);
225 if (IdeStatus == 0xFF || IdeStatus == 0x7F)
229 ATA_WRITE(Registers->ByteCountLow, 0x55);
230 ATA_WRITE(Registers->ByteCountLow, 0xAA);
231 ATA_WRITE(Registers->ByteCountLow, 0x55);
232 if (
ATA_READ(Registers->ByteCountLow) != 0x55)
234 ATA_WRITE(Registers->ByteCountHigh, 0xAA);
235 ATA_WRITE(Registers->ByteCountHigh, 0x55);
236 ATA_WRITE(Registers->ByteCountHigh, 0xAA);
237 if (
ATA_READ(Registers->ByteCountHigh) != 0xAA)
244 DPRINT1(
"Device is busy, attempting to recover %02x\n", IdeStatus);
257 SignatureLow =
ATA_READ(Registers->SignatureLow);
258 SignatureHigh =
ATA_READ(Registers->SignatureHigh);
260 DPRINT(
"SL = 0x%02x, SH = 0x%02x\n", SignatureLow, SignatureHigh);
263 if (SignatureLow == 0x14 && SignatureHigh == 0xEB)
297 DPRINT(
"Found IDE device\n");
353#define CHANNEL_PC98_RESOURCE_COUNT 12
373 for (
i = 0;
i < 7; ++
i)
388#define CHANNEL_PCAT_RESOURCE_COUNT 3
462 *IsAddressMmio =
FALSE;
467 *IsAddressMmio =
TRUE;
523 PVOID ControllerContext;
528 DPRINT(
"IDE Channel IO %lx, Irq %lu\n", LegacyChannel->IoBase, LegacyChannel->Irq);
532 DPRINT(
"Failed to build the resource list\n");
538 DPRINT(
"Failed to claim resources\n");
543 IsAddressMmio[0] =
FALSE;
544 IsAddressMmio[1] =
FALSE;
561 DPRINT(
"Failed to map command port\n");
564 goto ReleaseResources;
572 DPRINT(
"Failed to map control port\n");
575 goto ReleaseResources;
590 DPRINT(
"No IDE devices found\n");
611 DPRINT(
"IoReportDetectedDevice() failed with status 0x%lx\n",
Status);
620 (
PVOID)ControllerInferface,
624 DPRINT1(
"Failed to register the legacy channel 0x%lx, status 0x%lx\n",
625 LegacyChannel->IoBase,
Status);
631 DPRINT1(
"Unknown interface version 0x%lx\n", ControllerInferface->Version);
640 DPRINT1(
"Failed to add the legacy channel 0x%lx, status 0x%lx\n",
641 LegacyChannel->IoBase,
Status);
650 DPRINT1(
"Failed to start the legacy channel 0x%lx, status 0x%lx\n",
651 LegacyChannel->IoBase,
Status);
653 ControllerInferface->RemoveDevice(ControllerContext);
657 if (IsAddressMmio[0] && Registers.
Data)
662 if (IsAddressMmio[1] && Registers.
Control)
699 HANDLE SoftKeyHandle, ParamsKeyHandle;
702 static const WCHAR MapperKeyPath[] =
703 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Pnp";
720 DPRINT(
"Skipping legacy detection on a PnP system\n");
736 DPRINT1(
"Failed to open the 'Parameters' key, status 0x%lx\n",
Status);
749 (
PWSTR)ParamsKeyHandle,
753 PerformDetection = (KeyValue != 0);
756 if (PerformDetection)
760 (
PWSTR)ParamsKeyHandle,
770 return PerformDetection;
792 LegacyChannel[0].
IoBase = 0x640;
793 LegacyChannel[0].
Irq = 9;
800 LegacyChannel[0].
IoBase = 0x1F0;
801 LegacyChannel[0].
Irq = 14;
804 LegacyChannel[1].
IoBase = 0x170;
805 LegacyChannel[1].
Irq = 15;
808 LegacyChannel[2].
IoBase = 0x1E8;
809 LegacyChannel[2].
Irq = 11;
812 LegacyChannel[3].
IoBase = 0x168;
813 LegacyChannel[3].
Irq = 10;
824 DPRINT1(
"Failed to allocate the resource list\n");
836 for (
i = 0; LegacyChannel[
i].
IoBase != 0; ++
i)
839 &ControllerInferface,
#define IDE_STATUS_DEVICE_FAULT
#define PCIIDEX_INTERFACE_VERSION
#define PCIIDEX_GET_CONTROLLER_INTERFACE_SIGNATURE
#define IDE_COMMAND_ATAPI_IDENTIFY
#define IDE_DC_RESET_CONTROLLER
#define IDE_COMMAND_IDENTIFY
#define IDE_DC_DISABLE_INTERRUPTS
#define READ_PORT_BUFFER_USHORT(port, buffer, count)
PDEVICE_OBJECT PhysicalDeviceObject
_In_ PCHAR _In_ ULONG DeviceNumber
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
#define NT_SUCCESS(StatCode)
#define RTL_CONSTANT_STRING(s)
static const WCHAR Cleanup[]
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
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
BOOLEAN NTAPI HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
static ULONG ResourceCount
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
static NTSTATUS AtaOpenRegistryKey(_Out_ PHANDLE KeyHandle, _In_ HANDLE RootKey, _In_ PUNICODE_STRING KeyName)
static VOID AtaLegacyMakePortResource(_Out_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, _In_ ULONG IoBase, _In_ ULONG Length)
static BOOLEAN AtaLegacyChannelBuildResources(_In_ PATA_LEGACY_CHANNEL LegacyChannel, _Inout_ PCM_RESOURCE_LIST ResourceList)
DRIVER_INITIALIZE DriverEntry
static BOOLEAN AtaLegacyFindAtaDevice(_In_ PIDE_REGISTERS Registers, _In_ ULONG DeviceNumber)
static BOOLEAN AtaLegacyChannelPresent(_In_ PIDE_REGISTERS Registers)
static BOOLEAN AtaLegacyShouldDetectChannels(_In_ PUNICODE_STRING RegistryPath)
#define ATA_TIME_BUSY_RESET
static BOOLEAN AtaLegacyDetectChannel(_In_ PDRIVER_OBJECT DriverObject, _In_ PPCIIDEX_LEGACY_CONTROLLER_INTERFACE ControllerInferface, _In_ PATA_LEGACY_CHANNEL LegacyChannel, _In_ PCM_RESOURCE_LIST ResourceList, _In_ ULONG ResourceListSize)
#define CHANNEL_PC98_RESOURCE_COUNT
struct _ATA_LEGACY_CHANNEL ATA_LEGACY_CHANNEL
static UCHAR AtaWait(_In_ PIDE_REGISTERS Registers, _In_range_(>, 0) ULONG Timeout, _In_ UCHAR Mask, _In_ UCHAR Value)
static BOOLEAN AtaLegacyPerformSoftwareReset(_In_ PIDE_REGISTERS Registers, _In_ ULONG DeviceNumber)
static VOID AtaLegacyFetchIdentifyData(_In_ PIDE_REGISTERS Registers)
static PVOID AtaLegacyTranslateBusAddress(_In_ ULONG Address, _In_ ULONG NumberOfBytes, _Out_ PBOOLEAN IsAddressMmio)
#define ATA_TIME_DRQ_CLEAR
static BOOLEAN AtaLegacyClaimHardwareResources(_In_ PDRIVER_OBJECT DriverObject, _In_ PCM_RESOURCE_LIST ResourceList, _In_ ULONG ResourceListSize)
static VOID AtaLegacyMakeInterruptResource(_Out_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, _In_ ULONG Level)
static VOID AtaLegacyChannelTranslateResources(_Inout_ PCM_RESOURCE_LIST ResourceList, _In_ PUCHAR CommandPortBase, _In_ PUCHAR ControlPortBase)
#define ATA_WRITE(Port, Value)
#define ATA_TIME_RESET_SELECT
#define ATA_TIME_BUSY_IDENTIFY
struct _ATA_LEGACY_CHANNEL * PATA_LEGACY_CHANNEL
static VOID AtaLegacyReleaseHardwareResources(_In_ PDRIVER_OBJECT DriverObject)
#define ATA_TIME_BUSY_SELECT
#define CHANNEL_PCAT_RESOURCE_COUNT
static BOOLEAN AtaLegacyIdentifyDevice(_In_ PIDE_REGISTERS Registers, _In_ ULONG DeviceNumber, _In_ UCHAR Command)
#define ExFreePoolWithTag(_P, _T)
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
#define KeStallExecutionProcessor(MicroSeconds)
#define InitializeObjectAttributes(p, n, a, r, s)
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
#define CM_RESOURCE_PORT_IO
#define CM_RESOURCE_PORT_16_BIT_DECODE
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
#define RTL_REGISTRY_ABSOLUTE
#define RTL_QUERY_REGISTRY_REQUIRED
#define RTL_QUERY_REGISTRY_DIRECT
#define RTL_REGISTRY_HANDLE
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define STATUS_REVISION_MISMATCH
NTSTATUS NTAPI PciIdeXInitialize(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath, _In_ PCONTROLLER_PROPERTIES HwGetControllerProperties, _In_ ULONG ExtensionSize)
NTSTATUS NTAPI IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, IN ULONG DriverListSize OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PCM_RESOURCE_LIST DeviceList OPTIONAL, IN ULONG DeviceListSize OPTIONAL, OUT PBOOLEAN ConflictDetected)
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
#define OBJ_KERNEL_HANDLE
#define OBJ_CASE_INSENSITIVE
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
#define CmResourceTypePort
#define CM_RESOURCE_INTERRUPT_LATCHED
#define CmResourceTypeInterrupt
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.
struct _IO_RESOURCE_DESCRIPTOR::@2244::@2245 Port
union _IO_RESOURCE_DESCRIPTOR::@2244 u
Legacy detection interface with the PCIIDEX driver.
#define FIELD_OFFSET(t, f)
#define RtlZeroMemory(Destination, Length)
#define STATUS_UNSUCCESSFUL
#define STATUS_INSUFFICIENT_RESOURCES
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
_Must_inspect_result_ _In_ WDFCMRESLIST List
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
@ CmResourceShareDeviceExclusive
_In_ ULONG _In_ PHYSICAL_ADDRESS BusAddress
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes