Make backtraces slightly more reliable.
[pintos-anon] / src / devices / disk.c
index 1810fc4b1c474961d618a4002cb75ac4299d93a4..14fc63158be840c550d7eb7a9d42d6ecb23b0c77 100644 (file)
@@ -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);
@@ -182,7 +183,7 @@ disk_print_stats (void)
    slave, respectively--within the channel numbered CHAN_NO.
 
    Pintos uses disks this way:
-        0:0 - operating system kernel
+        0:0 - boot loader, command line args, and operating system kernel
         0:1 - file system
         1:0 - scratch
         1:1 - swap
@@ -212,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) 
 {
@@ -235,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)
 {
@@ -331,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;