#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;
+struct drives_s Drives VAR16VISIBLE;
/****************************************************************
fdpt->checksum -= checksum(fdpt, sizeof(*fdpt));
if (driveid == 0)
- SET_IVT(0x41, get_ebda_seg()
- , offsetof(struct extended_bios_data_area_s, fdpt[0]));
+ SET_IVT(0x41, SEGOFF(get_ebda_seg(), offsetof(
+ struct extended_bios_data_area_s, fdpt[0])));
else
- SET_IVT(0x46, get_ebda_seg()
- , offsetof(struct extended_bios_data_area_s, fdpt[1]));
+ SET_IVT(0x46, SEGOFF(get_ebda_seg(), offsetof(
+ struct extended_bios_data_area_s, fdpt[1])));
}
// Map a drive (that was registered via add_bcv_hd)
}
}
+// Show a one line description (without trailing newline) of a drive.
+void
+describe_drive(int driveid)
+{
+ ASSERT32();
+ u8 type = GET_GLOBAL(Drives.drives[driveid].type);
+ switch (type) {
+ case DTYPE_FLOPPY:
+ describe_floppy(driveid);
+ break;
+ case DTYPE_ATA:
+ describe_ata(driveid);
+ break;
+ case DTYPE_ATAPI:
+ describe_atapi(driveid);
+ break;
+ case DTYPE_RAMDISK:
+ describe_ramdisk(driveid);
+ break;
+ default:
+ printf("Unknown");
+ break;
+ }
+}
+
+
+/****************************************************************
+ * 16bit calling interface
+ ****************************************************************/
+
+// Execute a disk_op request.
+int
+process_op(struct disk_op_s *op)
+{
+ u8 type = GET_GLOBAL(Drives.drives[op->driveid].type);
+ switch (type) {
+ case DTYPE_FLOPPY:
+ return process_floppy_op(op);
+ case DTYPE_ATA:
+ return process_ata_op(op);
+ case DTYPE_ATAPI:
+ return process_atapi_op(op);
+ case DTYPE_RAMDISK:
+ return process_ramdisk_op(op);
+ case DTYPE_CDEMU:
+ return process_cdemu_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;
+ ASSERT16();
+
+ return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op);
+}
+
/****************************************************************
* Setup