-static void
-setup_translation(int driveid)
-{
- u8 translation = get_translation(driveid);
- SET_GLOBAL(ATA.devices[driveid].translation, translation);
-
- u8 channel = driveid / 2;
- u8 slave = driveid % 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);
- u64 sectors = GET_GLOBAL(ATA.devices[driveid].sectors);
-
- dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation="
- , channel, slave, cylinders, heads, spt);
- switch (translation) {
- case ATA_TRANSLATION_NONE:
- dprintf(1, "none");
- break;
- case ATA_TRANSLATION_LBA:
- dprintf(1, "lba");
- spt = 63;
- if (sectors > 63*255*1024) {
- heads = 255;
- cylinders = 1024;
- break;
- }
- u32 sect = (u32)sectors / 63;
- heads = sect / 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 = sect / heads;
- break;
- case ATA_TRANSLATION_RECHS:
- dprintf(1, "r-echs");
- // Take care not to overflow
- if (heads==16) {
- if (cylinders>61439)
- cylinders=61439;
- heads=15;
- cylinders = (u16)((u32)(cylinders)*16/15);
- }
- // then go through the large bitshift process
- case ATA_TRANSLATION_LARGE:
- if (translation == ATA_TRANSLATION_LARGE)
- dprintf(1, "large");
- while (cylinders > 1024) {
- cylinders >>= 1;
- heads <<= 1;
-
- // If we max out the head count
- if (heads > 127)
- break;
- }
- break;
+// Detect if the given drive is an atapi - initialize it if so.
+static struct atadrive_s *
+init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
+{
+ // Send an IDENTIFY_DEVICE_PACKET command to device
+ int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_PACKET_DEVICE);
+ if (ret)
+ return NULL;
+
+ // Success - setup as ATAPI.
+ struct atadrive_s *adrive_g = init_atadrive(dummy, buffer);
+ if (!adrive_g)
+ return NULL;
+ adrive_g->drive.type = DTYPE_ATAPI;
+ adrive_g->drive.blksize = CDROM_SECTOR_SIZE;
+ adrive_g->drive.sectors = (u64)-1;
+ u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
+ char model[MAXMODEL+1];
+ char *desc = znprintf(MAXDESCSIZE
+ , "DVD/CD [ata%d-%d: %s ATAPI-%d %s]"
+ , adrive_g->chan_gf->chanid, adrive_g->slave
+ , ata_extract_model(model, MAXMODEL, buffer)
+ , ata_extract_version(buffer)
+ , (iscd ? "DVD/CD" : "Device"));
+ dprintf(1, "%s\n", desc);
+
+ // fill cdidmap
+ if (iscd) {
+ int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_tmp,
+ adrive_g->chan_gf->chanid,
+ adrive_g->slave);
+ boot_add_cd(&adrive_g->drive, desc, prio);