- // Now we send a IDENTIFY command to ATA device
- u8 buffer[0x0200];
- memset(buffer, 0, sizeof(buffer));
- u16 ret = ata_cmd_data(driveid, ATA_CMD_IDENTIFY_DEVICE
- , 1, 1
- , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
- if (ret)
- BX_PANIC("ata-detect: Failed to detect ATA device\n");
-
- u8 removable = (buffer[0] & 0x80) ? 1 : 0;
- u8 mode = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
- u16 blksize = *(u16*)&buffer[10];
-
- u16 cylinders = *(u16*)&buffer[1*2]; // word 1
- u16 heads = *(u16*)&buffer[3*2]; // word 3
- u16 spt = *(u16*)&buffer[6*2]; // word 6
-
- u32 sectors = *(u32*)&buffer[60*2]; // word 60 and word 61
-
- SET_EBDA(ata.devices[driveid].device,ATA_DEVICE_HD);
- SET_EBDA(ata.devices[driveid].removable, removable);
- SET_EBDA(ata.devices[driveid].mode, mode);
- SET_EBDA(ata.devices[driveid].blksize, blksize);
- SET_EBDA(ata.devices[driveid].pchs.heads, heads);
- SET_EBDA(ata.devices[driveid].pchs.cylinders, cylinders);
- SET_EBDA(ata.devices[driveid].pchs.spt, spt);
- SET_EBDA(ata.devices[driveid].sectors, sectors);
-
- u8 channel = driveid / 2;
- u8 slave = driveid % 2;
- u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2);
- u8 shift;
- for (shift=driveid%4; shift>0; shift--)
- translation >>= 2;
- translation &= 0x03;
-
- SET_EBDA(ata.devices[driveid].translation, translation);
-
- BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation="
- , channel, slave, cylinders, heads, spt);
- switch (translation) {
- case ATA_TRANSLATION_NONE:
- BX_INFO("none");
- break;
- case ATA_TRANSLATION_LBA:
- BX_INFO("lba");
- spt = 63;
- sectors /= 63;
- heads = sectors / 1024;
- if (heads>128)
- heads = 255;
- else if (heads>64)
- heads = 128;
- else if (heads>32)
- heads = 64;
- else if (heads>16)
- heads = 32;
- else
- heads = 16;
- cylinders = sectors / heads;
- break;
- case ATA_TRANSLATION_RECHS:
- BX_INFO("r-echs");
- // Take care not to overflow
- if (heads==16) {
- if (cylinders>61439)
- cylinders=61439;
- heads=15;
- cylinders = (u16)((u32)(cylinders)*16/15);