From b11443614f5ae7326aa5f238534a19660b2cf4a5 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 11 Aug 2009 20:43:38 -0400 Subject: [PATCH] Densely populate ATA.devices list. Populate ATA.devices in order of drives found; the array index no longer correlates with the ATA.channels list. Add cntl_id to device struct for finding the channel info. --- src/ata.c | 66 +++++++++++++++++++++++++++++++++--------------------- src/disk.c | 24 ++++++++++---------- src/disk.h | 3 ++- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src/ata.c b/src/ata.c index 20d360a..a833c1d 100644 --- a/src/ata.c +++ b/src/ata.c @@ -79,11 +79,12 @@ ndelay_await_not_bsy(u16 iobase1) } // Reset a drive -void +static void ata_reset(int driveid) { - u8 channel = driveid / 2; - u8 slave = driveid % 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); @@ -132,7 +133,8 @@ static int isready(int driveid) { // Read the status from controller - u8 channel = driveid / 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + 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; @@ -176,8 +178,9 @@ struct ata_pio_command { static int send_cmd(int driveid, struct ata_pio_command *cmd) { - u8 channel = driveid / 2; - u8 slave = driveid % 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); @@ -243,7 +246,8 @@ ata_transfer(struct disk_op_s *op, int iswrite, int blocksize) dprintf(16, "ata_transfer id=%d write=%d count=%d bs=%d buf=%p\n" , op->driveid, iswrite, op->count, blocksize, op->buf_fl); - u8 channel = op->driveid / 2; + u8 ataid = GET_GLOBAL(ATA.devices[op->driveid].cntl_id); + u8 channel = ataid / 2; u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); int count = op->count; @@ -360,7 +364,8 @@ process_ata_op(struct disk_op_s *op) static int send_atapi_cmd(int driveid, u8 *cmdbuf, u8 cmdlen, u16 blocksize) { - u8 channel = driveid / 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); @@ -461,9 +466,10 @@ get_translation(int driveid) { if (! CONFIG_COREBOOT) { // Emulators pass in the translation info via nvram. - u8 channel = driveid / 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2); - translation >>= 2 * (driveid % 4); + translation >>= 2 * (ataid % 4); translation &= 0x03; return translation; } @@ -486,8 +492,9 @@ setup_translation(int driveid) u8 translation = get_translation(driveid); SET_GLOBAL(ATA.devices[driveid].translation, translation); - u8 channel = driveid / 2; - u8 slave = driveid % 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; u16 heads = GET_GLOBAL(ATA.devices[driveid].pchs.heads); u16 cylinders = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders); u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt); @@ -615,8 +622,9 @@ init_drive_atapi(int driveid, u16 *buffer) u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05; // Report drive info to user. - u8 channel = driveid / 2; - u8 slave = driveid % 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; printf("ata%d-%d: %s ATAPI-%d %s\n", channel, slave , ATA.devices[driveid].model, ATA.devices[driveid].version , (iscd ? "CD-Rom/DVD-Rom" : "Device")); @@ -666,8 +674,9 @@ init_drive_ata(int driveid, u16 *buffer) setup_translation(driveid); // Report drive info to user. - u8 channel = driveid / 2; - u8 slave = driveid % 2; + u8 ataid = GET_GLOBAL(ATA.devices[driveid].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; char *model = ATA.devices[driveid].model; printf("ata%d-%d: %s ATA-%d Hard-Disk ", channel, slave, model , ATA.devices[driveid].version); @@ -711,10 +720,10 @@ ata_detect() { // Device detection u64 end = calc_future_tsc(IDE_TIMEOUT); - int driveid, last_reset_driveid=-1; - for(driveid=0; driveid= ARRAY_SIZE(ATA.devices)) + break; + memset(&ATA.devices[driveid], 0, sizeof(ATA.devices[0])); + ATA.devices[driveid].cntl_id = ataid; + // reset the channel - if (slave && driveid == last_reset_driveid + 1) { + if (slave && ataid == last_reset_ataid + 1) { // The drive was just reset - no need to reset it again. } else { ata_reset(driveid); - last_reset_driveid = driveid; + last_reset_ataid = ataid; } // check for ATAPI @@ -773,6 +788,7 @@ ata_detect() // No ATA drive found continue; } + driveid++; u16 resetresult = buffer[93]; dprintf(6, "ata_detect resetresult=%04x\n", resetresult); @@ -780,7 +796,7 @@ ata_detect() // resetresult looks valid and device 0 is responding to // device 1 requests - device 1 must not be present - skip // detection. - driveid++; + ataid++; } printf("\n"); diff --git a/src/disk.c b/src/disk.c index 4ace85c..609beaa 100644 --- a/src/disk.c +++ b/src/disk.c @@ -464,7 +464,14 @@ disk_1348(struct bregs *regs, u8 device) , size, type, npc, nph, npspt, (u32)lba, blksize); SET_INT13DPT(regs, size, 26); - if (type == DTYPE_ATA) { + if (type == DTYPE_ATAPI) { + // 0x74 = removable, media change, lockable, max values + SET_INT13DPT(regs, infos, 0x74); + SET_INT13DPT(regs, cylinders, 0xffffffff); + SET_INT13DPT(regs, heads, 0xffffffff); + SET_INT13DPT(regs, spt, 0xffffffff); + SET_INT13DPT(regs, sector_count, (u64)-1); + } else { if (lba > (u64)npspt*nph*0x3fff) { SET_INT13DPT(regs, infos, 0x00); // geometry is invalid SET_INT13DPT(regs, cylinders, 0x3fff); @@ -475,18 +482,10 @@ disk_1348(struct bregs *regs, u8 device) SET_INT13DPT(regs, heads, (u32)nph); SET_INT13DPT(regs, spt, (u32)npspt); SET_INT13DPT(regs, sector_count, lba); - } else { - // ATAPI - // 0x74 = removable, media change, lockable, max values - SET_INT13DPT(regs, infos, 0x74); - SET_INT13DPT(regs, cylinders, 0xffffffff); - SET_INT13DPT(regs, heads, 0xffffffff); - SET_INT13DPT(regs, spt, 0xffffffff); - SET_INT13DPT(regs, sector_count, (u64)-1); } SET_INT13DPT(regs, blksize, blksize); - if (size < 30) { + if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) { disk_ret(regs, DISK_RET_SUCCESS); return; } @@ -501,8 +500,9 @@ disk_1348(struct bregs *regs, u8 device) , offsetof(struct extended_bios_data_area_s, dpte)); // Fill in dpte - u8 channel = device / 2; - u8 slave = device % 2; + u8 ataid = GET_GLOBAL(ATA.devices[device].cntl_id); + u8 channel = ataid / 2; + u8 slave = ataid % 2; u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); u8 irq = GET_GLOBAL(ATA.channels[channel].irq); diff --git a/src/disk.h b/src/disk.h index 260affa..915c53f 100644 --- a/src/disk.h +++ b/src/disk.h @@ -175,10 +175,11 @@ struct ata_channel_s { }; struct ata_device_s { - u8 type; // Detected type of ata (ata/atapi/none/unknown) + u8 type; // Detected type of ata (ata/atapi/none) u8 removable; // Removable device flag u16 blksize; // block size u8 version; // ATA/ATAPI version + int cntl_id; char model[41]; -- 2.25.1