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');
}
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
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);
static void devide_init_drive(uint8_t drive)
{
+ blkdev_t *blk;
uint8_t *buffer, select;
uint32_t size;
/* 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:
static void sd_init_drive(uint8_t drive)
{
+ blkdev_t *blk;
uint32_t sector_count;
kprintf("SD drive %d: ", 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)