3 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0)
4 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1)
5 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2)
6 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3)
7 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4)
8 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5)
9 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6)
10 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7)
11 #define reg_command(CHANNEL) reg_status (CHANNEL)
12 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206)
13 #define reg_alt(CHANNEL) reg_ctl (CHANNEL)
15 /* Alternate Status Register bits. */
25 /* Control Register bits. */
29 /* Device Register bits. */
30 #define DEV_MBS 0xa0 /* Must be set. */
31 #define DEV_LBA 0x40 /* Linear based addressing. */
32 #define DEV_DEV 0x10 /* Select device: 0=master, 1=slave. */
35 #define CMD_IDENTIFY 0xec /* IDENTIFY DEVICE. */
40 struct channel *channel;
44 disk_sector_no capacity;
55 #define CHANNEL_CNT (sizeof channels / sizeof *channels)
56 static struct channel channels[2] = {
62 select_device (struct device *d)
64 struct channel *c = d->channel;
65 uint8_t dev = DEV_MBS;
68 outb (reg_device (c), dev);
74 wait_idle (struct device *d)
78 for(i = 0; i < 1000; i++)
80 if ((inb (reg_status (d->channel)) & (STA_BUSY | STA_DRQ)) == 0)
85 printk ("%s: idle timeout\n", d->name);
89 select_device_wait (struct device *d)
97 busy_wait (struct channel *c)
101 for (i = 0; i < 3000; i++)
104 printk ("%s: busy, waiting...");
105 if (!(inb (reg_alt (c)) & ALT_BSY))
114 printk ("failed\n", c->name);
119 reset_channel (struct channel *c)
123 /* The ATA reset sequence depends on which devices are present,
124 so we start by detecting device presence. */
125 for (device = 0; device < 2; device++)
127 struct disk *d = &c->dev[device];
131 outb (reg_nsect (c), 0x55);
132 outb (reg_lbal (c), 0xaa);
134 outb (reg_nsect (c), 0xaa);
135 outb (reg_lbal (c), 0x55);
137 outb (reg_nsect (c), 0x55);
138 outb (reg_lbal (c), 0xaa);
140 present[device] = (inb (reg_nsect (c)) == 0x55
141 && inb (reg_lbal (c)) == 0xaa);
144 /* Issue soft reset sequence, which selects device 0 as a side effect.
145 Also enable interrupts. */
146 outb (reg_ctl (c), 0);
148 outb (reg_ctl (c), CTL_SRST);
150 outb (reg_ctl (c), 0);
153 /* Wait for device 0 to clear BSY. */
156 select_device (c->dev[0]);
160 /* Wait for device 1 to clear BSY. */
163 select_device (c->dev[1]);
164 for (i = 0; i < 3000; i++)
166 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
175 check_ata_device (const struct device *d)
177 struct channel *c = d->channel;
178 bool maybe_slave; /* If D is a master, could a slave exist? */
179 uint8_t error, lbam, lbah;
183 error = inb (reg_error (c));
184 lbam = inb (reg_lbam (c));
185 lbah = inb (reg_lbah (c));
187 if (error != 1 && (error != 0x81 || d->device == 1))
190 return error != 0x81;
194 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
200 execute_command (struct disk *d, uint8_t command)
202 struct channel *c = d->channel;
204 /* Interrupts must be enabled or our semaphore will never be
205 up'd by the completion handler. */
206 ASSERT (intr_get_level () == IF_ON);
209 sema_init (&completion_sema, 0, "disk");
212 outb (reg_command (c), command);
218 identify_ata_device (struct disk *d)
220 struct channel *c = d->channel;
224 select_device_wait (d);
225 execute_command (CMD_IDENTIFY);
236 for (c = channels; c < channels + CHANNEL_CNT; c++)
240 /* Register interrupt handler. */
243 /* Initialize device state. */
244 for (device = 0; device < 2; device++)
246 struct disk *d = &c->dev[device];
251 /* Reset hardware. */
254 /* Detect ATA devices. */
255 if (check_ata_device (&c->dev[0]))
256 check_ata_device (&c->dev[1]);
258 /* Detect device properties. */
259 for (device = 0; device < 2; device++)
260 if (c->dev[device].is_ata)
261 identify_ata_device (&c->dev[device]);
268 ASSERT (idx >= 0 && idx < 4);
269 return &channel[idx / 2].dev[idx % 2];
272 disk_sector_no disk_size (struct disk *);
273 void disk_read (struct disk *, disk_sector_no, void *);
274 void disk_write (struct disk *, disk_sector_no, const void *);