123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- /*++
- Copyright (c) 2014 Minoca Corp. All Rights Reserved
- Module Name:
- ata.h
- Abstract:
- This header contains definitions for the AT Attachment (ATA) driver.
- Author:
- Evan Green 4-Jun-2014
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define ATA_ALLOCATION_TAG 0x21617441 // '!atA'
- #define ATA_CABLE_COUNT 2
- #define ATA_CHILD_COUNT (2 * ATA_CABLE_COUNT)
- #define ATA_SECTOR_SIZE 512
- #define ATA_MAX_LBA28_SECTOR_COUNT 0x100
- #define ATA_MAX_LBA48_SECTOR_COUNT 0x10000
- //
- // Define the timeout in seconds before an ATA command expires.
- //
- #define ATA_TIMEOUT 60
- //
- // Define the timeout in microseconds before a device selection fails.
- //
- #define ATA_SELECT_TIMEOUT (60 * MICROSECONDS_PER_MILLISECOND)
- //
- // Define the amount of time in microseconds to wait for the selected device to
- // set the status appropriately.
- //
- #define ATA_SELECT_STALL MICROSECONDS_PER_MILLISECOND
- //
- // Define the known locations of the ATA controller if the PCI BARs did not
- // seem to specify them.
- //
- #define ATA_LEGACY_PRIMARY_IO_BASE 0x1F0
- #define ATA_LEGACY_PRIMARY_CONTROL_BASE 0x3F6
- #define ATA_LEGACY_SECONDARY_IO_BASE 0x170
- #define ATA_LEGACY_SECONDARY_CONTROL_BASE 0x376
- #define ATA_LEGACY_IO_SIZE 8
- #define ATA_LEGACY_CONTROL_SIZE 4
- //
- // Define the legacy interrupts assigned to the disk controller.
- //
- #define ATA_LEGACY_PRIMARY_INTERRUPT 14
- #define ATA_LEGACY_SECONDARY_INTERRUPT 15
- #define ATA_LEGACY_INTERRUPT_CHARACTERISTICS INTERRUPT_LINE_EDGE_TRIGGERED
- #define ATA_LEGACY_VECTOR_CHARACTERISTICS INTERRUPT_VECTOR_EDGE_TRIGGERED
- //
- // Define values that come out of the LBA1 and LBA2 registers when ATAPI or
- // SATA devices are interrogated using an ATA IDENTIFY command.
- //
- #define ATA_PATAPI_LBA1 0x14
- #define ATA_PATAPI_LBA2 0xEB
- #define ATA_SATAPI_LBA1 0x69
- #define ATA_SATAPI_LBA2 0x96
- #define ATA_SATA_LBA1 0x3C
- #define ATA_SATA_LBA2 0xC3
- //
- // Define the maximum LBA for the LBA28 command set.
- //
- #define ATA_MAX_LBA28 0x0FFFFFFFULL
- //
- // Define the total size of the PRDT for all four disks.
- //
- #define ATA_PRDT_TOTAL_SIZE 0x1000
- #define ATA_PRDT_DISK_SIZE (ATA_PRDT_TOTAL_SIZE / ATA_CABLE_COUNT)
- //
- // Define the boundary that DMA PRDT entries must not cross.
- //
- #define ATA_DMA_BOUNDARY 0x10000
- //
- // Define the flag set in the PRDT entry for the last descriptor.
- //
- #define ATA_DMA_LAST_DESCRIPTOR 0x8000
- //
- // Define conversions between the ATA register enum and the actual base
- // register segments.
- //
- #define ATA_HIGH_ADDRESSING_OFFSET (AtaRegisterSectorCountHigh - 2)
- #define ATA_HIGH_REGISTER_COUNT 4
- #define ATA_CONTROL_REGISTER_OFFSET \
- (ATA_HIGH_ADDRESSING_OFFSET + ATA_HIGH_ADDRESSING_OFFSET)
- #define ATA_BUS_MASTER_REGISTER_OFFSET AtaRegisterBusMasterCommand
- #define ATA_BUS_MASTER_TABLE_REGISTER 0x4
- //
- // ATA Status register definitions.
- //
- #define ATA_STATUS_ERROR 0x01
- #define ATA_STATUS_INDEX 0x02
- #define ATA_STATUS_CORRECTED_ERROR 0x04
- #define ATA_STATUS_DATA_REQUEST 0x08
- #define ATA_STATUS_SEEK_COMPLETE 0x10
- #define ATA_STATUS_FAULT 0x20
- #define ATA_STATUS_DRIVE_READY 0x40
- #define ATA_STATUS_BUSY 0x80
- #define ATA_STATUS_BUSY_MASK (ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST)
- #define ATA_STATUS_ERROR_MASK (ATA_STATUS_ERROR | ATA_STATUS_FAULT)
- //
- // Define ATA control register bits.
- //
- #define ATA_CONTROL_HIGH_ORDER 0x80
- #define ATA_CONTROL_SOFTWARE_RESET 0x04
- #define ATA_CONTROL_INTERRUPT_DISABLE 0x02
- //
- // Define ATA drive select register bits.
- //
- #define ATA_DRIVE_SELECT_LBA 0x40
- #define ATA_DRIVE_SELECT_MASTER 0xA0
- #define ATA_DRIVE_SELECT_SLAVE 0xB0
- //
- // IDE Bus Master Status Register definitions.
- //
- //
- // Set if the drive is active.
- //
- #define IDE_STATUS_ACTIVE 0x01
- //
- // Set if the last operation had an error.
- //
- #define IDE_STATUS_ERROR 0x02
- //
- // Set if the INTRQ signal is asserted.
- //
- #define IDE_STATUS_INTERRUPT 0x04
- //
- // Set if drive 0 can do DMA.
- //
- #define IDE_STATUS_DRIVE0_DMA 0x20
- //
- // Set if drive 1 can do DMA.
- //
- #define IDE_STATUS_DRIVE1_DMA 0x40
- //
- // Set if only simplex operations are supported.
- //
- #define IDE_STATUS_SIMPLEX_ONLY 0x80
- //
- // Define the IDE programming interface register offset and bits.
- //
- #define IDE_INTERFACE_OFFSET 8
- #define IDE_INTERFACE_SIZE sizeof(USHORT)
- #define IDE_INTERFACE_PRIMARY_NATIVE_SUPPORTED 0x0800
- #define IDE_INTERFACE_PRIMARY_NATIVE_ENABLED 0x0400
- #define IDE_INTERFACE_SECONDARY_NATIVE_SUPPORTED 0x0200
- #define IDE_INTERFACE_SECONDARY_NATIVE_ENABLED 0x0100
- //
- // Define the bus master command bits.
- //
- #define ATA_BUS_MASTER_COMMAND_DMA_ENABLE 0x01
- #define ATA_BUS_MASTER_COMMAND_DMA_READ 0x08
- //
- // Define ATA supported command set bits.
- //
- #define ATA_SUPPORTED_COMMAND_LBA48 (1 << 26)
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- typedef enum _ATA_CONTEXT_TYPE {
- AtaContextInvalid,
- AtaControllerContext,
- AtaChildContext
- } ATA_CONTEXT_TYPE, *PATA_CONTEXT_TYPE;
- typedef struct _ATA_CONTROLLER ATA_CONTROLLER, *PATA_CONTROLLER;
- typedef struct _ATA_CHILD ATA_CHILD, *PATA_CHILD;
- //
- // Define the ATA registers. Values >= 7 go the control base.
- //
- typedef enum _ATA_REGISTER {
- AtaRegisterData = 0x0,
- AtaRegisterError = 0x1,
- AtaRegisterFeatures = 0x1,
- AtaRegisterSectorCountLow = 0x2,
- AtaRegisterLba0 = 0x3,
- AtaRegisterLba1 = 0x4,
- AtaRegisterLba2 = 0x5,
- AtaRegisterDeviceSelect = 0x6,
- AtaRegisterCommand = 0x7,
- AtaRegisterStatus = 0x7,
- AtaRegisterSectorCountHigh = 0x8,
- AtaRegisterLba3 = 0x9,
- AtaRegisterLba4 = 0xA,
- AtaRegisterLba5 = 0xB,
- AtaRegisterControl = 0xC,
- AtaRegisterAlternateStatus = 0xC,
- AtaRegisterDeviceAddress = 0xD,
- AtaRegisterBusMasterCommand = 0xE,
- AtaRegisterBusMasterStatus = 0x10,
- AtaRegisterBusMasterTableAddress = 0x12,
- } ATA_REGISTER, *PATA_REGISTER;
- typedef enum _ATA_COMMAND {
- AtaCommandReadPio28 = 0x20,
- AtaCommandReadPio48 = 0x24,
- AtaCommandReadDma48 = 0x25,
- AtaCommandWritePio28 = 0x30,
- AtaCommandWritePio48 = 0x34,
- AtaCommandWriteDma48 = 0x35,
- AtaCommandPacket = 0xA0,
- AtaCommandIdentifyPacket = 0xA1,
- AtaCommandReadDma28 = 0xC8,
- AtaCommandWriteDma28 = 0xCA,
- AtaCommandCacheFlush28 = 0xE7,
- AtaCommandCacheFlush48 = 0xEA,
- AtaCommandIdentify = 0xEC,
- } ATA_COMMAND, *PATA_COMMAND;
- /*++
- Structure Description:
- This structure defines the Physical Region Descriptor Table format, which
- tells the ATA bus mastering controller where the memory is to DMA to.
- Members:
- PhysicalAddress - Stores the physical address to DMA to. This buffer
- cannot cross a 64k boundary.
- Size - Stores the size of the region in bytes. 0 is 64k.
- Flags - Stores flags, which should all be zero except the most significant
- bit, which indicates that this is the last entry in the PRDT.
- --*/
- typedef struct _ATA_PRDT {
- ULONG PhysicalAddress;
- USHORT Size;
- USHORT Flags;
- } PACKED ATA_PRDT, *PATA_PRDT;
- /*++
- Structure Description:
- This structure defines register bases for one ATA channel.
- Members:
- IoBase - Supplies the base I/O port of the I/O registers used for issuing
- ATA commands.
- ControlBase - Supplies the base I/O port of the control registers.
- BusMasterBase - Supplies the base I/O port of the bus master registers.
- InterruptDisable - Stores the bit to OR in to the control mask to indicate
- if interrupts are disabled or not.
- SelectedDevice - Stores the currently selected device.
- Lock - Stores a pointer to the lock used to synchronize this channel.
- Irp - Stores a pointer to the I/O IRP actively running on the channel.
- IoSize - Stores the size of this I/O operation.
- OwningChild - Stores a pointer to the child that has the channel locked.
- Prdt - Stores a pointer to the array of Physical Region Descriptor Table
- entries.
- PrdtPhysicalAddress - Stores the physical address of the PRDT.
- --*/
- typedef struct _ATA_CHANNEL {
- USHORT IoBase;
- USHORT ControlBase;
- USHORT BusMasterBase;
- UCHAR InterruptDisable;
- UCHAR SelectedDevice;
- PQUEUED_LOCK Lock;
- PIRP Irp;
- UINTN IoSize;
- PATA_CHILD OwningChild;
- PATA_PRDT Prdt;
- PHYSICAL_ADDRESS PrdtPhysicalAddress;
- } ATA_CHANNEL, *PATA_CHANNEL;
- /*++
- Structure Description:
- This structure defines state associated with an ATA child device (the
- bus driver's context for a disk itself).
- Members:
- Type - Stores the context type.
- Controller - Stores a pointer back up to the controller.
- Channel - Stores a pointer to the channel context.
- OsDevice - Stores a pointer to the OS device.
- Slave - Stores whether or not this device is the slave device or the master
- device.
- DmaSupported - Stores a boolean indicating whether or not this device
- supports DMA transfers.
- Lba48Supported - Stores a boolean indicating whether or not LBA48 is
- supported.
- TotalSectors - Stores the total number of sectors in the device.
- DiskInterface - Stores the disk interface.
- --*/
- struct _ATA_CHILD {
- ATA_CONTEXT_TYPE Type;
- PATA_CONTROLLER Controller;
- PATA_CHANNEL Channel;
- PDEVICE OsDevice;
- UCHAR Slave;
- BOOL DmaSupported;
- BOOL Lba48Supported;
- ULONGLONG TotalSectors;
- DISK_INTERFACE DiskInterface;
- };
- /*++
- Structure Description:
- This structure defines state associated with an ATA controller.
- Members:
- Type - Stores the context type.
- PrimaryInterruptLine - Stores the interrupt line that this controller's
- primary (or only) interrupt comes in on.
- SecondaryInterruptLine - Stores the secondary interrupt line for the
- controller.
- PrimaryInterruptVector - Stores the interrupt vector that this controller's
- primary interrupt comes in on.
- SecondaryInterruptVector - Stores the secondary interrupt vector.
- PrimaryInterruptFound - Stores a boolean indicating whether or not the
- primary interrupt line and interrupt vector fields are valid.
- SecondaryInterruptFound - Stores a boolean indicating whether or not
- secondary interrupt resources were found.
- SkipFirstInterrupt - Stores a boolean indicating whether or not to skip the
- first interrupt line resource found in favor of legacy ones later.
- PrimaryInterruptHandle - Stores a pointer to the handle received when the
- primary interrupt was connected. If the device only has one interrupt,
- it will be this one.
- SecondaryInterruptHandle - Stores a pointer to the handle received when
- the secondary interrupt was connected. This is only used in
- "compatibility" mode.
- Handle - Stores a pointer to the interrupt handle.
- PrimaryLock - Stores a pointer to the lock serializing access to the primary
- registers.
- SecondaryLock - Stores a pointer to the lock serializing access to the
- secondary registers.
- DpcLock - Stores a spinlock used to serialize DPC execution.
- Channel - Stores the array (size two) of ATA channels.
- PciConfigInterface - Stores the interface to access PCI configuration space.
- PciConfigInterfaceAvailable - Stores a boolean indicating if the PCI
- config interface is actively available.
- RegisteredForPciConfigInterfaces - Stores a boolean indicating whether or
- not the driver has regsistered for PCI Configuration Space interface
- access.
- Interface - Stores the programming interface of the controller.
- PrdtIoBuffer - Stores a pointer to the I/O buffer containing the
- physical region descriptor table.
- PendingStatus - Stores the pending bus master status register bits. The
- secondary controller's bits are shifted left by 8.
- --*/
- struct _ATA_CONTROLLER {
- ATA_CONTEXT_TYPE Type;
- ULONGLONG PrimaryInterruptLine;
- ULONGLONG SecondaryInterruptLine;
- ULONGLONG PrimaryInterruptVector;
- ULONGLONG SecondaryInterruptVector;
- BOOL PrimaryInterruptFound;
- BOOL SecondaryInterruptFound;
- BOOL SkipFirstInterrupt;
- HANDLE PrimaryInterruptHandle;
- HANDLE SecondaryInterruptHandle;
- KSPIN_LOCK DpcLock;
- ATA_CHANNEL Channel[ATA_CABLE_COUNT];
- PDEVICE ChildDevices[ATA_CHILD_COUNT];
- ATA_CHILD ChildContexts[ATA_CHILD_COUNT];
- INTERFACE_PCI_CONFIG_ACCESS PciConfigInterface;
- BOOL PciConfigInterfaceAvailable;
- BOOL RegisteredForPciConfigInterfaces;
- USHORT Interface;
- PIO_BUFFER PrdtIoBuffer;
- volatile ULONG PendingStatusBits;
- };
- /*++
- Structure Description:
- This structure defines the result of an IDENTIFY DEVICE command sent to a
- drive.
- Members:
- Configuration - Stores configuration information about the device such as
- whether it's a removable device and whether it's an ATA device.
- SerialNumber - Stores a 20 byte ASCII string representing the device's
- serial number.
- FirmwareRevision - Stores an 8 byte ASCII string representing the device's
- firmware revision.
- ModelNumber - Stores a 40 byte ASCII string representing the device model.
- MaxMultipleSectorTransfer - Stores the maximum number of sectors that can
- be transferred per interrupt on READ/WRITE MULTIPLE commands.
- Capabilities - Stores device capability bits such as whether LBA is
- supported, IORDY is supporetd, DMA is supported, etc.
- ValidFields - Stores bits indicating whether the words in fields 64-70 and
- word 88 are valid.
- CurrentMaxSectorTransfer - Stores the current setting for the number of
- sectors that can be transferred per interrupts on a READ/WRITE MULTIPLE
- command.
- TotalSectors - Stores the total number of user addressable sectors. If the
- LBA48 command set is supported, use that value instead of this one.
- MultiwordDmaSettings - Stores which Multiword DMA modes are supported, and
- which mode is selected.
- PioModesSupported - Stores which Polled I/O modes are supported on this
- device.
- MinMultiwordTransferCycles - Stores the minimum Multiword DMA transfer
- cycle time in nanoseconds.
- RecommendedMultiwordTransferCycles - Stores the manufacturer's
- recommended Multiword DMA transfer cycle time in nanoseconds.
- MinPioTransferCyclesNoFlow - Stores the minimum PIO transfer cycle time
- without flow control, in nanoseconds.
- MinPioTransferCyclesWithFlow - Stores the minimum PIO transfer cycle time
- with IORDY flow control, in nanoseconds.
- QueueDepth - Stores the maximum queue depth minus one.
- MajorVersion - Stores the major version of the ATA/ATAPI protocol
- supported.
- MinorVersion - Stores the device minor version.
- CommandSetSupported - Stores the command/feature sets that are supported on
- this device.
- FeatureSetSupported - Stores the command/feature extensions that are
- supported on this device.
- CommandSetEnabled - Stores a bitmask showing which command/features sets
- are currently enabled.
- CommandSetDefault - Stores the default features enabled.
- UltraDmaSettings - Stores which Ultra DMA modes are supported and currently
- enabled on this device.
- SecurityEraseTime - Stores the time required for security erase unit
- completion.
- EnhancedSecurityEraseTime - Stores the time required for enhanced security
- erase completion.
- CurrentPowerManagementValue - Stores the current power managment value.
- PasswordRevisionCode - Stores the Master Password Revision Code.
- ResetResult - Stores various statistics about how the drives behaved during
- a hardware reset.
- AcousticManagement - Stores the recommended and current acoustic
- management value.
- TotalSectorsLba48 - Stores the one beyond the maximum valid block number if
- the LBA48 command set is supported.
- RemovableMediaStatus - Stores whether or not the removable media status
- notification feature set is supported.
- SecurityStatus - Stores the current security state of the drive.
- PowerMode1 - Stores whether or not the CFA power mode 1 is supported or
- required for some commands.
- MediaSerialNumber - Stores the current media serial number.
- Checksum - Stores the two's complement of the sum of all bytes in words
- 0-254 and the byte in bits 0-7 of word 255, if bits 0-7 of word 255
- contains the value 0xA5. Each byte shall be added with unsigned
- arithmetic, and overflow shall be ignored. The sum of all 512 bytes is
- zero when the checksum is correct.
- --*/
- typedef struct _ATA_IDENTIFY_PACKET {
- USHORT Configuration;
- USHORT Reserved1[9];
- CHAR SerialNumber[20];
- USHORT Reserved2[3];
- CHAR FirmwareRevision[8];
- CHAR ModelNumber[40];
- USHORT MaxMultipleSectorTransfer;
- USHORT Reserved3;
- ULONG Capabilities;
- USHORT Reserved4[2];
- USHORT ValidFields;
- USHORT Reserved5[5];
- USHORT CurrentMaxSectorTransfer;
- ULONG TotalSectors;
- USHORT Reserved6;
- USHORT MultiwordDmaSettings;
- USHORT PioModesSupported;
- USHORT MinMultiwordTransferCycles;
- USHORT RecommendedMultiwordTransferCycles;
- USHORT MinPioTransferCyclesNoFlow;
- USHORT MinPioTransferCyclesWithFlow;
- USHORT Reserved7[6];
- USHORT QueueDepth;
- USHORT Reserved8[4];
- USHORT MajorVersion;
- USHORT MinorVersion;
- ULONG CommandSetSupported;
- USHORT FeatureSetSupported;
- ULONG CommandSetEnabled;
- USHORT CommandSetDefault;
- USHORT UltraDmaSettings;
- USHORT SecurityEraseTime;
- USHORT EnhancedSecurityEraseTime;
- USHORT CurrentPowerManagementValue;
- USHORT PasswordRevisionCode;
- USHORT ResetResult;
- USHORT AcousticManagement;
- USHORT Reserved9[5];
- ULONGLONG TotalSectorsLba48;
- USHORT Reserved10[23];
- USHORT RemovableMediaStatus;
- USHORT SecurityStatus;
- USHORT Reserved11[31];
- USHORT PowerMode1;
- USHORT Reserved12[15];
- USHORT MediaSerialNumber[30];
- USHORT Reserved13[49];
- USHORT Checksum;
- } PACKED ATA_IDENTIFY_PACKET, *PATA_IDENTIFY_PACKET;
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // -------------------------------------------------------- Function Prototypes
- //
|