Print statistics at power off.
[pintos-anon] / src / devices / disk.c
index d8bed65343e16a2b91c6d41aea8b7771877444fc..baf120864399f11a8c33ae27f37a41992b413cab 100644 (file)
@@ -52,7 +52,10 @@ struct disk
     int dev_no;                 /* Device 0 or 1 for master or slave. */
 
     bool is_ata;                /* 1=This device is an ATA disk. */
-    disk_sector_t capacity;    /* Capacity in sectors (if is_ata is true). */
+    disk_sector_t capacity;     /* Capacity in sectors (if is_ata). */
+
+    long long read_cnt;         /* Number of sectors read. */
+    long long write_cnt;        /* Number of sectors written. */
   };
 
 /* An ATA channel (aka controller).
@@ -103,7 +106,7 @@ disk_init (void)
       int dev_no;
 
       /* Initialize channel. */
-      snprintf (c->name, sizeof c->name, "hd%d", chan_no);
+      snprintf (c->name, sizeof c->name, "hd%zd", chan_no);
       switch (chan_no) 
         {
         case 0:
@@ -131,6 +134,8 @@ disk_init (void)
 
           d->is_ata = false;
           d->capacity = 0;
+
+          d->read_cnt = d->write_cnt = 0;
         }
 
       /* Register interrupt handler. */
@@ -150,6 +155,26 @@ disk_init (void)
     }
 }
 
+/* Prints disk statistics. */
+void
+disk_print_stats (void) 
+{
+  int chan_no;
+
+  for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++) 
+    {
+      int dev_no;
+
+      for (dev_no = 0; dev_no < 2; dev_no++) 
+        {
+          struct disk *d = disk_get (chan_no, dev_no);
+          if (d != NULL && d->is_ata) 
+            printf ("%s: %lld reads, %lld writes\n",
+                    d->name, d->read_cnt, d->write_cnt);
+        }
+    }
+}
+
 /* Returns the disk numbered DEV_NO--either 0 or 1 for master or
    slave, respectively--within the channel numbered CHAN_NO. */
 struct disk *
@@ -194,6 +219,7 @@ disk_read (struct disk *d, disk_sector_t sec_no, void *buffer)
   if (!wait_while_busy (d))
     PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
   input_sector (c, buffer);
+  d->read_cnt++;
   lock_release (&c->lock);
 }
 
@@ -216,6 +242,7 @@ disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
     PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
   output_sector (c, buffer);
   sema_down (&c->completion_wait);
+  d->write_cnt++;
   lock_release (&c->lock);
 }
 \f
@@ -255,12 +282,12 @@ reset_channel (struct channel *c)
   /* Issue soft reset sequence, which selects device 0 as a side effect.
      Also enable interrupts. */
   outb (reg_ctl (c), 0);
-  timer_usleep (10);
+  timer_sleep (timer_us2ticks (10));
   outb (reg_ctl (c), CTL_SRST);
-  timer_usleep (10);
+  timer_sleep (timer_us2ticks (10));
   outb (reg_ctl (c), 0);
 
-  timer_msleep (150);
+  timer_sleep (timer_ms2ticks (150));
 
   /* Wait for device 0 to clear BSY. */
   if (present[0]) 
@@ -279,7 +306,7 @@ reset_channel (struct channel *c)
         {
           if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
             break;
-          timer_msleep (10);
+          timer_sleep (timer_ms2ticks (10));
         }
       wait_while_busy (&c->devices[1]);
     }
@@ -445,7 +472,7 @@ wait_until_idle (const struct disk *d)
     {
       if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
         return;
-      timer_usleep (10);
+      timer_sleep (timer_us2ticks (10));
     }
 
   printf ("%s: idle timeout\n", d->name);
@@ -471,7 +498,7 @@ wait_while_busy (const struct disk *d)
             printf ("ok\n");
           return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
         }
-      timer_msleep (10);
+      timer_sleep (timer_ms2ticks (10));
     }
 
   printf ("failed\n");
@@ -488,7 +515,7 @@ select_device (const struct disk *d)
     dev |= DEV_DEV;
   outb (reg_device (c), dev);
   inb (reg_alt_status (c));
-  timer_nsleep (400);
+  timer_sleep (timer_ns2ticks (400));
 }
 
 /* Select disk D in its channel, as select_device(), but wait for