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.
16 static int diskno
= 1;
19 ide_wait_ready(bool check_error
)
23 while (((r
= inb(0x1F7)) & (IDE_BSY
|IDE_DRDY
)) != IDE_DRDY
)
26 if (check_error
&& (r
& (IDE_DF
|IDE_ERR
)) != 0)
36 // wait for Device 0 to be ready
40 outb(0x1F6, 0xE0 | (1<<4));
42 // check for Device 1 to be ready for a while
44 x
< 1000 && ((r
= inb(0x1F7)) & (IDE_BSY
|IDE_DF
|IDE_ERR
)) != 0;
48 // switch back to Device 0
49 outb(0x1F6, 0xE0 | (0<<4));
51 cprintf("Device 1 presence: %d\n", (x
< 1000));
59 panic("bad disk number");
64 ide_read(uint32_t secno
, void *dst_voidp
, size_t nsecs
)
66 char *dst
= (char *) dst_voidp
;
74 outb(0x1F3, secno
& 0xFF);
75 outb(0x1F4, (secno
>> 8) & 0xFF);
76 outb(0x1F5, (secno
>> 16) & 0xFF);
77 outb(0x1F6, 0xE0 | ((diskno
&1)<<4) | ((secno
>>24)&0x0F));
78 outb(0x1F7, 0x20); // CMD 0x20 means read sector
80 for (; nsecs
> 0; nsecs
--, dst
+= SECTSIZE
) {
81 if ((r
= ide_wait_ready(1)) < 0)
83 insl(0x1F0, dst
, SECTSIZE
/4);
90 ide_write(uint32_t secno
, const void *src_voidp
, size_t nsecs
)
92 const char *src
= (const char *) src_voidp
;
100 outb(0x1F3, secno
& 0xFF);
101 outb(0x1F4, (secno
>> 8) & 0xFF);
102 outb(0x1F5, (secno
>> 16) & 0xFF);
103 outb(0x1F6, 0xE0 | ((diskno
&1)<<4) | ((secno
>>24)&0x0F));
104 outb(0x1F7, 0x30); // CMD 0x30 means write sector
106 for (; nsecs
> 0; nsecs
--, src
+= SECTSIZE
) {
107 if ((r
= ide_wait_ready(1)) < 0)
109 outsl(0x1F0, src
, SECTSIZE
/4);