11#define ATADEV_UNKNOWN 0x000
12#define ATADEV_NOTFOUND 0x001
13#define ATADEV_PATA 0x002
14#define ATADEV_SATA 0x003
15#define ATADEV_PATAPI 0x004
16#define ATADEV_SATAPI 0x005
19#define ATA_PIO_PRI_PORT_BASE 0x1F0
20#define ATA_PIO_PRI_PORT_CONTROL 0x3F6
21#define ATA_PIO_SEC_PORT_BASE 0x170
22#define ATA_PIO_SEC_PORT_CONTROL 0x376
25#define ATA_REG_DATA 0x00
26#define ATA_REG_ERROR 0x01
27#define ATA_REG_FEATURES 0x01
28#define ATA_REG_SECCOUNT0 0x02
29#define ATA_REG_LBA0 0x03
30#define ATA_REG_LBA1 0x04
31#define ATA_REG_LBA2 0x05
32#define ATA_REG_HDDEVSEL 0x06
33#define ATA_REG_CMD 0x07
34#define ATA_REG_STATUS 0x07
35#define ATA_REG_SECCOUNT1 0x08
36#define ATA_REG_LBA3 0x09
37#define ATA_REG_LBA4 0x0A
38#define ATA_REG_LBA5 0x0B
39#define ATA_REG_CONTROL 0x0C
40#define ATA_REG_ALTSTATUS 0x0C
41#define ATA_REG_DEVADDRESS 0x0D
44#define ATA_CMD_RESET 0x04
45#define ATA_CMD_READ_SECTORS 0x20
46#define ATA_CMD_READ_SECTORS_EXT 0x24
47#define ATA_CMD_WRITE_SECTORS 0x30
48#define ATA_CMD_WRITE_SECTORS_EXT 0x34
49#define ATA_CMD_READ_DMA 0xC8
50#define ATA_CMD_READ_DMA_EXT 0x25
51#define ATA_CMD_WRITE_DMA 0xCA
52#define ATA_CMD_WRITE_DMA_EXT 0x35
53#define ATA_CMD_CACHE_FLUSH 0xE7
54#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
55#define ATA_CMD_PACKET 0xA0
56#define ATA_CMD_IDENTIFY_PACKET 0xA1
57#define ATA_CMD_IDENTIFY 0xEC
59#define ATA_DRIVE_LBA48 0x40
62#define ATA_STATUS_BSY 0x80
63#define ATA_STATUS_DRDY 0x40
64#define ATA_STATUS_DF 0x20
65#define ATA_STATUS_DSC 0x10
66#define ATA_STATUS_DRQ 0x08
67#define ATA_STATUS_CORR 0x04
68#define ATA_STATUS_IDX 0x02
69#define ATA_STATUS_ERR 0x01
72#define ATA_ERROR_BBK 0x080
73#define ATA_ERROR_UNC 0x040
74#define ATA_ERROR_MC 0x020
75#define ATA_ERROR_IDNF 0x010
76#define ATA_ERROR_MCR 0x008
77#define ATA_ERROR_ABRT 0x004
78#define ATA_ERROR_TK0NF 0x002
79#define ATA_ERROR_AMNF 0x001
82#define ATA_IDENT_DEVICETYPE 0
83#define ATA_IDENT_CYLINDERS 2
84#define ATA_IDENT_HEADS 6
85#define ATA_IDENT_SECTORS 12
86#define ATA_IDENT_SERIAL 20
87#define ATA_IDENT_MODEL 54
88#define ATA_IDENT_CAPABILITIES 98
89#define ATA_IDENT_FIELDVALID 106
90#define ATA_IDENT_MAX_LBA 120
91#define ATA_IDENT_COMMANDSETS 164
92#define ATA_IDENT_MAX_LBA_EXT 200
95#define ATA_CAP_DMA 0x100
96#define ATA_CAP_LBA 0x200
99#define ATA_MODE_CHS 0x10
100#define ATA_MODE_LBA28 0x20
101#define ATA_MODE_LBA48 0x40
104#include <aquila/errno.h>
164 default:
return "Unknown";
173 for (
int i = 0; i < 4; ++i)
180#define ATA_TIMEOUT 1000000
199 printk(
"ata: drive busy, not answering\n");
203 if (advanced_check) {
212 printk(
"ata: drive error: DRQ not set\n");
static uint8_t io_in8(struct ioaddr *io, uintptr_t off)
Reads an 8-, 16- or 32-bit register.
void ata_select_drive(struct ata_drive *drive, uint32_t mode)
Selects a drive on its channel, for an addressing mode, if it isn't selected so already,...
void ata_setup(struct ata_drive *drive, uint64_t lba, size_t count)
Writes the registers of a command on count sectors from lba: the drive, the address and the count.
void ata_reset(struct ata_drive *drive)
Resets both drives on a drive's channel, and waits until they are done.
void dma_irq(struct ata_channel *channel)
Handles a channel's interrupt.
void pio_init(struct ata_drive *drive)
Sets a drive up for PIO, and resets its channel.
static int ata_poll(struct ata_drive *drive, int advanced_check)
Waits until a drive is done with what it was doing (BSY clears).
static void ata_wait(struct ata_drive *drive)
Waits about 400 ns, as a drive needs after a command, by reading the alternate status register four t...
int dma_init(struct ata_drive *drive)
Sets a drive up for DMA, if both the drive and its channel's controller can do it.
static const char * ata_error_string(uint8_t err)
Returns the name of an error, from the error register.
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
unsigned long long int uint64_t
unsigned short int uint16_t
An IDE channel, with the master and slave drives on it.
int busy
one command at a time: whether one is running, and the requests waiting for the channel
struct ioaddr base
the command block's registers, and the bus master's for DMA (whose address is 0 if the controller has...
struct waitq irq_wait
the DMA transfer waiting for the interrupt, and what it found
ssize_t(*) read(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
struct ata_channel * channel
int(*) flush(struct ata_drive *drive)
ssize_t(*) write(struct ata_drive *drive, uint64_t lba, size_t count, void *buf)
Where a device's registers are.