diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-08-16 18:48:38 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-08-16 18:48:38 -0400 |
commit | af5aabb09f2ee803ab25bdcd2c44522cdb49f5fe (patch) | |
tree | 574a46dc5fc24a4bef3a66586a5c9069c816fae0 /src/block.c | |
parent | 48410fdcc11a72b2a463639c8a65f3a42e157a1b (diff) | |
download | seabios-af5aabb09f2ee803ab25bdcd2c44522cdb49f5fe.tar.gz |
Unify floppy and harddrive command routing.
Implement low-level floppy commands using the disk_op structure.
The requests can then be filled using the regular disk_13xx functions.
Diffstat (limited to 'src/block.c')
-rw-r--r-- | src/block.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/block.c b/src/block.c index 70fffae9..3345db71 100644 --- a/src/block.c +++ b/src/block.c @@ -9,6 +9,7 @@ #include "biosvar.h" // GET_GLOBAL #include "cmos.h" // inb_cmos #include "util.h" // dprintf +#include "ata.h" // process_ata_op struct drives_s Drives VAR16_32; @@ -225,6 +226,64 @@ map_floppy_drive(int driveid) /**************************************************************** + * 16bit calling interface + ****************************************************************/ + +// Execute a disk_op request. +static int +process_op(struct disk_op_s *op) +{ + u8 type = GET_GLOBAL(Drives.drives[op->driveid].type); + switch (type) { + case DTYPE_ATA: + return process_ata_op(op); + case DTYPE_ATAPI: + return process_atapi_op(op); + case DTYPE_FLOPPY: + return process_floppy_op(op); + default: + op->count = 0; + return DISK_RET_EPARAM; + } +} + +// Execute a "disk_op_s" request - this runs on a stack in the ebda. +static int +__send_disk_op(struct disk_op_s *op_far, u16 op_seg) +{ + struct disk_op_s dop; + memcpy_far(GET_SEG(SS), &dop + , op_seg, op_far + , sizeof(dop)); + + dprintf(DEBUG_HDL_13, "disk_op d=%d lba=%d buf=%p count=%d cmd=%d\n" + , dop.driveid, (u32)dop.lba, dop.buf_fl + , dop.count, dop.command); + + irq_enable(); + + int status = process_op(&dop); + + irq_disable(); + + // Update count with total sectors transferred. + SET_FARVAR(op_seg, op_far->count, dop.count); + + return status; +} + +// Execute a "disk_op_s" request by jumping to a stack in the ebda. +int +send_disk_op(struct disk_op_s *op) +{ + if (! CONFIG_DRIVES) + return -1; + + return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op); +} + + +/**************************************************************** * Setup ****************************************************************/ |