1/* @title: ATA */
2#pragma once
3#include <block/block.h>
4#include <compiler.h>
5#include <log.h>
6#include <stdbool.h>
7#include <stdint.h>
8#include <sync/spinlock.h>
9#include <types/types.h>
10
11#define IDE_CMD_TIMEOUT_MS 5000 // Read/write sector
12#define IDE_IDENT_TIMEOUT_MS 10000 // Identify or cache flush
13#define IDE_RESET_TIMEOUT_MS 30000 // Controller reset or spin-up
14
15#define ATAPI_CMD_TIMEOUT_MS 8000 // Short packet commands
16#define ATAPI_SPINUP_TIMEOUT_MS 15000 // Spinning up disc or loading tray
17#define ATAPI_EJECT_TIMEOUT_MS 20000 // Eject/load tray or seek disc
18
19#define REG_DATA(base) (base + 0)
20#define REG_ERROR(base) (base + 1)
21#define REG_FEATURES(base) (base + 1)
22#define REG_SECTOR_COUNT(base) (base + 2)
23#define REG_LBA_LOW(base) (base + 3)
24#define REG_LBA_MID(base) (base + 4)
25#define REG_LBA_HIGH(base) (base + 5)
26#define REG_DRIVE_HEAD(base) (base + 6)
27#define REG_STATUS(base) (base + 7)
28#define REG_COMMAND(base) (base + 7)
29#define REG_ALT_STATUS(ctrl) (ctrl + 0)
30#define REG_CONTROL(ctrl) (ctrl + 0)
31
32#define STATUS_BSY 0x80
33#define STATUS_DRDY 0x40
34#define STATUS_DRQ 0x08
35#define STATUS_ERR 0x01
36#define STATUS_DF 0x20
37
38#define COMMAND_READ 0x20
39#define COMMAND_WRITE 0x30
40
41#define ATA_CMD_READ_PIO 0x20
42#define ATA_CMD_READ_PIO_EXT 0x24
43#define ATA_CMD_READ_DMA 0xC8
44#define ATA_CMD_READ_DMA_EXT 0x25
45#define ATA_CMD_WRITE_PIO 0x30
46#define ATA_CMD_WRITE_PIO_EXT 0x34
47#define ATA_CMD_WRITE_DMA 0xCA
48#define ATA_CMD_WRITE_DMA_EXT 0x35
49#define ATA_CMD_CACHE_FLUSH 0xE7
50#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
51#define ATA_CMD_PACKET 0xA0
52#define ATA_CMD_IDENTIFY_PACKET 0xA1
53#define ATA_CMD_IDENTIFY 0xEC
54
55#define ATA_PRIMARY_IO 0x1F0
56#define ATA_PRIMARY_CTRL 0x3F6
57#define ATA_SECONDARY_IO 0x170
58#define ATA_SECONDARY_CTRL 0x376
59
60struct pci_device;
61
62enum ide_type {
63 IDE_TYPE_ATA,
64 IDE_TYPE_ATAPI,
65};
66
67struct ide_request {
68 uint64_t lba;
69 void *buffer;
70 uint64_t size;
71 uint64_t sector_count;
72 uint16_t current_sector;
73
74 bool write;
75 volatile bool done;
76 int status;
77
78 void (*on_complete)(struct ide_request *);
79 void *user_data;
80
81 bool trigger_completion;
82 struct thread *waiter;
83 struct ide_request *next;
84 struct spinlock lock;
85};
86
87struct ide_channel {
88 struct ide_request *head;
89 struct ide_request *tail;
90
91 bool busy;
92 struct spinlock lock;
93 struct ata_drive *current_drive;
94};
95
96struct ata_drive {
97 bool actually_exists; // it picks everything up
98 uint32_t sector_size;
99 uint16_t io_base;
100 uint16_t ctrl_base;
101 uint16_t slave;
102 enum ide_type type;
103 void *identify_data;
104
105 char model[41]; // 40 chars + null
106 char serial[21]; // 20 chars + null
107 char firmware[9]; // 8 chars + null
108 uint64_t total_sectors;
109 uint8_t supports_lba48;
110 uint8_t supports_dma;
111 uint8_t udma_mode;
112 uint8_t pio_mode;
113 irq_t irq;
114 struct ide_channel channel;
115};
116
117#define IDE_RETRY_COUNT 3
118
119bool ide_read_sector_wrapper(struct block_device *d, uint64_t lba, uint8_t *buf,
120 uint64_t cnt);
121
122bool ide_write_sector_wrapper(struct block_device *d, uint64_t lba,
123 const uint8_t *buf, uint64_t cnt);
124
125uint8_t ide_detect_drives();
126
127bool ata_setup_drive(struct ata_drive *ide, struct pci_device *devices,
128 uint64_t count, int channel, bool is_slave);
129
130struct block_device *ide_create_generic(struct ata_drive *ide);
131
132void ide_identify(struct ata_drive *drive);
133void ide_print_info(struct block_device *d);
134
135struct ata_identify {
136 uint16_t config;
137 uint16_t cylinders;
138 uint16_t reserved1;
139 uint16_t heads;
140 uint16_t vendor1[2];
141 uint16_t sectors_per_track;
142 uint16_t vendor2[3];
143 uint16_t serial_number[10];
144 uint16_t vendor3[2];
145 uint16_t obsolete1;
146 uint16_t firmware_revision[4];
147 uint16_t model_number[20];
148 uint16_t max_rw_multiple;
149 uint16_t reserved2;
150 uint16_t capabilities[2];
151 uint16_t obsolete2[2];
152 uint16_t field_validity;
153 uint16_t current_cylinders;
154 uint16_t current_heads;
155 uint16_t current_sectors;
156 uint16_t current_capacity_lo;
157 uint16_t current_capacity_hi;
158 uint16_t rw_multiple;
159 uint32_t lba28_capacity;
160 uint16_t dma_supported;
161 uint16_t advanced_pio_modes;
162 uint16_t min_dma_cycle_time;
163 uint16_t recommended_dma_cycle_time;
164 uint16_t min_pio_cycle_time;
165 uint16_t min_pio_cycle_time_iordy;
166 uint16_t additional_supported;
167 uint16_t reserved3[5];
168 uint16_t queue_depth;
169 uint16_t sata_capabilities;
170 uint16_t sata_additional;
171 uint16_t sata_features_supported;
172 uint16_t sata_features_enabled;
173 uint16_t major_version;
174 uint16_t minor_version;
175 uint16_t command_set_supported[3];
176 uint16_t command_set_enabled[3];
177 uint16_t features_supported_extension;
178 uint16_t security_erase_time;
179 uint16_t enhanced_security_erase_time;
180 uint16_t current_advanced_power_mgmt;
181 uint16_t master_password_revision;
182 uint16_t hardware_reset_result;
183 uint16_t acoustic_management;
184 uint16_t stream_min_req_size;
185 uint16_t stream_transfer_time_dma;
186 uint16_t stream_access_latency;
187 uint32_t streaming_performance_gran;
188 uint64_t lba48_sector_count;
189 uint16_t streaming_transfer_time;
190 uint16_t dsm_cap;
191 uint16_t phys_log_sector_size;
192 uint16_t inter_seek_delay;
193 uint16_t world_wide_name[4];
194 uint16_t reserved4[144];
195} __packed;
196
197LOG_SITE_EXTERN(ide);
198LOG_HANDLE_EXTERN(ide);
199
200#define ide_log(log_level, fmt, ...) \
201 log(LOG_SITE(ide), LOG_HANDLE(ide), log_level, fmt, ##__VA_ARGS__)
202
203void ata_ident_print(struct ata_identify *id);
204void ata_select_drive(struct ata_drive *ata_drive);
205void ata_soft_reset(struct ata_drive *ata_drive);
206bool atapi_identify(struct ata_drive *ide);
207void ata_init(struct pci_device *devices, uint64_t count);
208enum irq_result ide_irq_handler(void *ctx, irq_t irq_num,
209 struct irq_context *ct);
210void ide_reorder(struct block_device *disk);
211bool ide_submit_bio_async(struct block_device *d, struct bio_request *b);
212struct block_device *atapi_create_generic(struct ata_drive *d);
213