#include "disk.h" // struct ata_s
#include "atabits.h" // ATA_CB_STAT
-#define TIMEOUT 0
-#define BSY 1
-#define NOT_BSY 2
-#define NOT_BSY_DRQ 3
-#define NOT_BSY_NOT_DRQ 4
-#define NOT_BSY_RDY 5
-
#define IDE_SECTOR_SIZE 512
#define CDROM_SECTOR_SIZE 2048
// On a user-reset request, wait for RDY if it is an ATA device.
u8 type=GET_GLOBAL(ATA.devices[driveid].type);
- if (type == ATA_TYPE_ATA)
+ if (type == DTYPE_ATA)
status = await_rdy(iobase1);
done:
dprintf(6, "ata_reset exit status=%x\n", status);
}
+static int
+isready(int driveid)
+{
+ // Read the status from controller
+ u8 channel = driveid / 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;
+}
+
+static int
+process_ata_misc_op(struct disk_op_s *op)
+{
+ switch (op->command) {
+ default:
+ return 0;
+ case CMD_RESET:
+ ata_reset(op->driveid);
+ return 0;
+ case CMD_ISREADY:
+ return isready(op->driveid);
+ }
+}
+
/****************************************************************
* ATA send command
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);
+ default:
+ return process_ata_misc_op(op);
}
}
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);
+ default:
+ return process_ata_misc_op(op);
}
}
u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt);
if (cylinders <= 1024 && heads <= 16 && spt <= 63)
- return ATA_TRANSLATION_NONE;
+ return TRANSLATION_NONE;
if (cylinders * heads <= 131072)
- return ATA_TRANSLATION_LARGE;
- return ATA_TRANSLATION_LBA;
+ return TRANSLATION_LARGE;
+ return TRANSLATION_LBA;
}
static void
dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation="
, channel, slave, cylinders, heads, spt);
switch (translation) {
- case ATA_TRANSLATION_NONE:
+ case TRANSLATION_NONE:
dprintf(1, "none");
break;
- case ATA_TRANSLATION_LBA:
+ case TRANSLATION_LBA:
dprintf(1, "lba");
spt = 63;
if (sectors > 63*255*1024) {
heads = 16;
cylinders = sect / heads;
break;
- case ATA_TRANSLATION_RECHS:
+ case TRANSLATION_RECHS:
dprintf(1, "r-echs");
// Take care not to overflow
if (heads==16) {
cylinders = (u16)((u32)(cylinders)*16/15);
}
// then go through the large bitshift process
- case ATA_TRANSLATION_LARGE:
- if (translation == ATA_TRANSLATION_LARGE)
+ case TRANSLATION_LARGE:
+ if (translation == TRANSLATION_LARGE)
dprintf(1, "large");
while (cylinders > 1024) {
cylinders >>= 1;
// Success - setup as ATAPI.
extract_identify(driveid, buffer);
- SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATAPI);
- SET_GLOBAL(ATA.devices[driveid].device, (buffer[0] >> 8) & 0x1f);
+ SET_GLOBAL(ATA.devices[driveid].type, DTYPE_ATAPI);
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);
- SET_GLOBAL(ATA.idmap[1][cdcount], driveid);
- SET_GLOBAL(ATA.cdcount, cdcount+1);
+ u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
// Report drive info to user.
u8 channel = driveid / 2;
u8 slave = driveid % 2;
printf("ata%d-%d: %s ATAPI-%d %s\n", channel, slave
, ATA.devices[driveid].model, ATA.devices[driveid].version
- , (ATA.devices[driveid].device == ATA_DEVICE_CDROM
- ? "CD-Rom/DVD-Rom" : "Device"));
+ , (iscd ? "CD-Rom/DVD-Rom" : "Device"));
+
+ // fill cdidmap
+ if (iscd) {
+ u8 cdcount = GET_GLOBAL(ATA.cdcount);
+ SET_GLOBAL(ATA.idmap[1][cdcount], driveid);
+ SET_GLOBAL(ATA.cdcount, cdcount+1);
+ }
return 0;
}
// Success - setup as ATA.
extract_identify(driveid, buffer);
- SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATA);
- SET_GLOBAL(ATA.devices[driveid].device, ATA_DEVICE_HD);
+ SET_GLOBAL(ATA.devices[driveid].type, DTYPE_ATA);
SET_GLOBAL(ATA.devices[driveid].blksize, IDE_SECTOR_SIZE);
SET_GLOBAL(ATA.devices[driveid].pchs.cylinders, buffer[1]);
#define ATA_CMD_WRITE_MULTIPLE 0xC5
#define ATA_CMD_WRITE_SECTORS 0x30
#define ATA_CMD_WRITE_VERIFY 0x3C
-
-#define ATA_IFACE_NONE 0x00
-#define ATA_IFACE_ISA 0x00
-#define ATA_IFACE_PCI 0x01
-
-#define ATA_TYPE_NONE 0x00
-#define ATA_TYPE_ATA 0x02
-#define ATA_TYPE_ATAPI 0x03
-
-#define ATA_DEVICE_NONE 0x00
-#define ATA_DEVICE_HD 0xFF
-#define ATA_DEVICE_CDROM 0x05
-
-#define ATA_MODE_NONE 0x00
-#define ATA_MODE_PIO16 0x00
-#define ATA_MODE_PIO32 0x01
-#define ATA_MODE_ISADMA 0x02
-#define ATA_MODE_PCIDMA 0x03
-#define ATA_MODE_USEIRQ 0x10
-
-#define ATA_TRANSLATION_NONE 0
-#define ATA_TRANSLATION_LBA 1
-#define ATA_TRANSLATION_LARGE 2
-#define ATA_TRANSLATION_RECHS 3
-
-#define ATA_DATA_NO 0x00
-#define ATA_DATA_IN 0x01
-#define ATA_DATA_OUT 0x02
#include "pic.h" // eoi_pic2
#include "bregs.h" // struct bregs
#include "pci.h" // pci_bdf_to_bus
-#include "atabits.h" // ATA_CB_STAT
+#include "atabits.h" // ATA_CB_DC
/****************************************************************
int status = 0;
u8 type = GET_GLOBAL(ATA.devices[dop.driveid].type);
- if (type == ATA_TYPE_ATA)
+ if (type == DTYPE_ATA)
status = process_ata_op(&dop);
- else if (type == ATA_TYPE_ATAPI)
+ else if (type == DTYPE_ATAPI)
status = process_atapi_op(&dop);
irq_disable();
{
// should look at 40:8E also???
- // Read the status from controller
- u8 status = inb(GET_GLOBAL(ATA.channels[device/2].iobase1) + ATA_CB_STAT);
- if ( (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY )
- disk_ret(regs, DISK_RET_SUCCESS);
- else
+ struct disk_op_s dop;
+ dop.driveid = device;
+ dop.command = CMD_ISREADY;
+ int status = send_disk_op(&dop);
+ if (status)
disk_ret(regs, DISK_RET_ENOTREADY);
+ else
+ disk_ret(regs, DISK_RET_SUCCESS);
}
// recalibrate
, size, type, npc, nph, npspt, (u32)lba, blksize);
SET_INT13DPT(regs, size, 26);
- if (type == ATA_TYPE_ATA) {
+ if (type == DTYPE_ATA) {
if (lba > (u64)npspt*nph*0x3fff) {
SET_INT13DPT(regs, infos, 0x00); // geometry is invalid
SET_INT13DPT(regs, cylinders, 0x3fff);
u8 irq = GET_GLOBAL(ATA.channels[channel].irq);
u16 options = 0;
- if (type == ATA_TYPE_ATA) {
+ if (type == DTYPE_ATA) {
u8 translation = GET_GLOBAL(ATA.devices[device].translation);
- if (translation != ATA_TRANSLATION_NONE) {
+ if (translation != TRANSLATION_NONE) {
options |= 1<<3; // CHS translation
- if (translation == ATA_TRANSLATION_LBA)
+ if (translation == TRANSLATION_LBA)
options |= 1<<9;
- if (translation == ATA_TRANSLATION_RECHS)
+ if (translation == TRANSLATION_RECHS)
options |= 3<<9;
}
} else {