X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Ffloppy.c;h=383744a22d9d8fa5debc025053d4d2af2463de5c;hb=refs%2Fheads%2Fcoreboot;hp=248950715cccedc1aa7a95a48151d25e779ca8f6;hpb=51fd0a17153a8c94c97f9a80afd6e238fb542e3b;p=seabios.git diff --git a/src/floppy.c b/src/floppy.c index 2489507..383744a 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -9,12 +9,14 @@ #include "disk.h" // DISK_RET_SUCCESS #include "config.h" // CONFIG_FLOPPY #include "biosvar.h" // SET_BDA -#include "util.h" // irq_disable +#include "util.h" // wait_irq #include "cmos.h" // inb_cmos #include "pic.h" // eoi_pic1 #include "bregs.h" // struct bregs +#include "boot.h" // boot_add_floppy +#include "pci.h" // pci_to_bdf +#include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA -#define FLOPPY_SECTOR_SIZE 512 #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 #define FLOPPY_MOTOR_TICKS 37 // ~2 seconds @@ -89,40 +91,45 @@ struct floppyinfo_s FloppyInfo[] VAR16VISIBLE = { { {2, 40, 8}, 0x00, 0x27}, }; -int -addFloppy(int floppyid, int ftype, int driver) +struct drive_s * +init_floppy(int floppyid, int ftype) { if (ftype <= 0 || ftype >= ARRAY_SIZE(FloppyInfo)) { dprintf(1, "Bad floppy type %d\n", ftype); - return -1; + return NULL; } - int driveid = Drives.drivecount; - if (driveid >= ARRAY_SIZE(Drives.drives)) - return -1; - Drives.drivecount++; - memset(&Drives.drives[driveid], 0, sizeof(Drives.drives[0])); - Drives.drives[driveid].cntl_id = floppyid; - Drives.drives[driveid].type = driver; - Drives.drives[driveid].blksize = FLOPPY_SECTOR_SIZE; - Drives.drives[driveid].floppy_type = ftype; - Drives.drives[driveid].sectors = (u16)-1; - - memcpy(&Drives.drives[driveid].lchs, &FloppyInfo[ftype].chs + 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 = DTYPE_FLOPPY; + drive_g->blksize = DISK_SECTOR_SIZE; + drive_g->floppy_type = ftype; + drive_g->sectors = (u64)-1; + + memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs , sizeof(FloppyInfo[ftype].chs)); - - map_floppy_drive(driveid); - return driveid; + return drive_g; } -void -describe_floppy(int driveid) +static void +addFloppy(int floppyid, int ftype) { - printf("drive %c", 'A' + Drives.drives[driveid].cntl_id); + struct drive_s *drive_g = init_floppy(floppyid, ftype); + if (!drive_g) + return; + char *desc = znprintf(MAXDESCSIZE, "Floppy [drive %c]", 'A' + floppyid); + struct pci_device *pci = pci_find_class(PCI_CLASS_BRIDGE_ISA); /* isa-to-pci bridge */ + int prio = bootprio_find_fdc_device(pci, PORT_FD_BASE, floppyid); + boot_add_floppy(drive_g, desc, prio); } void -floppy_setup() +floppy_setup(void) { if (! CONFIG_FLOPPY) return; @@ -133,14 +140,14 @@ floppy_setup() } else { u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); if (type & 0xf0) - addFloppy(0, type >> 4, DTYPE_FLOPPY); + addFloppy(0, type >> 4); if (type & 0x0f) - addFloppy(1, type & 0x0f, DTYPE_FLOPPY); + addFloppy(1, type & 0x0f); } outb(0x02, PORT_DMA1_MASK_REG); - enable_hwirq(6, entry_0e); + enable_hwirq(6, FUNC16(entry_0e)); } // Find a floppy type that matches a given image size. @@ -150,7 +157,7 @@ find_floppy_type(u32 size) int i; for (i=1; icylinders * c->heads * c->spt * FLOPPY_SECTOR_SIZE == size) + if (c->cylinders * c->heads * c->spt * DISK_SECTOR_SIZE == size) return i; } return -1; @@ -162,7 +169,7 @@ find_floppy_type(u32 size) ****************************************************************/ static void -floppy_reset_controller() +floppy_reset_controller(void) { // Reset controller u8 val8 = inb(PORT_FD_DOR); @@ -175,21 +182,20 @@ floppy_reset_controller() } static int -wait_floppy_irq() +wait_floppy_irq(void) { - irq_enable(); + ASSERT16(); u8 v; for (;;) { - if (!GET_BDA(floppy_motor_counter)) { - irq_disable(); + if (!GET_BDA(floppy_motor_counter)) return -1; - } v = GET_BDA(floppy_recalibration_status); if (v & FRS_TIMEOUT) break; - cpu_relax(); + // Could use wait_irq() here, but that causes issues on + // bochs, so use yield() instead. + yield(); } - irq_disable(); v &= ~FRS_TIMEOUT; SET_BDA(floppy_recalibration_status, v); @@ -319,7 +325,7 @@ floppy_drive_recal(u8 floppyid) } static int -floppy_media_sense(u8 driveid) +floppy_media_sense(struct drive_s *drive_g) { // for now cheat and get drive type from CMOS, // assume media is same as drive type @@ -352,18 +358,18 @@ floppy_media_sense(u8 driveid) // 110 reserved // 111 all other formats/drives - u8 ftype = GET_GLOBAL(Drives.drives[driveid].floppy_type); + u8 ftype = GET_GLOBAL(drive_g->floppy_type); SET_BDA(floppy_last_data_rate, GET_GLOBAL(FloppyInfo[ftype].config_data)); - u8 floppyid = GET_GLOBAL(Drives.drives[driveid].cntl_id); + u8 floppyid = GET_GLOBAL(drive_g->cntl_id); SET_BDA(floppy_media_state[floppyid] , GET_GLOBAL(FloppyInfo[ftype].media_state)); return DISK_RET_SUCCESS; } static int -check_recal_drive(u8 driveid) +check_recal_drive(struct drive_s *drive_g) { - u8 floppyid = GET_GLOBAL(Drives.drives[driveid].cntl_id); + u8 floppyid = GET_GLOBAL(drive_g->cntl_id); if ((GET_BDA(floppy_recalibration_status) & (1<lba; - u8 driveid = op->driveid; u32 tmp = lba + 1; - u16 nlspt = GET_GLOBAL(Drives.drives[driveid].lchs.spt); + u16 nlspt = GET_GLOBAL(op->drive_g->lchs.spt); *sector = tmp % nlspt; tmp /= nlspt; - u16 nlh = GET_GLOBAL(Drives.drives[driveid].lchs.heads); + u16 nlh = GET_GLOBAL(op->drive_g->lchs.heads); *head = tmp % nlh; tmp /= nlh; @@ -403,7 +408,7 @@ lba2chs(struct disk_op_s *op, u8 *track, u8 *sector, u8 *head) static int floppy_reset(struct disk_op_s *op) { - u8 floppyid = GET_GLOBAL(Drives.drives[op->driveid].cntl_id); + u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); set_diskette_current_cyl(floppyid, 0); // current cylinder return DISK_RET_SUCCESS; } @@ -412,7 +417,7 @@ floppy_reset(struct disk_op_s *op) static int floppy_read(struct disk_op_s *op) { - int res = check_recal_drive(op->driveid); + int res = check_recal_drive(op->drive_g); if (res) goto fail; @@ -420,7 +425,7 @@ floppy_read(struct disk_op_s *op) lba2chs(op, &track, §or, &head); // send read-normal-data command (9 bytes) to controller - u8 floppyid = GET_GLOBAL(Drives.drives[op->driveid].cntl_id); + u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); u8 data[12]; data[0] = 0xe6; // e6: read normal data data[1] = (head << 2) | floppyid; // HD DR1 DR2 @@ -432,7 +437,7 @@ floppy_read(struct disk_op_s *op) data[7] = FLOPPY_GAPLEN; data[8] = FLOPPY_DATALEN; - res = floppy_cmd(op, op->count * FLOPPY_SECTOR_SIZE, data, 9); + res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); if (res) goto fail; @@ -453,7 +458,7 @@ fail: static int floppy_write(struct disk_op_s *op) { - int res = check_recal_drive(op->driveid); + int res = check_recal_drive(op->drive_g); if (res) goto fail; @@ -461,7 +466,7 @@ floppy_write(struct disk_op_s *op) lba2chs(op, &track, §or, &head); // send write-normal-data command (9 bytes) to controller - u8 floppyid = GET_GLOBAL(Drives.drives[op->driveid].cntl_id); + u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); u8 data[12]; data[0] = 0xc5; // c5: write normal data data[1] = (head << 2) | floppyid; // HD DR1 DR2 @@ -473,7 +478,7 @@ floppy_write(struct disk_op_s *op) data[7] = FLOPPY_GAPLEN; data[8] = FLOPPY_DATALEN; - res = floppy_cmd(op, op->count * FLOPPY_SECTOR_SIZE, data, 9); + res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); if (res) goto fail; @@ -497,7 +502,7 @@ fail: static int floppy_verify(struct disk_op_s *op) { - int res = check_recal_drive(op->driveid); + int res = check_recal_drive(op->drive_g); if (res) goto fail; @@ -505,7 +510,7 @@ floppy_verify(struct disk_op_s *op) lba2chs(op, &track, §or, &head); // ??? should track be new val from return_status[3] ? - u8 floppyid = GET_GLOBAL(Drives.drives[op->driveid].cntl_id); + u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); set_diskette_current_cyl(floppyid, track); return DISK_RET_SUCCESS; fail: @@ -517,14 +522,14 @@ fail: static int floppy_format(struct disk_op_s *op) { - int ret = check_recal_drive(op->driveid); + int ret = check_recal_drive(op->drive_g); if (ret) return ret; u8 head = op->lba; // send format-track command (6 bytes) to controller - u8 floppyid = GET_GLOBAL(Drives.drives[op->driveid].cntl_id); + u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); u8 data[12]; data[0] = 0x4d; // 4d: format track data[1] = (head << 2) | floppyid; // HD DR1 DR2 @@ -577,7 +582,7 @@ process_floppy_op(struct disk_op_s *op) // INT 0Eh Diskette Hardware ISR Entry Point void VISIBLE16 -handle_0e() +handle_0e(void) { debug_isr(DEBUG_ISR_0e); if (! CONFIG_FLOPPY) @@ -600,7 +605,7 @@ done: // Called from int08 handler. void -floppy_tick() +floppy_tick(void) { if (! CONFIG_FLOPPY) return;