diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.2.18-pre7/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- /opt/kernel/linux-2.2.18-pre7/drivers/block/ide-cd.c Fri Sep 1 02:21:42 2000 +++ linux/drivers/block/ide-cd.c Fri Sep 15 03:50:27 2000 @@ -1827,6 +1827,20 @@ return cdrom_queue_packet_command(drive, &pc); } +static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) +{ + struct request_sense sense; + struct packet_command pc; + + memset(&pc, 0, sizeof (pc)); + pc.sense = &sense; + + pc.c[0] = GPCMD_PLAY_AUDIO_10; + put_unaligned(cpu_to_be32(lba_start), (unsigned int *) &pc.c[2]); + put_unaligned(cpu_to_be16(lba_end - lba_start), (unsigned int *) &pc.c[7]); + + return cdrom_queue_packet_command(drive, &pc); +} static int cdrom_get_toc_entry(ide_drive_t *drive, int track, struct atapi_toc_entry **ent) @@ -1932,6 +1946,34 @@ struct cdrom_info *info = drive->driver_data; switch (cmd) { + /* + * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since + * atapi doesn't support it + */ + case CDROMPLAYTRKIND: { + int stat, lba_start, lba_end; + struct cdrom_ti *ti = (struct cdrom_ti *)arg; + struct atapi_toc_entry *first_toc, *last_toc; + + stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc); + if (stat) + return stat; + + stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, &last_toc); + if (stat) + return stat; + + if (ti->cdti_trk1 != CDROM_LEADOUT) + ++last_toc; + lba_start = first_toc->addr.lba; + lba_end = last_toc->addr.lba; + + if (lba_end <= lba_start) + return -EINVAL; + + return cdrom_play_audio(drive, lba_start, lba_end); + } + case CDROMREADTOCHDR: { int stat; struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg; @@ -2275,7 +2317,7 @@ CDROM_CONFIG_FLAGS (drive)->dvd_ram = 1; if (cap.audio_play) CDROM_CONFIG_FLAGS (drive)->audio_play = 1; - if (cap.mechtype == 0) + if (cap.mechtype == mechtype_caddy || cap.mechtype == mechtype_popup) CDROM_CONFIG_FLAGS (drive)->close_tray = 0; #if ! STANDARD_ATAPI diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.2.18-pre7/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- /opt/kernel/linux-2.2.18-pre7/drivers/cdrom/cdrom.c Fri Sep 1 02:21:42 2000 +++ linux/drivers/cdrom/cdrom.c Fri Sep 15 03:50:27 2000 @@ -1604,7 +1604,7 @@ return -EDRIVE_CANT_DO_THIS; keeplocked = arg ? 1 : 0; /* don't unlock the door on multiple opens */ - if ((cdi->use_count != 1) && !arg) + if ((cdi->use_count != 1) && !arg && !capable(CAP_SYS_ADMIN)) return -EBUSY; return cdo->lock_door(cdi, arg); } @@ -1965,19 +1965,6 @@ IOCTL_OUT(arg, struct cdrom_subchnl, q); /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ return 0; - } - case CDROMPLAYTRKIND: { - struct cdrom_ti ti; - - cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n"); - IOCTL_IN(arg, struct cdrom_ti, ti); - - cgc.cmd[0] = GPCMD_PLAY_AUDIO_TI; - cgc.cmd[4] = ti.cdti_trk0; - cgc.cmd[5] = ti.cdti_ind0; - cgc.cmd[7] = ti.cdti_trk1; - cgc.cmd[8] = ti.cdti_ind1; - return cdo->generic_packet(cdi, &cgc); } case CDROMPLAYMSF: { struct cdrom_msf msf; diff -ur --exclude-from /home/axboe/cdrom/exclude /opt/kernel/linux-2.2.18-pre7/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c --- /opt/kernel/linux-2.2.18-pre7/drivers/scsi/sr_ioctl.c Fri Sep 1 02:21:43 2000 +++ linux/drivers/scsi/sr_ioctl.c Fri Sep 15 03:50:27 2000 @@ -314,6 +314,8 @@ u_char sr_cmd[10]; int result, target = MINOR(cdi->dev); unsigned char buffer[32]; + + memset(sr_cmd, 0, sizeof(sr_cmd)); switch (cmd) { @@ -324,10 +326,7 @@ sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP; sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5); sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0; - sr_cmd[6] = 0; - sr_cmd[7] = 0; /* MSB of length (12) */ sr_cmd[8] = 12; /* LSB of length */ - sr_cmd[9] = 0; result = sr_do_ioctl(target, sr_cmd, buffer, 12, 1); @@ -346,9 +345,7 @@ (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0); sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0; sr_cmd[6] = tocentry->cdte_track; - sr_cmd[7] = 0; /* MSB of length (12) */ sr_cmd[8] = 12; /* LSB of length */ - sr_cmd[9] = 0; result = sr_do_ioctl (target, sr_cmd, buffer, 12, 0); @@ -373,9 +370,7 @@ sr_cmd[0] = MODE_SENSE; sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5; sr_cmd[2] = 0xe; /* Want mode page 0xe, CDROM audio params */ - sr_cmd[3] = 0; sr_cmd[4] = 28; - sr_cmd[5] = 0; if ((buffer = (unsigned char *) scsi_malloc(512)) == NULL) return -ENOMEM; @@ -436,9 +431,7 @@ sr_cmd[0] = MODE_SENSE; sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5; sr_cmd[2] = 0xe; /* Want mode page 0xe, CDROM audio params */ - sr_cmd[3] = 0; sr_cmd[4] = 28; - sr_cmd[5] = 0; if ((buffer = (unsigned char *) scsi_malloc(512)) == NULL) return -ENOMEM; @@ -455,6 +448,20 @@ volctrl->channel3 = buffer[27]; scsi_free(buffer, 512); + break; + } + + case CDROMPLAYTRKIND: { + struct cdrom_ti* ti = (struct cdrom_ti*)arg; + + sr_cmd[0] = GPCMD_PLAYAUDIO_TI; + sr_cmd[1] = scsi_CDs[target].device->lun << 5; + sr_cmd[4] = ti->cdti_trk0; + sr_cmd[5] = ti->cdti_ind0; + sr_cmd[7] = ti->cdti_trk1; + sr_cmd[8] = ti->cdti_ind1; + + result = sr_do_ioctl(target, sr_cmd, NULL, 255, 0); break; }