X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fdevices%2Fdisk.c;h=14fc63158be840c550d7eb7a9d42d6ecb23b0c77;hp=971f3af537288f38523d92e0807e2489870e33f6;hb=bb940d21474958a1d8ee2abffdcb6bac27918398;hpb=a40483c415f3b61066ddcc4890c0aedfca723f26 diff --git a/src/devices/disk.c b/src/devices/disk.c index 971f3af..14fc631 100644 --- a/src/devices/disk.c +++ b/src/devices/disk.c @@ -30,6 +30,7 @@ /* Alternate Status Register bits. */ #define STA_BSY 0x80 /* Busy. */ +#define STA_DRDY 0x40 /* Device Ready. */ #define STA_DRQ 0x08 /* Data Request. */ /* Control Register bits. */ @@ -123,9 +124,9 @@ disk_init (void) default: NOT_REACHED (); } - lock_init (&c->lock, c->name); + lock_init (&c->lock); c->expecting_interrupt = false; - sema_init (&c->completion_wait, 0, c->name); + sema_init (&c->completion_wait, 0); /* Initialize devices. */ for (dev_no = 0; dev_no < 2; dev_no++) @@ -142,7 +143,7 @@ disk_init (void) } /* Register interrupt handler. */ - intr_register (c->irq, 0, INTR_OFF, interrupt_handler, c->name); + intr_register_ext (c->irq, interrupt_handler, c->name); /* Reset hardware. */ reset_channel (c); @@ -179,7 +180,14 @@ disk_print_stats (void) } /* Returns the disk numbered DEV_NO--either 0 or 1 for master or - slave, respectively--within the channel numbered CHAN_NO. */ + slave, respectively--within the channel numbered CHAN_NO. + + Pintos uses disks this way: + 0:0 - boot loader, command line args, and operating system kernel + 0:1 - file system + 1:0 - scratch + 1:1 - swap +*/ struct disk * disk_get (int chan_no, int dev_no) { @@ -205,7 +213,9 @@ disk_size (struct disk *d) } /* Reads sector SEC_NO from disk D into BUFFER, which must have - room for DISK_SECTOR_SIZE bytes. */ + room for DISK_SECTOR_SIZE bytes. + Internally synchronizes accesses to disks, so external + per-disk locking is unneeded. */ void disk_read (struct disk *d, disk_sector_t sec_no, void *buffer) { @@ -228,7 +238,9 @@ disk_read (struct disk *d, disk_sector_t sec_no, void *buffer) /* Write sector SEC_NO to disk D from BUFFER, which must contain DISK_SECTOR_SIZE bytes. Returns after the disk has - acknowledged receiving the data. */ + acknowledged receiving the data. + Internally synchronizes accesses to disks, so external + per-disk locking is unneeded. */ void disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer) { @@ -324,15 +336,18 @@ static bool check_device_type (struct disk *d) { struct channel *c = d->channel; - uint8_t error, lbam, lbah; + uint8_t error, lbam, lbah, status; select_device (d); error = inb (reg_error (c)); lbam = inb (reg_lbam (c)); lbah = inb (reg_lbah (c)); + status = inb (reg_status (c)); - if (error != 1 && (error != 0x81 || d->dev_no == 1)) + if ((error != 1 && (error != 0x81 || d->dev_no == 1)) + || (status & STA_DRDY) == 0 + || (status & STA_BSY) != 0) { d->is_ata = false; return error != 0x81;