10 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0)
11 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1)
12 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2)
13 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3)
14 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4)
15 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5)
16 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6)
17 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7)
18 #define reg_command(CHANNEL) reg_status (CHANNEL)
19 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206)
20 #define reg_alt_status(CHANNEL) reg_ctl (CHANNEL)
22 /* Alternate Status Register bits. */
32 /* Control Register bits. */
36 /* Device Register bits. */
37 #define DEV_MBS 0xa0 /* Must be set. */
38 #define DEV_LBA 0x40 /* Linear based addressing. */
39 #define DEV_DEV 0x10 /* Select device: 0=master, 1=slave. */
42 #define CMD_IDENTIFY 0xec /* IDENTIFY DEVICE. */
47 struct channel *channel;
51 disk_sector_no capacity;
60 bool expecting_interrupt;
61 struct semaphore completion_wait;
66 #define CHANNEL_CNT (sizeof channels / sizeof *channels)
67 static struct channel channels[2];
70 select_device (const struct disk *d)
72 struct channel *c = d->channel;
73 uint8_t dev = DEV_MBS;
76 outb (reg_device (c), dev);
77 inb (reg_alt_status (c));
82 wait_idle (const struct disk *d)
86 for(i = 0; i < 1000; i++)
88 if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
93 printk ("%s: idle timeout\n", d->name);
97 select_device_wait (const struct disk *d)
104 /* Wait up to 30 seconds for disk D to clear BSY. */
106 busy_wait (const struct disk *d)
108 struct channel *c = d->channel;
111 for (i = 0; i < 3000; i++)
114 printk ("%s: busy, waiting...", d->name);
115 if (!(inb (reg_alt_status (c)) & STA_BSY))
129 reset_channel (struct channel *c)
134 /* The ATA reset sequence depends on which devices are present,
135 so we start by detecting device presence. */
136 for (device = 0; device < 2; device++)
138 struct disk *d = &c->dev[device];
142 outb (reg_nsect (c), 0x55);
143 outb (reg_lbal (c), 0xaa);
145 outb (reg_nsect (c), 0xaa);
146 outb (reg_lbal (c), 0x55);
148 outb (reg_nsect (c), 0x55);
149 outb (reg_lbal (c), 0xaa);
151 present[device] = (inb (reg_nsect (c)) == 0x55
152 && inb (reg_lbal (c)) == 0xaa);
155 /* Issue soft reset sequence, which selects device 0 as a side effect.
156 Also enable interrupts. */
157 outb (reg_ctl (c), 0);
159 outb (reg_ctl (c), CTL_SRST);
161 outb (reg_ctl (c), 0);
165 /* Wait for device 0 to clear BSY. */
168 select_device (&c->dev[0]);
169 busy_wait (&c->dev[0]);
172 /* Wait for device 1 to clear BSY. */
177 select_device (&c->dev[1]);
178 for (i = 0; i < 3000; i++)
180 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
184 busy_wait (&c->dev[1]);
189 check_ata_device (struct disk *d)
191 struct channel *c = d->channel;
192 uint8_t error, lbam, lbah;
196 error = inb (reg_error (c));
197 lbam = inb (reg_lbam (c));
198 lbah = inb (reg_lbah (c));
200 if (error != 1 && (error != 0x81 || d->device == 1))
203 return error != 0x81;
207 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
213 execute_command (struct disk *d, uint8_t command)
215 struct channel *c = d->channel;
217 /* Interrupts must be enabled or our semaphore will never be
218 up'd by the completion handler. */
219 ASSERT (intr_get_level () == IF_ON);
221 /* Atomically note that we expect an interrupt and send the
222 command to the device. */
224 c->expecting_interrupt = true;
225 outb (reg_command (c), command);
228 /* Wait for the command to complete. */
229 sema_down (&c->completion_wait);
233 input_sector (struct channel *c, void *sector)
237 ASSERT (sector != NULL);
239 status = inb (reg_status (c));
240 if (status & STA_DRQ)
242 /* Command was successful. Read data into SECTOR. */
243 insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
248 /* Command failed. */
254 identify_ata_device (struct disk *d)
256 uint16_t id[DISK_SECTOR_SIZE / 2];
260 select_device_wait (d);
261 execute_command (d, CMD_IDENTIFY);
264 if (!input_sector (d->channel, id))
270 d->capacity = id[57] | ((uint32_t) id[58] << 16);
271 printk ("%s: detected %"PRDSNu" sector (%d MB) disk\n",
272 d->name, d->capacity, d->capacity * DISK_SECTOR_SIZE / 1024 / 1024);
276 interrupt_handler (struct intr_frame *f)
280 for (c = channels; c < channels + CHANNEL_CNT; c++)
281 if (f->vec_no == c->irq)
283 if (c->expecting_interrupt)
284 sema_up (&c->completion_wait);
286 printk ("%s: unexpected interrupt\n", c->name);
298 for (channel = 0; channel < CHANNEL_CNT; channel++)
300 struct channel *c = &channels[channel];
303 /* Initialize channel. */
304 snprintf (c->name, sizeof c->name, "ide%d", channel);
318 c->expecting_interrupt = false;
319 sema_init (&c->completion_wait, 0, c->name);
321 /* Initialize devices. */
322 for (device = 0; device < 2; device++)
324 struct disk *d = &c->dev[device];
325 snprintf (d->name, sizeof d->name, "%s:%d", c->name, device);
333 /* Register interrupt handler. */
334 intr_register (c->irq, 0, IF_OFF, interrupt_handler, c->name);
336 /* Reset hardware. */
339 /* Detect ATA devices. */
340 if (check_ata_device (&c->dev[0]))
341 check_ata_device (&c->dev[1]);
343 /* Detect device properties. */
344 for (device = 0; device < 2; device++)
345 if (c->dev[device].is_ata)
346 identify_ata_device (&c->dev[device]);
353 ASSERT (idx >= 0 && idx < 4);
354 return &channels[idx / 2].dev[idx % 2];
357 disk_sector_no disk_size (struct disk *);
358 void disk_read (struct disk *, disk_sector_no, void *);
359 void disk_write (struct disk *, disk_sector_no, const void *);