#define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
-struct ata_channel_s ATA_channels[CONFIG_MAX_ATA_INTERFACES] VAR16_32;
+struct ata_channel_s ATA_channels[CONFIG_MAX_ATA_INTERFACES] VAR16VISIBLE;
/****************************************************************
goto done;
}
}
+ } else {
+ // QEMU doesn't reset dh on reset, so set it explicitly.
+ outb(ATA_CB_DH_DEV0, iobase1 + ATA_CB_DH);
}
// On a user-reset request, wait for RDY if it is an ATA device.
u8 channel = ataid / 2;
u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
u8 status = inb(iobase1 + ATA_CB_STAT);
- return (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY;
+ if ((status & (ATA_CB_STAT_BSY|ATA_CB_STAT_RDY)) == ATA_CB_STAT_RDY)
+ return DISK_RET_SUCCESS;
+ return DISK_RET_ENOTREADY;
}
static int
return 0;
switch (op->command) {
- default:
- return 0;
case CMD_RESET:
ata_reset(op->driveid);
- return 0;
+ return DISK_RET_SUCCESS;
case CMD_ISREADY:
return isready(op->driveid);
+ case CMD_FORMAT:
+ case CMD_VERIFY:
+ case CMD_SEEK:
+ return DISK_RET_SUCCESS;
+ default:
+ op->count = 0;
+ return DISK_RET_EPARAM;
}
}
if (!CONFIG_ATA)
return 0;
+ int ret;
switch (op->command) {
case CMD_READ:
- return ata_cmd_data(op, 0, ATA_CMD_READ_SECTORS);
+ ret = ata_cmd_data(op, 0, ATA_CMD_READ_SECTORS);
+ break;
case CMD_WRITE:
- return ata_cmd_data(op, 1, ATA_CMD_WRITE_SECTORS);
+ ret = ata_cmd_data(op, 1, ATA_CMD_WRITE_SECTORS);
+ break;
default:
return process_ata_misc_op(op);
}
+ if (ret)
+ return DISK_RET_EBADTRACK;
+ return DISK_RET_SUCCESS;
}
int
process_atapi_op(struct disk_op_s *op)
{
+ int ret;
switch (op->command) {
case CMD_READ:
- return cdrom_read(op);
+ ret = cdrom_read(op);
+ break;
+ case CMD_FORMAT:
+ case CMD_WRITE:
+ return DISK_RET_EWRITEPROTECT;
default:
return process_ata_misc_op(op);
}
+ if (ret)
+ return DISK_RET_EBADTRACK;
+ return DISK_RET_SUCCESS;
}
// Send a simple atapi command to a drive.
{
// Device detection
u64 end = calc_future_tsc(IDE_TIMEOUT);
- int ataid, last_reset_ataid=-1, driveid=0;
+ int ataid, last_reset_ataid=-1;
for (ataid=0; ataid<CONFIG_MAX_ATA_INTERFACES*2; ataid++) {
u8 channel = ataid / 2;
u8 slave = ataid % 2;
continue;
// Prepare new driveid.
+ u8 driveid = GET_GLOBAL(Drives.drivecount);
if (driveid >= ARRAY_SIZE(Drives.drives))
break;
memset(&Drives.drives[driveid], 0, sizeof(Drives.drives[0]));
// No ATA drive found
continue;
}
- driveid++;
+ SET_GLOBAL(Drives.drivecount, driveid+1);
u16 resetresult = buffer[93];
dprintf(6, "ata_detect resetresult=%04x\n", resetresult);