From: Alan Cox Date: Tue, 6 Jan 2015 12:31:14 +0000 (+0000) Subject: blkdev: Break apart blkdev_init X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=08dcea72180c4de942e9f9ede0b99de78a604f4a;p=FUZIX.git blkdev: Break apart blkdev_init There are two reasons for doing this 1. We push a lot of arguments, and will need to push more which will break the planned banked kernel, as well as eating memory 2. We want to give drivers the ability to provide their own alternative scan methods Doing the alloc/assign/scan sequence doesn't cost us anything but is much more flexible. --- diff --git a/Kernel/dev/blkdev.c b/Kernel/dev/blkdev.c index f061dabe..96b9aa8f 100644 --- a/Kernel/dev/blkdev.c +++ b/Kernel/dev/blkdev.c @@ -120,32 +120,31 @@ int blkdev_write(uint8_t minor, uint8_t rawflag, uint8_t flag) return blkdev_transfer(minor, false, rawflag); } -void blkdev_add(transfer_function_t transfer, uint8_t drive_number, uint32_t lba_count) +/* FIXME: this would tidier and handle odd partition types sanely if split + into blkdev_alloc() - just returns a device, and blkdev_scan() */ + +blkdev_t *blkdev_alloc(void) { - char letter; - blkdev_t *blk = NULL; - - letter = 'a'; - blk = &blkdev_table[0]; - - /* find an empty slot */ - while(blk <= &blkdev_table[MAX_BLKDEV-1]){ - if(blk->drive_lba_count == 0){ - blk->drive_lba_count = lba_count; - blk->drive_number = drive_number; - blk->transfer = transfer; - - /* now we parse the partition table; might need a hook for platforms to - parse their platform-specific partition table first? eg P112 has its - own partitioning scheme */ - kprintf("hd%c: ", letter); - mbr_parse(blk, letter); - kputchar('\n'); - return; - } - blk++; - letter++; + blkdev_t *blk = &blkdev_table[0]; + while (blk < &blkdev_table[MAX_BLKDEV-1]) { + /* Cheapest to scan for an 8 or 16bit field and to make it start + the struct */ + if (blk->transfer == NULL) + return blk; + blk++; } + kputs("blkdev: full\n"); + return NULL; +} + +/* Flags is not used yet but will be needed (eg for swap scans) */ +void blkdev_scan(blkdev_t *blk, uint8_t flags) +{ + uint8_t letter = 'a' + (blk - blkdev_table); + + flags; - kputs("blkdev: full!\n"); + kprintf("hd%c: ", letter); + mbr_parse(blk, letter); + kputchar('\n'); } diff --git a/Kernel/dev/blkdev.h b/Kernel/dev/blkdev.h index f9acbaee..a720dbfd 100644 --- a/Kernel/dev/blkdev.h +++ b/Kernel/dev/blkdev.h @@ -5,20 +5,24 @@ and implement a sector transfer function matching the following prototype. */ typedef bool (*transfer_function_t)(uint8_t drive, uint32_t lba, void *buffer, bool read_notwrite); -/* public interface */ -void blkdev_add(transfer_function_t transfer, uint8_t drive_number, uint32_t lba_count); -int blkdev_open(uint8_t minor, uint16_t flags); -int blkdev_read(uint8_t minor, uint8_t rawflag, uint8_t flag); -int blkdev_write(uint8_t minor, uint8_t rawflag, uint8_t flag); /* the following details should be required only by partition parsing code */ #define MAX_PARTITIONS 15 /* must be at least 4, at most 15 */ typedef struct { + transfer_function_t transfer; /* function to read and write sectors */ uint32_t drive_lba_count; /* count of sectors on raw disk device */ - uint8_t drive_number; /* driver's drive number */ uint32_t lba_first[MAX_PARTITIONS]; /* LBA of first sector of each partition; 0 if partition absent */ uint32_t lba_count[MAX_PARTITIONS]; /* count of sectors in each partition; 0 if partition absent */ - transfer_function_t transfer; /* function to read and write sectors */ + uint8_t drive_number; /* driver's drive number */ } blkdev_t; +/* public interface */ +/* public interface */ +extern blkdev_t *blkdev_alloc(void); +extern void blkdev_scan(blkdev_t *blk, uint8_t flags); +#define SWAPSCAN 0x01 +extern int blkdev_open(uint8_t minor, uint16_t flags); +extern int blkdev_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +extern int blkdev_write(uint8_t minor, uint8_t rawflag, uint8_t flag); + #endif diff --git a/Kernel/dev/devide.c b/Kernel/dev/devide.c index ced4c893..a72214a8 100644 --- a/Kernel/dev/devide.c +++ b/Kernel/dev/devide.c @@ -97,6 +97,7 @@ static bool devide_wait(uint8_t bits) static bool devide_transfer_sector(uint8_t drive, uint32_t lba, void *buffer, bool read_notwrite) { + /* FIXME: only safe for LE, and only sensible for Z80/Z180 */ #if 0 ide_reg_lba_3 = ((lba >> 24) & 0xF) | ((drive == 0) ? 0xE0 : 0xF0); // select drive, start loading LBA ide_reg_lba_2 = (lba >> 16); @@ -150,6 +151,7 @@ static void devide_delay(void) static void devide_init_drive(uint8_t drive) { + blkdev_t *blk; uint8_t *buffer, select; uint32_t size; @@ -208,7 +210,13 @@ static void devide_init_drive(uint8_t drive) /* done with our temporary memory */ brelse((bufptr)buffer); - blkdev_add(devide_transfer_sector, drive, size); + blk = blkdev_alloc(); + if (blk) { + blk->transfer = devide_transfer_sector; + blk->drive_number = drive; + blk->drive_lba_count = size; + blkdev_scan(blk, SWAPSCAN); + } return; failout: diff --git a/Kernel/dev/devsd.c b/Kernel/dev/devsd.c index 66ad9a22..e8df58f8 100644 --- a/Kernel/dev/devsd.c +++ b/Kernel/dev/devsd.c @@ -186,6 +186,7 @@ void devsd_init(void) static void sd_init_drive(uint8_t drive) { + blkdev_t *blk; uint32_t sector_count; kprintf("SD drive %d: ", drive); @@ -202,8 +203,13 @@ static void sd_init_drive(uint8_t drive) kputs("weird card\n"); return; } - - blkdev_add(devsd_transfer_sector, drive, sector_count); + blk = blkdev_alloc(); + if (blk) { + blk->transfer = devsd_transfer_sector; + blk->drive_number = drive; + blk->drive_lba_count = sector_count; + blkdev_scan(blk, 0); + } } static int sd_spi_init(uint8_t drive)