Dynamically allocate each drive_g with malloc_fseg().
authorKevin O'Connor <kevin@koconnor.net>
Tue, 16 Feb 2010 03:48:28 +0000 (22:48 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 16 Feb 2010 03:48:28 +0000 (22:48 -0500)
This eliminates the limit on the number of available drives.  It also
allows for each driver to allocate additional custom fields.

src/ata.c
src/biosvar.h
src/block.c
src/boot.c
src/cdrom.c
src/config.h
src/disk.h
src/floppy.c

index a27da56b0337589f61cac17c0ad2709384e89321..f935e1f6fc140fbaf540c508f13bd7e73a1cf727 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -775,9 +775,12 @@ init_drive_atapi(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATAPI.
-    struct drive_s *drive_g = allocDrive();
-    if (! drive_g)
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (! drive_g) {
+        warn_noalloc();
         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);
@@ -821,9 +824,12 @@ init_drive_ata(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATA.
-    struct drive_s *drive_g = allocDrive();
-    if (! drive_g)
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (! drive_g) {
+        warn_noalloc();
         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);
index d011966b132adfe369bda60de56ae3326d0a87a3..c67503cd5ef4a4e34b8812e3950fd832f8c28e45 100644 (file)
@@ -329,9 +329,11 @@ static inline u16 get_global_seg(void) {
         (var) = (val);                          \
     } while (0)
 #if MODESEGMENT
-#define ADJUST_GLOBAL_PTR(var) (var)
+#define STORE_GLOBAL_PTR(var) (var)
+#define RETRIEVE_GLOBAL_PTR(var) (var)
 #else
-#define ADJUST_GLOBAL_PTR(var) ((typeof(var))((void*)var - BUILD_BIOS_ADDR))
+#define STORE_GLOBAL_PTR(var) ((typeof(var))((void*)var - BUILD_BIOS_ADDR))
+#define RETRIEVE_GLOBAL_PTR(var) ((typeof(var))((void*)var + BUILD_BIOS_ADDR))
 #endif
 
 
index 3a9a68d2e338f90e9bb0c6d9c4594b851c2dcac2..63aa368d1e8b2f91b8ed59e11c2f99ec0e34e9a8 100644 (file)
@@ -16,30 +16,9 @@ struct drives_s Drives VAR16VISIBLE;
 struct drive_s *
 getDrive(u8 exttype, u8 extdriveoffset)
 {
-    // basic check : device has to be defined
     if (extdriveoffset >= ARRAY_SIZE(Drives.idmap[0]))
         return NULL;
-
-    // Get the ata channel
-    u8 driveid = GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]);
-
-    // basic check : device has to be valid
-    if (driveid >= ARRAY_SIZE(Drives.drives))
-        return NULL;
-
-    return &Drives.drives[driveid];
-}
-
-struct drive_s *
-allocDrive(void)
-{
-    int driveid = Drives.drivecount;
-    if (driveid >= ARRAY_SIZE(Drives.drives))
-        return NULL;
-    Drives.drivecount++;
-    struct drive_s *drive_g = &Drives.drives[driveid];
-    memset(drive_g, 0, sizeof(*drive_g));
-    return drive_g;
+    return RETRIEVE_GLOBAL_PTR(GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]));
 }
 
 
@@ -208,11 +187,12 @@ map_hd_drive(struct drive_s *drive_g)
 {
     // fill hdidmap
     u8 hdcount = GET_BDA(hdcount);
-    if (hdcount >= ARRAY_SIZE(Drives.idmap[0]))
+    if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) {
+        warn_noalloc();
         return;
+    }
     dprintf(3, "Mapping hd drive %p to %d\n", drive_g, hdcount);
-    int driveid = drive_g - Drives.drives;
-    SET_GLOBAL(Drives.idmap[EXTTYPE_HD][hdcount], driveid);
+    Drives.idmap[EXTTYPE_HD][hdcount] = STORE_GLOBAL_PTR(drive_g);
     SET_BDA(hdcount, hdcount + 1);
 
     // Fill "fdpt" structure.
@@ -221,22 +201,22 @@ map_hd_drive(struct drive_s *drive_g)
 
 // Find spot to add a drive
 static void
-add_ordered_drive(u8 *idmap, u8 *count, struct drive_s *drive_g)
+add_ordered_drive(struct drive_s **idmap, u8 *count, struct drive_s *drive_g)
 {
     if (*count >= ARRAY_SIZE(Drives.idmap[0])) {
         warn_noalloc();
         return;
     }
-    u8 *pos = &idmap[*count];
+    struct drive_s **pos = &idmap[*count];
     *count = *count + 1;
     if (CONFIG_THREADS) {
         // Add to idmap with assured drive order.
-        u8 *end = pos;
+        struct drive_s **end = pos;
         for (;;) {
-            u8 *prev = pos - 1;
+            struct drive_s **prev = pos - 1;
             if (prev < idmap)
                 break;
-            struct drive_s *prevdrive = &Drives.drives[*prev];
+            struct drive_s *prevdrive = *prev;
             if (prevdrive->type < drive_g->type
                 || (prevdrive->type == drive_g->type
                     && prevdrive->cntl_id < drive_g->cntl_id))
@@ -246,7 +226,7 @@ add_ordered_drive(u8 *idmap, u8 *count, struct drive_s *drive_g)
         if (pos != end)
             memmove(pos+1, pos, (void*)end-(void*)pos);
     }
-    *pos = drive_g - Drives.drives;
+    *pos = STORE_GLOBAL_PTR(drive_g);
 }
 
 // Map a cd
@@ -312,6 +292,7 @@ describe_drive(struct drive_s *drive_g)
 int
 process_op(struct disk_op_s *op)
 {
+    ASSERT16();
     u8 type = GET_GLOBAL(op->drive_g->type);
     switch (type) {
     case DTYPE_FLOPPY:
@@ -355,9 +336,9 @@ __send_disk_op(struct disk_op_s *op_far, u16 op_seg)
 int
 send_disk_op(struct disk_op_s *op)
 {
+    ASSERT16();
     if (! CONFIG_DRIVES)
         return -1;
-    ASSERT16();
 
     return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op);
 }
@@ -371,5 +352,4 @@ void
 drive_setup(void)
 {
     memset(&Drives, 0, sizeof(Drives));
-    memset(&Drives.idmap, 0xff, sizeof(Drives.idmap));
 }
index 151b0d36905d379dfbd98b04d6eac292d46418cb..6b69dc2f9f343a66f8bfd525722e7f560180a895 100644 (file)
@@ -321,7 +321,7 @@ boot_prep(void)
 
     // Setup floppy boot order
     int override = IPL.bev[0].subchoice;
-    int tmp = Drives.idmap[EXTTYPE_FLOPPY][0];
+    struct drive_s *tmp = Drives.idmap[EXTTYPE_FLOPPY][0];
     Drives.idmap[EXTTYPE_FLOPPY][0] = Drives.idmap[EXTTYPE_FLOPPY][override];
     Drives.idmap[EXTTYPE_FLOPPY][override] = tmp;
 
index 4e70729107bb249ebc74853d1f471cd7e2d1f797..06adefa903527a0b3648b4e94462ca1a82c2432b 100644 (file)
@@ -113,12 +113,14 @@ cdemu_setup(void)
     if (!CONFIG_CDROM_EMU)
         return;
 
-    struct drive_s *drive_g = allocDrive();
-    if (!drive_g) {
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (! drive_g) {
+        warn_noalloc();
         cdemu_drive = NULL;
         return;
     }
-    cdemu_drive = ADJUST_GLOBAL_PTR(drive_g);
+    memset(drive_g, 0, sizeof(*drive_g));
+    cdemu_drive = STORE_GLOBAL_PTR(drive_g);
     drive_g->type = DTYPE_CDEMU;
     drive_g->blksize = DISK_SECTOR_SIZE;
     drive_g->sectors = (u64)-1;
@@ -327,7 +329,7 @@ cdrom_boot(int cdid)
     u8 media = buffer[0x21];
     SET_EBDA2(ebda_seg, cdemu.media, media);
 
-    SET_EBDA2(ebda_seg, cdemu.emulated_drive, ADJUST_GLOBAL_PTR(dop.drive_g));
+    SET_EBDA2(ebda_seg, cdemu.emulated_drive, STORE_GLOBAL_PTR(dop.drive_g));
 
     u16 boot_segment = *(u16*)&buffer[0x22];
     if (!boot_segment)
index c02d4964ef60fff20d2474b50a5335c7a1d35cfa..e3596526b829496ae139480fc78f3b0010155085 100644 (file)
 #define CONFIG_USE_SMM 1
 // Maximum number of map entries in the e820 map
 #define CONFIG_MAX_E820 32
-// Space to reserve in f-segment for run-time built bios tables.
+// Space to reserve in f-segment for dynamic allocations
 #define CONFIG_MAX_BIOSTABLE 2048
 // Space to reserve in high-memory for tables
 #define CONFIG_MAX_HIGHTABLE (64*1024)
 
 // Maximum number of ATA controllers to support
 #define CONFIG_MAX_ATA_INTERFACES 4
-// Maximum number of internal drives supported
-#define CONFIG_MAX_DRIVES 8
 // Largest supported externaly facing drive id
 #define CONFIG_MAX_EXTDRIVE 16
 
index ac5748ec655952917190accdd22cabe4ea2397e4..635d51193225776761100d6d0e970173f20fbfc2 100644 (file)
@@ -173,7 +173,7 @@ struct chs_s {
 };
 
 struct drive_s {
-    u8  type;         // Detected type of drive (ata/atapi/none)
+    u8  type;         // Driver type (DTYPE_*)
     u8  removable;    // Removable device flag
     u16 blksize;      // block size
     u32 cntl_id;
@@ -205,14 +205,10 @@ struct drive_s {
 #define TRANSLATION_RECHS 3
 
 struct drives_s {
-    // info on each internally handled drive
-    struct drive_s drives[CONFIG_MAX_DRIVES];
-    u8 drivecount;
-    //
-    // map between bios floppy/hd/cd id and driveid index into drives[]
+    // map between bios floppy/hd/cd id and drive_s struct
     u8 floppycount;
     u8 cdcount;
-    u8 idmap[3][CONFIG_MAX_EXTDRIVE];
+    struct drive_s *idmap[3][CONFIG_MAX_EXTDRIVE];
 };
 
 #define EXTTYPE_FLOPPY 0
@@ -230,7 +226,6 @@ struct drives_s {
 // block.c
 extern struct drives_s Drives;
 struct drive_s *getDrive(u8 exttype, u8 extdriveoffset);
-struct drive_s *allocDrive(void);
 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);
index dba3e00428139ffa21280addbd1417fab7076af1..d2e689c12d6623f26499bab708caa532b33066f1 100644 (file)
@@ -96,9 +96,12 @@ addFloppy(int floppyid, int ftype, int driver)
         return NULL;
     }
 
-    struct drive_s *drive_g = allocDrive();
-    if (!drive_g)
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (!drive_g) {
+        warn_noalloc();
         return NULL;
+    }
+    memset(drive_g, 0, sizeof(*drive_g));
     drive_g->cntl_id = floppyid;
     drive_g->type = driver;
     drive_g->blksize = DISK_SECTOR_SIZE;