Misc ATA cleanups.
Remove some unused defines.
Rename ATA_TYPE_* to DTYPE_* and move from atabits.h to disk.h.
Rename ATA_TRANSLATION_* to TRANSLATION_* and move from atabits.h to disk.h.
Convert bios is-drive-ready call to use send_disk_op().
Only add atapi devices to the cdmap if they are cd/dvd roms.
Remove 'device' from struct ata_devices_s.
diff --git a/src/ata.c b/src/ata.c
index 2996728..20d360a 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -18,13 +18,6 @@
#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
@@ -125,7 +118,7 @@
// 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:
@@ -135,6 +128,30 @@
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
@@ -325,15 +342,12 @@
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);
}
}
@@ -412,13 +426,10 @@
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);
}
}
@@ -463,10 +474,10 @@
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
@@ -485,10 +496,10 @@
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) {
@@ -510,7 +521,7 @@
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) {
@@ -520,8 +531,8 @@
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;
@@ -598,23 +609,24 @@
// 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;
}
@@ -636,8 +648,7 @@
// 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]);
diff --git a/src/atabits.h b/src/atabits.h
index 688b70b..8495107 100644
--- a/src/atabits.h
+++ b/src/atabits.h
@@ -105,31 +105,3 @@
#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
diff --git a/src/cdrom.c b/src/cdrom.c
index 2cb3f0f..c62829a 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -9,7 +9,7 @@
#include "util.h" // memset
#include "bregs.h" // struct bregs
#include "biosvar.h" // GET_EBDA
-#include "atabits.h" // ATA_TYPE_ATAPI
+#include "atabits.h" // ATA_CMD_REQUEST_SENSE
/****************************************************************
@@ -404,8 +404,6 @@
if (cdid >= ATA.cdcount)
return 1;
int driveid = GET_GLOBAL(ATA.idmap[1][cdid]);
- if (GET_GLOBAL(ATA.devices[driveid].device) != ATA_DEVICE_CDROM)
- return 2;
int ret = atapi_is_ready(driveid);
if (ret)
diff --git a/src/disk.c b/src/disk.c
index d012af7..4ace85c 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -12,7 +12,7 @@
#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
/****************************************************************
@@ -57,9 +57,9 @@
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();
@@ -343,12 +343,14 @@
{
// 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
@@ -462,7 +464,7 @@
, 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);
@@ -506,13 +508,13 @@
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 {
diff --git a/src/disk.h b/src/disk.h
index 441eca6..260affa 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -149,11 +149,12 @@
u8 command;
};
-#define CMD_RESET 0
-#define CMD_READ 2
-#define CMD_WRITE 3
-#define CMD_VERIFY 4
-#define CMD_SEEK 7
+#define CMD_RESET 0x00
+#define CMD_READ 0x02
+#define CMD_WRITE 0x03
+#define CMD_VERIFY 0x04
+#define CMD_SEEK 0x07
+#define CMD_ISREADY 0x10
/****************************************************************
@@ -175,7 +176,6 @@
struct ata_device_s {
u8 type; // Detected type of ata (ata/atapi/none/unknown)
- u8 device; // Detected type of attached devices (hd/cd/none)
u8 removable; // Removable device flag
u16 blksize; // block size
u8 version; // ATA/ATAPI version
@@ -189,12 +189,21 @@
u64 sectors; // Total sectors count
};
+#define DTYPE_NONE 0x00
+#define DTYPE_ATA 0x02
+#define DTYPE_ATAPI 0x03
+
+#define TRANSLATION_NONE 0
+#define TRANSLATION_LBA 1
+#define TRANSLATION_LARGE 2
+#define TRANSLATION_RECHS 3
+
struct ata_s {
// ATA channels info
struct ata_channel_s channels[CONFIG_MAX_ATA_INTERFACES];
// ATA devices info
- struct ata_device_s devices[CONFIG_MAX_ATA_DEVICES];
+ struct ata_device_s devices[CONFIG_MAX_ATA_DEVICES];
//
// map between bios hd/cd id and ata channels
u8 cdcount;