X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdevices%2Fdisk.c;h=baf120864399f11a8c33ae27f37a41992b413cab;hb=34a1a2cf11500505e74ae5796e88de0d8de00958;hp=9e4b9f506358296c0eb2f9b49760059e12a95282;hpb=f6580e9ad405b519dbe85027691bf3c66074b0a4;p=pintos-anon diff --git a/src/devices/disk.c b/src/devices/disk.c index 9e4b9f5..baf1208 100644 --- a/src/devices/disk.c +++ b/src/devices/disk.c @@ -1,8 +1,9 @@ -#include "disk.h" +#include "devices/disk.h" +#include +#include #include -#include "timer.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include +#include "devices/timer.h" #include "threads/io.h" #include "threads/interrupt.h" #include "threads/synch.h" @@ -51,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). @@ -102,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: @@ -130,6 +134,8 @@ disk_init (void) d->is_ata = false; d->capacity = 0; + + d->read_cnt = d->write_cnt = 0; } /* Register interrupt handler. */ @@ -149,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 * @@ -193,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); } @@ -215,12 +242,13 @@ 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); } /* Disk detection and identification. */ -static void printk_ata_string (char *string, size_t size); +static void print_ata_string (char *string, size_t size); /* Resets an ATA channel and waits for any devices present on it to finish the reset. */ @@ -254,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]) @@ -278,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]); } @@ -341,28 +369,28 @@ identify_ata_device (struct disk *d) d->capacity = id[60] | ((uint32_t) id[61] << 16); /* Print identification message. */ - printk ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity); + printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity); if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024) - printk ("%"PRDSNu" GB", + printf ("%"PRDSNu" GB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024)); else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024) - printk ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024)); + printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024)); else if (d->capacity > 1024 / DISK_SECTOR_SIZE) - printk ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE)); + printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE)); else - printk ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE); - printk (") disk, model \""); - printk_ata_string ((char *) &id[27], 40); - printk ("\", serial \""); - printk_ata_string ((char *) &id[10], 20); - printk ("\"\n"); + printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE); + printf (") disk, model \""); + print_ata_string ((char *) &id[27], 40); + printf ("\", serial \""); + print_ata_string ((char *) &id[10], 20); + printf ("\"\n"); } /* Prints STRING, which consists of SIZE bytes in a funky format: each pair of bytes is in reverse order. Does not print trailing whitespace and/or nulls. */ static void -printk_ata_string (char *string, size_t size) +print_ata_string (char *string, size_t size) { size_t i; @@ -376,7 +404,7 @@ printk_ata_string (char *string, size_t size) /* Print. */ for (i = 0; i < size; i++) - printk ("%c", string[i ^ 1]); + printf ("%c", string[i ^ 1]); } /* Selects device D, waiting for it to become ready, and then @@ -444,10 +472,10 @@ 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)); } - printk ("%s: idle timeout\n", d->name); + printf ("%s: idle timeout\n", d->name); } /* Wait up to 30 seconds for disk D to clear BSY, @@ -463,17 +491,17 @@ wait_while_busy (const struct disk *d) for (i = 0; i < 3000; i++) { if (i == 700) - printk ("%s: busy, waiting...", d->name); + printf ("%s: busy, waiting...", d->name); if (!(inb (reg_alt_status (c)) & STA_BSY)) { if (i >= 700) - printk ("ok\n"); + printf ("ok\n"); return (inb (reg_alt_status (c)) & STA_DRQ) != 0; } - timer_msleep (10); + timer_sleep (timer_ms2ticks (10)); } - printk ("failed\n"); + printf ("failed\n"); return false; } @@ -487,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 @@ -515,7 +543,7 @@ interrupt_handler (struct intr_frame *f) sema_up (&c->completion_wait); /* Wake up waiter. */ } else - printk ("%s: unexpected interrupt\n", c->name); + printf ("%s: unexpected interrupt\n", c->name); return; }