-static void
-report_model(int driveid, u8 *buffer)
-{
- u8 model[41];
-
- // Read model name
- int i;
- for (i=0; i<40; i+=2) {
- model[i] = buffer[i+54+1];
- model[i+1] = buffer[i+54];
- }
-
- // Reformat
- model[40] = 0x00;
- for (i=39; i>0; i--) {
- if (model[i] != 0x20)
- break;
- model[i] = 0x00;
- }
-
- u8 channel = driveid / 2;
- u8 slave = driveid % 2;
- // XXX - model on stack not %cs
- printf("ata%d %s: %s", channel, slave ? " slave" : "master", model);
-}
-
-static u8
-get_ata_version(u8 *buffer)
-{
- u16 ataversion = *(u16*)&buffer[160];
- u8 version;
- for (version=15; version>0; version--)
- if (ataversion & (1<<version))
- break;
- return version;
-}
-
-static void
-init_drive_atapi(int driveid)
-{
- SET_EBDA(ata.devices[driveid].type, ATA_TYPE_ATAPI);
-
- // Temporary values to do the transfer
- SET_EBDA(ata.devices[driveid].device,ATA_DEVICE_CDROM);
- SET_EBDA(ata.devices[driveid].mode, ATA_MODE_PIO16);
-
- // Now we send a IDENTIFY command to ATAPI device
- u8 buffer[0x0200];
- memset(buffer, 0, sizeof(buffer));
- u16 ret = ata_cmd_data(driveid, ATA_CMD_IDENTIFY_DEVICE_PACKET
- , 1, 1
- , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
- if (ret != 0)
- BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
-
- u8 type = buffer[1] & 0x1f;
- u8 removable = (buffer[0] & 0x80) ? 1 : 0;
- u8 mode = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
- u16 blksize = CDROM_SECTOR_SIZE;
-
- SET_EBDA(ata.devices[driveid].device, type);
- SET_EBDA(ata.devices[driveid].removable, removable);
- SET_EBDA(ata.devices[driveid].mode, mode);
- SET_EBDA(ata.devices[driveid].blksize, blksize);
-
- // fill cdidmap
- u8 cdcount = GET_EBDA(ata.cdcount);
- SET_EBDA(ata.idmap[1][cdcount], driveid);
- SET_EBDA(ata.cdcount, ++cdcount);
-
- report_model(driveid, buffer);
- u8 version = get_ata_version(buffer);
- if (GET_EBDA(ata.devices[driveid].device)==ATA_DEVICE_CDROM)
- printf(" ATAPI-%d CD-Rom/DVD-Rom\n", version);
- else
- printf(" ATAPI-%d Device\n", version);
-}
-
-static void
-fill_fdpt(int driveid)
-{
- if (driveid > 1)
- return;
-
- u16 nlc = GET_EBDA(ata.devices[driveid].lchs.cylinders);
- u16 nlh = GET_EBDA(ata.devices[driveid].lchs.heads);
- u16 nlspt = GET_EBDA(ata.devices[driveid].lchs.spt);
-
- u16 npc = GET_EBDA(ata.devices[driveid].pchs.cylinders);
- u16 nph = GET_EBDA(ata.devices[driveid].pchs.heads);
- u16 npspt = GET_EBDA(ata.devices[driveid].pchs.spt);
-
- SET_EBDA(fdpt[driveid].precompensation, 0xffff);
- SET_EBDA(fdpt[driveid].drive_control_byte, 0xc0 | ((nph > 8) << 3));
- SET_EBDA(fdpt[driveid].landing_zone, npc);
- SET_EBDA(fdpt[driveid].cylinders, nlc);
- SET_EBDA(fdpt[driveid].heads, nlh);
- SET_EBDA(fdpt[driveid].sectors, nlspt);
-
- if (nlc == npc && nlh == nph && nlspt == npspt)
- // no logical CHS mapping used, just physical CHS
- // use Standard Fixed Disk Parameter Table (FDPT)
- return;
-
- // complies with Phoenix style Translated Fixed Disk Parameter
- // Table (FDPT)
- SET_EBDA(fdpt[driveid].phys_cylinders, npc);
- SET_EBDA(fdpt[driveid].phys_heads, nph);
- SET_EBDA(fdpt[driveid].phys_sectors, npspt);
- SET_EBDA(fdpt[driveid].a0h_signature, 0xa0);
-
- // Checksum structure.
- u8 *p = MAKE_FARPTR(SEG_EBDA, offsetof(struct extended_bios_data_area_s
- , fdpt[driveid]));
- u8 sum = checksum(p, FIELD_SIZEOF(struct extended_bios_data_area_s
- , fdpt[driveid]) - 1);
- SET_EBDA(fdpt[driveid].checksum, -sum);
-}
-