2 * Minimal PIO-based (non-interrupt-driven) IDE driver code.
3 * For information about what all this IDE/ATA magic means,
4 * see the materials available on the class references page.
15 static int diskno
= 1;
18 ide_wait_ready(bool check_error
)
22 while (((r
= inb(0x1F7)) & (IDE_BSY
|IDE_DRDY
)) != IDE_DRDY
)
25 if (check_error
&& (r
& (IDE_DF
|IDE_ERR
)) != 0)
35 // wait for Device 0 to be ready
39 outb(0x1F6, 0xE0 | (1<<4));
41 // check for Device 1 to be ready for a while
43 x
< 1000 && ((r
= inb(0x1F7)) & (IDE_BSY
|IDE_DF
|IDE_ERR
)) != 0;
47 // switch back to Device 0
48 outb(0x1F6, 0xE0 | (0<<4));
50 cprintf("Device 1 presence: %d\n", (x
< 1000));
58 panic("bad disk number");
63 ide_read(uint32_t secno
, void *dst
, size_t nsecs
)
72 outb(0x1F3, secno
& 0xFF);
73 outb(0x1F4, (secno
>> 8) & 0xFF);
74 outb(0x1F5, (secno
>> 16) & 0xFF);
75 outb(0x1F6, 0xE0 | ((diskno
&1)<<4) | ((secno
>>24)&0x0F));
76 outb(0x1F7, 0x20); // CMD 0x20 means read sector
78 for (; nsecs
> 0; nsecs
--, dst
+= SECTSIZE
) {
79 if ((r
= ide_wait_ready(1)) < 0)
81 insl(0x1F0, dst
, SECTSIZE
/4);
88 ide_write(uint32_t secno
, const void *src
, size_t nsecs
)
97 outb(0x1F3, secno
& 0xFF);
98 outb(0x1F4, (secno
>> 8) & 0xFF);
99 outb(0x1F5, (secno
>> 16) & 0xFF);
100 outb(0x1F6, 0xE0 | ((diskno
&1)<<4) | ((secno
>>24)&0x0F));
101 outb(0x1F7, 0x30); // CMD 0x30 means write sector
103 for (; nsecs
> 0; nsecs
--, src
+= SECTSIZE
) {
104 if ((r
= ide_wait_ready(1)) < 0)
106 outsl(0x1F0, src
, SECTSIZE
/4);