patch-2.2.18 linux/drivers/block/ide-cd.c
Next file: linux/drivers/block/ide-dma.c
Previous file: linux/drivers/block/ida_ioctl.h
Back to the patch index
Back to the overall index
- Lines: 218
- Date:
Sat Nov 18 19:12:22 2000
- Orig file:
v2.2.17/drivers/block/ide-cd.c
- Orig date:
Sat Sep 9 18:42:34 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
@@ -210,17 +210,17 @@
* patch thanks to "Eddie C. Dost" <ecd@skynet.be>
*
* 4.50 Oct 19, 1998 -- New maintainers!
- * Jens Axboe <axboe@image.dk>
+ * Jens Axboe <axboe@suse.de>
* Chris Zwilling <chris@cloudnet.com>
*
- * 4.51 Dec 23, 1998 -- Jens Axboe <axboe@image.dk>
+ * 4.51 Dec 23, 1998 -- Jens Axboe <axboe@suse.de>
* - ide_cdrom_reset enabled since the ide subsystem
- * handles resets fine now. <axboe@image.dk>
+ * handles resets fine now. <axboe@suse.de>
* - Transfer size fix for Samsung CD-ROMs, thanks to
* "Ville Hallik" <ville.hallik@mail.ee>.
* - other minor stuff.
*
- * 4.52 Jan 19, 1999 -- Jens Axboe <axboe@image.dk>
+ * 4.52 Jan 19, 1999 -- Jens Axboe <axboe@suse.de>
* - Detect DVD-ROM/RAM drives
*
* 4.53 Feb 22, 1999 - Include other model Samsung and one Goldstar
@@ -324,41 +324,50 @@
info->nsectors_buffered = 0;
}
+static int cdrom_log_sense(ide_drive_t *drive, struct packet_command *pc,
+ struct request_sense *sense)
+{
+ int log = 0;
+
+ if (sense == NULL)
+ return 0;
+
+ switch (sense->sense_key) {
+ case NO_SENSE: case RECOVERED_ERROR:
+ break;
+ case NOT_READY:
+ /*
+ * don't care about tray state messages for
+ * e.g. capacity commands or in-progress or
+ * becoming ready
+ */
+ if (sense->asc == 0x3a || sense->asc == 0x04)
+ break;
+ log = 1;
+ break;
+ case UNIT_ATTENTION:
+ /*
+ * Make good and sure we've seen this potential media
+ * change. Some drives (i.e. Creative) fail to present
+ * the correct sense key in the error register.
+ */
+ cdrom_saw_media_change(drive);
+ break;
+ default:
+ log = 1;
+ break;
+ }
+ return log;
+}
static
void cdrom_analyze_sense_data(ide_drive_t *drive,
struct packet_command *failed_command,
struct request_sense *sense)
{
- if (sense->sense_key == NOT_READY ||
- sense->sense_key == UNIT_ATTENTION) {
- /* Make good and sure we've seen this potential media change.
- Some drives (i.e. Creative) fail to present the correct
- sense key in the error register. */
- cdrom_saw_media_change (drive);
-
-
- /* Don't print not ready or unit attention errors for
- READ_SUBCHANNEL. Workman (and probably other programs)
- uses this command to poll the drive, and we don't want
- to fill the syslog with useless errors. */
- if (failed_command &&
- (failed_command->c[0] == GPCMD_READ_SUBCHANNEL ||
- failed_command->c[0] == GPCMD_TEST_UNIT_READY))
- return;
- }
-
- if (sense->error_code == 0x70 && sense->sense_key == 0x02
- && ((sense->asc == 0x3a && sense->ascq == 0x00) ||
- (sense->asc == 0x04 && sense->ascq == 0x01)))
- {
- /*
- * Suppress the following errors:
- * "Medium not present", "in progress of becoming ready",
- * and "writing" to keep the noise level down to a dull roar.
- */
+
+ if (!cdrom_log_sense(drive, failed_command, sense))
return;
- }
#if VERBOSE_IDE_CD_ERRORS
{
@@ -1105,7 +1114,13 @@
if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) {
if (--retry == 0) {
+ /*
+ * this condition is far too common, to bother
+ * users about it
+ */
+#if 0
printk("%s: disabled DSC seek overlap\n", drive->name);
+#endif
drive->dsc_overlap = 0;
}
}
@@ -1329,8 +1344,12 @@
static
void cdrom_sleep (int time)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(time);
+ int sleep = time;
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+ sleep = schedule_timeout(sleep);
+ } while (sleep);
}
static
@@ -1827,6 +1846,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_MSF;
+ lba_to_msf(lba_start, &pc.c[3], &pc.c[4], &pc.c[5]);
+ lba_to_msf(lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]);
+
+ return cdrom_queue_packet_command(drive, &pc);
+}
static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
struct atapi_toc_entry **ent)
@@ -1835,6 +1868,9 @@
struct atapi_toc *toc = info->toc;
int ntracks;
+ if (!CDROM_STATE_FLAGS(drive)->toc_valid)
+ return -EINVAL;
+
/* Check validity of requested track number. */
ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0;
@@ -1930,10 +1966,38 @@
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
struct cdrom_info *info = drive->driver_data;
+ int stat;
switch (cmd) {
+ /*
+ * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_MSF, since
+ * atapi doesn't support it
+ */
+ case CDROMPLAYTRKIND: {
+ int 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;
struct atapi_toc *toc;
@@ -1949,7 +2013,6 @@
}
case CDROMREADTOCENTRY: {
- int stat;
struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg;
struct atapi_toc_entry *toce;
@@ -2275,7 +2338,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
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)