X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdevices%2Fdisk.c;h=5320d2e48f602c8eb1b5a36f9899b789263fb362;hb=fba4443410241dd95c25a0fd7c5f8c0d8ff30ada;hp=d8bed65343e16a2b91c6d41aea8b7771877444fc;hpb=f2f8875638593bd5365cfd6a5ba7c9578e52322f;p=pintos-anon diff --git a/src/devices/disk.c b/src/devices/disk.c index d8bed65..5320d2e 100644 --- a/src/devices/disk.c +++ b/src/devices/disk.c @@ -8,6 +8,9 @@ #include "threads/interrupt.h" #include "threads/synch.h" +/* The code in this file is an interface to an ATA (IDE) + controller. It attempts to comply to [ATA-3]. */ + /* ATA command block port addresses. */ #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0) /* Data. */ #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1) /* Error. */ @@ -52,7 +55,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 +109,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%zu", chan_no); switch (chan_no) { case 0: @@ -131,6 +137,8 @@ disk_init (void) d->is_ata = false; d->capacity = 0; + + d->read_cnt = d->write_cnt = 0; } /* Register interrupt handler. */ @@ -150,6 +158,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 * @@ -176,6 +204,15 @@ disk_size (struct disk *d) return d->capacity; } +/* Returns a human-readable name for disk D. */ +const char * +disk_name (struct disk *d) +{ + ASSERT (d != NULL); + + return d->name; +} + /* Reads sector SEC_NO from disk D into BUFFER, which must have room for DISK_SECTOR_SIZE bytes. */ void @@ -194,6 +231,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 +254,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); } @@ -343,15 +382,7 @@ identify_ata_device (struct disk *d) /* Print identification message. */ printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity); - if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024) - printf ("%"PRDSNu" GB", - d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024)); - else if (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) - printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE)); - else - printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE); + print_human_readable_size ((uint64_t) d->capacity * DISK_SECTOR_SIZE); printf (") disk, model \""); print_ata_string ((char *) &id[27], 40); printf ("\", serial \"");