Cleanup - build drive description in temp memory during init.
authorKevin O'Connor <kevin@koconnor.net>
Mon, 22 Feb 2010 04:20:10 +0000 (23:20 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Mon, 22 Feb 2010 04:20:10 +0000 (23:20 -0500)
Remove describe_drive() mechanism for calling printf with a drive
description.  Instead, have each drive build a description in
temporary ram during drive initialization.

Also, remove fields now unneeded from 'struct disk_s' - model and
cntl_info.

src/ata.c
src/ata.h
src/block.c
src/boot.c
src/disk.h
src/floppy.c
src/ramdisk.c
src/usb-msc.c
src/usb-msc.h
src/util.h

index 3c57f9f3b7045ae4dc91186f521833e4ac9801ac..953aef2880244d036b2fb4cfc57b8e170d73e860 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -711,44 +711,23 @@ extract_version(u16 *buffer)
     return version;
 }
 
-// Extract common information from IDENTIFY commands.
-static void
-extract_identify(struct drive_s *drive_g, u16 *buffer)
-{
-    dprintf(3, "Identify w0=%x w2=%x\n", buffer[0], buffer[2]);
+#define MAXMODEL 40
 
+// Extract the ATA/ATAPI model info.
+static char *
+extract_model(char *model, u16 *buffer)
+{
     // Read model name
-    char *model = drive_g->model;
-    int maxsize = ARRAY_SIZE(drive_g->model);
     int i;
-    for (i=0; i<maxsize/2; i++) {
-        u16 v = buffer[27+i];
-        model[i*2] = v >> 8;
-        model[i*2+1] = v & 0xff;
-    }
-    model[maxsize-1] = 0x00;
+    for (i=0; i<MAXMODEL/2; i++)
+        *(u16*)&model[i*2] = ntohs(buffer[27+i]);
+    model[MAXMODEL] = 0x00;
 
     // Trim trailing spaces from model name.
-    for (i=maxsize-2; i>0 && model[i] == 0x20; i--)
+    for (i=MAXMODEL-1; i>0 && model[i] == 0x20; i--)
         model[i] = 0x00;
 
-    // Common flags.
-    SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
-    SET_GLOBAL(drive_g->cntl_info, extract_version(buffer));
-}
-
-// Print out a description of the given atapi drive.
-void
-describe_atapi(struct drive_s *drive_g)
-{
-    u8 ataid = drive_g->cntl_id;
-    u8 channel = ataid / 2;
-    u8 slave = ataid % 2;
-    u8 version = drive_g->cntl_info;
-    int iscd = drive_g->floppy_type;
-    printf("ata%d-%d: %s ATAPI-%d %s", channel, slave
-           , drive_g->model, version
-           , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
+    return model;
 }
 
 // Detect if the given drive is an atapi - initialize it if so.
@@ -761,19 +740,29 @@ init_drive_atapi(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATAPI.
+    char *desc = malloc_tmp(MAXDESCSIZE);
     struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
-    if (! drive_g) {
+    if (!drive_g || !desc) {
         warn_noalloc();
+        free(desc);
+        free(drive_g);
         return NULL;
     }
     memset(drive_g, 0, sizeof(*drive_g));
     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
-    extract_identify(drive_g, buffer);
     SET_GLOBAL(drive_g->type, DTYPE_ATAPI);
     SET_GLOBAL(drive_g->blksize, CDROM_SECTOR_SIZE);
     SET_GLOBAL(drive_g->sectors, (u64)-1);
+    SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
     u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
-    SET_GLOBAL(drive_g->floppy_type, iscd);
+    u8 ataid = drive_g->cntl_id;
+    u8 channel = ataid / 2;
+    u8 slave = ataid % 2;
+    char model[MAXMODEL+1];
+    drive_g->desc = desc;
+    snprintf(desc, MAXDESCSIZE, "ata%d-%d: %s ATAPI-%d %s", channel, slave
+             , extract_model(model, buffer), extract_version(buffer)
+             , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
 
     // fill cdidmap
     if (iscd)
@@ -782,24 +771,6 @@ init_drive_atapi(struct drive_s *dummy, u16 *buffer)
     return drive_g;
 }
 
-// Print out a description of the given ata drive.
-void
-describe_ata(struct drive_s *drive_g)
-{
-    u8 ataid = drive_g->cntl_id;
-    u8 channel = ataid / 2;
-    u8 slave = ataid % 2;
-    u64 sectors = drive_g->sectors;
-    u8 version = drive_g->cntl_info;
-    char *model = drive_g->model;
-    printf("ata%d-%d: %s ATA-%d Hard-Disk", channel, slave, model, version);
-    u64 sizeinmb = sectors >> 11;
-    if (sizeinmb < (1 << 16))
-        printf(" (%u MiBytes)", (u32)sizeinmb);
-    else
-        printf(" (%u GiBytes)", (u32)(sizeinmb >> 10));
-}
-
 // Detect if the given drive is a regular ata drive - initialize it if so.
 static struct drive_s *
 init_drive_ata(struct drive_s *dummy, u16 *buffer)
@@ -810,14 +781,16 @@ init_drive_ata(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATA.
+    char *desc = malloc_tmp(MAXDESCSIZE);
     struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
-    if (! drive_g) {
+    if (!drive_g || !desc) {
         warn_noalloc();
+        free(desc);
+        free(drive_g);
         return NULL;
     }
     memset(drive_g, 0, sizeof(*drive_g));
     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
-    extract_identify(drive_g, buffer);
     SET_GLOBAL(drive_g->type, DTYPE_ATA);
     SET_GLOBAL(drive_g->blksize, DISK_SECTOR_SIZE);
 
@@ -831,6 +804,22 @@ init_drive_ata(struct drive_s *dummy, u16 *buffer)
     else
         sectors = *(u32*)&buffer[60]; // word 60 and word 61
     SET_GLOBAL(drive_g->sectors, sectors);
+    SET_GLOBAL(drive_g->removable, (buffer[0] & 0x80) ? 1 : 0);
+    u8 ataid = drive_g->cntl_id;
+    u8 channel = ataid / 2;
+    u8 slave = ataid % 2;
+    u64 adjsize = sectors >> 11;
+    char adjprefix = 'M';
+    if (adjsize >= (1 << 16)) {
+        adjsize >>= 10;
+        adjprefix = 'G';
+    }
+    char model[MAXMODEL+1];
+    drive_g->desc = desc;
+    snprintf(desc, MAXDESCSIZE, "ata%d-%d: %s ATA-%d Hard-Disk (%u %ciBytes)"
+             , channel, slave
+             , extract_model(model, buffer), extract_version(buffer)
+             , (u32)adjsize, adjprefix);
 
     // Setup disk geometry translation.
     setup_translation(drive_g);
index ede5f1726683625242fa870e9b335bcdac6fafb1..71624bbb3513a55ed3ca16f0c8e7382e290b9def 100644 (file)
--- a/src/ata.h
+++ b/src/ata.h
@@ -19,8 +19,6 @@ int atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize);
 void ata_setup(void);
 int process_ata_op(struct disk_op_s *op);
 int process_atapi_op(struct disk_op_s *op);
-void describe_ata(struct drive_s *drive_g);
-void describe_atapi(struct drive_s *drive_g);
 
 // Global defines -- ATA register and register bits.
 // command block & control block regs
index 3b43f97a6bda941995cb1ba7f1415b1c4dd1aea3..053012072193deea7ab39fba3f8fd7493a6fbad8 100644 (file)
@@ -262,34 +262,6 @@ map_floppy_drive(struct drive_s *drive_g)
     }
 }
 
-// Show a one line description (without trailing newline) of a drive.
-void
-describe_drive(struct drive_s *drive_g)
-{
-    ASSERT32FLAT();
-    u8 type = GET_GLOBAL(drive_g->type);
-    switch (type) {
-    case DTYPE_FLOPPY:
-        describe_floppy(drive_g);
-        break;
-    case DTYPE_ATA:
-        describe_ata(drive_g);
-        break;
-    case DTYPE_ATAPI:
-        describe_atapi(drive_g);
-        break;
-    case DTYPE_RAMDISK:
-        describe_ramdisk(drive_g);
-        break;
-    case DTYPE_USB:
-        describe_usb(drive_g);
-        break;
-    default:
-        printf("Unknown");
-        break;
-    }
-}
-
 
 /****************************************************************
  * 16bit calling interface
index 6b69dc2f9f343a66f8bfd525722e7f560180a895..6e9000e9b1f3e72f575b1f4069b1f4badc82b2cc 100644 (file)
@@ -159,9 +159,7 @@ menu_show_floppy(struct ipl_entry_s *ie, int menupos)
     int i;
     for (i = 0; i < Drives.floppycount; i++) {
         struct drive_s *drive_g = getDrive(EXTTYPE_FLOPPY, i);
-        printf("%d. Floppy [", menupos + i);
-        describe_drive(drive_g);
-        printf("]\n");
+        printf("%d. Floppy [%s]\n", menupos + i, drive_g->desc);
     }
     return Drives.floppycount;
 }
@@ -173,11 +171,10 @@ menu_show_harddisk(struct ipl_entry_s *ie, int menupos)
     int i;
     for (i = 0; i < IPL.bcvcount; i++) {
         struct ipl_entry_s *ie = &IPL.bcv[i];
+        struct drive_s *drive_g = (void*)ie->vector;
         switch (ie->type) {
         case BCV_TYPE_INTERNAL:
-            printf("%d. ", menupos + i);
-            describe_drive((void*)ie->vector);
-            printf("\n");
+            printf("%d. %s\n", menupos + i, drive_g->desc);
             break;
         default:
             menu_show_default(ie, menupos+i);
@@ -194,9 +191,7 @@ menu_show_cdrom(struct ipl_entry_s *ie, int menupos)
     int i;
     for (i = 0; i < Drives.cdcount; i++) {
         struct drive_s *drive_g = getDrive(EXTTYPE_CD, i);
-        printf("%d. CD-Rom [", menupos + i);
-        describe_drive(drive_g);
-        printf("]\n");
+        printf("%d. CD-Rom [%s]\n", menupos + i, drive_g->desc);
     }
     return Drives.cdcount;
 }
index d87d71aa81805b3dc72514c7a2e6392cdc4a872c..3ecb05276f8e4e7e9f9314bdd164c35c81449e76 100644 (file)
@@ -177,17 +177,14 @@ struct drive_s {
     u8 floppy_type;     // Type of floppy (only for floppy drives).
     struct chs_s lchs;  // Logical CHS
     u64 sectors;        // Total sectors count
+    char *desc;         // Drive description (only available during POST)
+    u32 cntl_id;        // Unique id for a given driver type.
+    u8 removable;       // Is media removable (currently unused)
 
     // Info for EDD calls
+    u8 translation;     // type of translation
     u16 blksize;        // block size
     struct chs_s pchs;  // Physical CHS
-    u8 translation;     // type of translation
-
-    // Driver specific
-    u32 cntl_id;
-    u32 cntl_info;
-    u8 removable;       // Removable device flag
-    char model[41];
 };
 
 #define DISK_SECTOR_SIZE  512
@@ -201,6 +198,8 @@ struct drive_s {
 #define DTYPE_CDEMU    0x05
 #define DTYPE_USB      0x06
 
+#define MAXDESCSIZE 80
+
 #define TRANSLATION_NONE  0
 #define TRANSLATION_LBA   1
 #define TRANSLATION_LARGE 2
@@ -232,7 +231,6 @@ void setup_translation(struct drive_s *drive_g);
 void map_floppy_drive(struct drive_s *drive_g);
 void map_hd_drive(struct drive_s *drive_g);
 void map_cd_drive(struct drive_s *drive_g);
-void describe_drive(struct drive_s *drive_g);
 int process_op(struct disk_op_s *op);
 int send_disk_op(struct disk_op_s *op);
 void drive_setup(void);
@@ -241,7 +239,6 @@ void drive_setup(void);
 extern struct floppy_ext_dbt_s diskette_param_table2;
 void floppy_setup(void);
 struct drive_s *addFloppy(int floppyid, int ftype, int driver);
-void describe_floppy(struct drive_s *drive_g);
 int find_floppy_type(u32 size);
 int process_floppy_op(struct disk_op_s *op);
 void floppy_tick(void);
@@ -254,7 +251,6 @@ void cdemu_134b(struct bregs *regs);
 int cdrom_boot(int cdid);
 
 // ramdisk.c
-void describe_ramdisk(struct drive_s *drive_g);
 void ramdisk_setup(void);
 int process_ramdisk_op(struct disk_op_s *op);
 
index d2e689c12d6623f26499bab708caa532b33066f1..a8942cf02217ae17879eb251da431a59155194e9 100644 (file)
@@ -96,9 +96,12 @@ addFloppy(int floppyid, int ftype, int driver)
         return NULL;
     }
 
+    char *desc = malloc_tmp(MAXDESCSIZE);
     struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
-    if (!drive_g) {
+    if (!drive_g || !desc) {
         warn_noalloc();
+        free(desc);
+        free(drive_g);
         return NULL;
     }
     memset(drive_g, 0, sizeof(*drive_g));
@@ -107,6 +110,8 @@ addFloppy(int floppyid, int ftype, int driver)
     drive_g->blksize = DISK_SECTOR_SIZE;
     drive_g->floppy_type = ftype;
     drive_g->sectors = (u64)-1;
+    drive_g->desc = desc;
+    snprintf(desc, MAXDESCSIZE, "drive %c", 'A' + floppyid);
 
     memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs
            , sizeof(FloppyInfo[ftype].chs));
@@ -115,12 +120,6 @@ addFloppy(int floppyid, int ftype, int driver)
     return drive_g;
 }
 
-void
-describe_floppy(struct drive_s *drive_g)
-{
-    printf("drive %c", 'A' + drive_g->cntl_id);
-}
-
 void
 floppy_setup(void)
 {
index 641d87e7022ec898b1bb4fd11d3743e0421b03c4..01648402b0e159e4f8cb7d0461e608092a49d5b4 100644 (file)
 #include "biosvar.h" // GET_GLOBAL
 #include "bregs.h" // struct bregs
 
-void
-describe_ramdisk(struct drive_s *drive_g)
-{
-    printf("%s", drive_g->model);
-}
-
 void
 ramdisk_setup(void)
 {
@@ -48,8 +42,8 @@ ramdisk_setup(void)
     // Setup driver.
     dprintf(1, "Mapping CBFS floppy %s to addr %p\n", cbfs_filename(file), pos);
     struct drive_s *drive_g = addFloppy((u32)pos, ftype, DTYPE_RAMDISK);
-    if (drive_g)
-        strtcpy(drive_g->model, cbfs_filename(file), ARRAY_SIZE(drive_g->model));
+    if (!drive_g)
+        strtcpy(drive_g->desc, cbfs_filename(file), MAXDESCSIZE);
 }
 
 static int
index 8d4a44ede685c4d754a4041f40a8e822f1e28ff4..c1fa45ddbc1af1bf1bb6853bd051d9b37106eb8a 100644 (file)
 #include "disk.h" // DTYPE_USB
 #include "boot.h" // add_bcv_internal
 
-#define DESCSIZE 80
-
 struct usbdrive_s {
     struct drive_s drive;
     struct usb_pipe *bulkin, *bulkout;
-    char *desc;
 };
 
 
@@ -131,14 +128,6 @@ process_usb_op(struct disk_op_s *op)
     }
 }
 
-void
-describe_usb(struct drive_s *drive_g)
-{
-    struct usbdrive_s *udrive_g = container_of(
-        drive_g, struct usbdrive_s, drive);
-    printf("%s", udrive_g->desc);
-}
-
 
 /****************************************************************
  * Setup
@@ -212,7 +201,7 @@ usb_msc_init(u32 endp, struct usb_interface_descriptor *iface, int imax)
         goto fail;
 
     // Allocate drive structure.
-    char *desc = malloc_tmphigh(DESCSIZE);
+    char *desc = malloc_tmphigh(MAXDESCSIZE);
     struct usbdrive_s *udrive_g = malloc_fseg(sizeof(*udrive_g));
     if (!udrive_g || !desc) {
         warn_noalloc();
@@ -241,6 +230,7 @@ usb_msc_init(u32 endp, struct usb_interface_descriptor *iface, int imax)
             , strtcpy(product, data.product, sizeof(product))
             , strtcpy(rev, data.rev, sizeof(rev))
             , pdt, removable);
+    udrive_g->drive.removable = removable;
 
     if (pdt == USB_MSC_TYPE_CDROM)
         ret = setup_drive_cdrom(&dop);
@@ -249,8 +239,8 @@ usb_msc_init(u32 endp, struct usb_interface_descriptor *iface, int imax)
     if (ret)
         goto fail;
 
-    snprintf(desc, DESCSIZE, "USB Drive %s %s %s", vendor, product, rev);
-    udrive_g->desc = desc;
+    snprintf(desc, MAXDESCSIZE, "USB Drive %s %s %s", vendor, product, rev);
+    udrive_g->drive.desc = desc;
 
     return 0;
 fail:
index 4bad91f3753613f21d962dead07686f70b2ba6d7..50c219366996b3f7598c4d31f01a4f6899e10e59 100644 (file)
@@ -7,8 +7,6 @@ int usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize);
 struct usb_interface_descriptor;
 int usb_msc_init(u32 endp, struct usb_interface_descriptor *iface, int imax);
 int process_usb_op(struct disk_op_s *op);
-struct drive_s;
-void describe_usb(struct drive_s *drive_g);
 
 
 /****************************************************************
index eb625077e338c655c7f51e0da4f68e12dc8ef235..9c78e4c800f60799c55c056f2459022cd57ed2d2 100644 (file)
@@ -385,6 +385,12 @@ static inline void *malloc_fseg(u32 size) {
 static inline void *malloc_tmphigh(u32 size) {
     return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
 }
+static inline void *malloc_tmp(u32 size) {
+    void *ret = malloc_tmphigh(size);
+    if (ret)
+        return ret;
+    return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
+}
 static inline void *memalign_low(u32 align, u32 size) {
     return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align);
 }