Don't confuse op->command with low-level ata cmd->command.
Modify __send_disk_op to route commands by drive type.
Add commands for verify and seek operations.
Do ata resets via disk_op also.
****************************************************************/
// Read/write count blocks from a harddrive.
-int
-ata_cmd_data(struct disk_op_s *op)
+static int
+ata_cmd_data(struct disk_op_s *op, int iswrite, int command)
{
u64 lba = op->lba;
struct ata_pio_command cmd;
memset(&cmd, 0, sizeof(cmd));
- cmd.command = op->command;
+ cmd.command = command;
if (op->count >= (1<<8) || lba + op->count >= (1<<28)) {
cmd.sector_count2 = op->count >> 8;
cmd.lba_low2 = lba >> 24;
int ret = send_cmd(op->driveid, &cmd);
if (ret)
return ret;
- return ata_transfer(op, op->command == ATA_CMD_WRITE_SECTORS
- , IDE_SECTOR_SIZE);
+ return ata_transfer(op, iswrite, IDE_SECTOR_SIZE);
+}
+
+int
+process_ata_op(struct disk_op_s *op)
+{
+ switch (op->command) {
+ default:
+ return 0;
+ case CMD_RESET:
+ ata_reset(op->driveid);
+ return 0;
+ case CMD_READ:
+ return ata_cmd_data(op, 0, ATA_CMD_READ_SECTORS);
+ case CMD_WRITE:
+ return ata_cmd_data(op, 1, ATA_CMD_WRITE_SECTORS);
+ }
}
return ata_transfer(op, 0, CDROM_SECTOR_SIZE);
}
+int
+process_atapi_op(struct disk_op_s *op)
+{
+ switch (op->command) {
+ default:
+ return 0;
+ case CMD_RESET:
+ ata_reset(op->driveid);
+ return 0;
+ case CMD_READ:
+ return cdrom_read(op);
+ }
+}
+
// Send a simple atapi command to a drive.
int
ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen
// Send an IDENTIFY_DEVICE_PACKET command to device
memset(buffer, 0, IDE_SECTOR_SIZE);
struct disk_op_s dop;
+ memset(&dop, 0, sizeof(dop));
dop.driveid = driveid;
- dop.command = ATA_CMD_IDENTIFY_DEVICE_PACKET;
dop.count = 1;
dop.lba = 1;
dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
- int ret = ata_cmd_data(&dop);
+ int ret = ata_cmd_data(&dop, 0, ATA_CMD_IDENTIFY_DEVICE_PACKET);
if (ret)
return ret;
SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATAPI);
SET_GLOBAL(ATA.devices[driveid].device, (buffer[0] >> 8) & 0x1f);
SET_GLOBAL(ATA.devices[driveid].blksize, CDROM_SECTOR_SIZE);
+ SET_GLOBAL(ATA.devices[driveid].sectors, (u64)-1);
// fill cdidmap
u8 cdcount = GET_GLOBAL(ATA.cdcount);
// Send an IDENTIFY_DEVICE command to device
memset(buffer, 0, IDE_SECTOR_SIZE);
struct disk_op_s dop;
+ memset(&dop, 0, sizeof(dop));
dop.driveid = driveid;
- dop.command = ATA_CMD_IDENTIFY_DEVICE;
dop.count = 1;
dop.lba = 1;
dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
- int ret = ata_cmd_data(&dop);
+ int ret = ata_cmd_data(&dop, 0, ATA_CMD_IDENTIFY_DEVICE);
if (ret)
return ret;
static void
cdemu_1302(struct bregs *regs, u8 device)
{
- cdemu_access(regs, device, ATA_CMD_READ_SECTORS);
+ cdemu_access(regs, device, CMD_READ);
}
static void
cdemu_1304(struct bregs *regs, u8 device)
{
- cdemu_access(regs, device, 0);
+ cdemu_access(regs, device, CMD_VERIFY);
}
// read disk drive parameters
// Read the Boot Record Volume Descriptor
u8 buffer[2048];
struct disk_op_s dop;
+ memset(&dop, 0, sizeof(dop));
dop.driveid = driveid;
dop.lba = 0x11;
dop.count = 1;
irq_enable();
- int status;
- if (!dop.command)
- // If verify or seek
- status = 0;
- if (dop.command == CMD_CDROM_READ)
- status = cdrom_read(&dop);
- else
- status = ata_cmd_data(&dop);
+ int status = 0;
+ u8 type = GET_GLOBAL(ATA.devices[dop.driveid].type);
+ if (type == ATA_TYPE_ATA)
+ status = process_ata_op(&dop);
+ else if (type == ATA_TYPE_ATAPI)
+ status = process_atapi_op(&dop);
irq_disable();
{
struct disk_op_s dop;
dop.driveid = device;
- dop.command = (command == ATA_CMD_READ_SECTORS ? CMD_CDROM_READ : 0);
+ dop.command = command;
u16 ebda_seg = get_ebda_seg();
int vlba = legacy_lba(
regs, ebda_seg
dop.lba = GET_INT13EXT(regs, lba);
dop.command = command;
dop.driveid = device;
- u8 type = GET_GLOBAL(ATA.devices[device].type);
- if (type == ATA_TYPE_ATA) {
- if (dop.lba >= GET_GLOBAL(ATA.devices[device].sectors)) {
- dprintf(1, "int13_harddisk: function %02x. LBA out of range\n"
- , regs->ah);
- disk_ret(regs, DISK_RET_EPARAM);
- return;
- }
- } else {
- dop.command = CMD_CDROM_READ;
+ if (dop.lba >= GET_GLOBAL(ATA.devices[device].sectors)) {
+ dprintf(1, "int13_harddisk: function %02x. LBA out of range\n"
+ , regs->ah);
+ disk_ret(regs, DISK_RET_EPARAM);
+ return;
}
u16 segment = GET_INT13EXT(regs, segment);
static void
disk_1300(struct bregs *regs, u8 device)
{
- ata_reset(device);
+ struct disk_op_s dop;
+ dop.driveid = device;
+ dop.command = CMD_RESET;
+ send_disk_op(&dop);
}
// read disk status
static void
disk_1302(struct bregs *regs, u8 device)
{
- basic_access(regs, device, ATA_CMD_READ_SECTORS);
+ basic_access(regs, device, CMD_READ);
}
// write disk sectors
static void
disk_1303(struct bregs *regs, u8 device)
{
- basic_access(regs, device, ATA_CMD_WRITE_SECTORS);
+ basic_access(regs, device, CMD_WRITE);
}
// verify disk sectors
static void
disk_1304(struct bregs *regs, u8 device)
{
- basic_access(regs, device, 0);
+ basic_access(regs, device, CMD_VERIFY);
// FIXME verify
}
static void
disk_1342(struct bregs *regs, u8 device)
{
- extended_access(regs, device, ATA_CMD_READ_SECTORS);
+ extended_access(regs, device, CMD_READ);
}
// IBM/MS extended write
static void
disk_1343(struct bregs *regs, u8 device)
{
- extended_access(regs, device, ATA_CMD_WRITE_SECTORS);
+ extended_access(regs, device, CMD_WRITE);
}
// IBM/MS verify
static void
disk_1344(struct bregs *regs, u8 device)
{
- extended_access(regs, device, 0);
+ extended_access(regs, device, CMD_VERIFY);
}
// IBM/MS lock/unlock drive
static void
disk_1347(struct bregs *regs, u8 device)
{
- extended_access(regs, device, 0);
+ extended_access(regs, device, CMD_SEEK);
}
// IBM/MS get drive parameters
u8 command;
};
-#define CMD_CDROM_READ 1
-#define CMD_CDEMU_READ 2
+#define CMD_RESET 0
+#define CMD_READ 2
+#define CMD_WRITE 3
+#define CMD_VERIFY 4
+#define CMD_SEEK 7
/****************************************************************
// ata.c
extern struct ata_s ATA;
-int ata_cmd_data(struct disk_op_s *op);
int cdrom_read(struct disk_op_s *op);
int ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen
, u32 length, void *buf_fl);
-void ata_reset(int driveid);
void hard_drive_setup();
+int process_ata_op(struct disk_op_s *op);
+int process_atapi_op(struct disk_op_s *op);
void map_drive(int driveid);
// floppy.c