Subject: kern/7299: CDIOCPLAYTRACKS, etc. fail on CD players with 2 audio channels
To: None <gnats-bugs@gnats.netbsd.org>
From: Julian Coleman <j.d.coleman@ncl.ac.uk>
List: netbsd-bugs
Date: 04/01/1999 19:43:34
>Number: 7299
>Category: kern
>Synopsis: cd_scsi.c assumes four channel audio
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Apr 1 11:05:00 1999
>Last-Modified:
>Originator: Julian Coleman
>Organization:
Computing Service, University of Newcastle upon Tyne, UK
>Release: 1.3 -> -current
>Environment:
NetBSD/sparc /i386 & /atari
>Description:
The CDIOCPLAYTRACKS, etc. ioctls do not work on some CD players, or work
but generate errors of the form :
cd0(ncrscsi0:6:0): Check Condition on opcode 0x15
SENSE KEY: Illegal Request
ASC/ASCQ: Invalid Field In Parameter List
SKSV: Error in Parameters, Offset 25, bit 7
or :
cd0(aic0:6:0): Check Condition on CDB: 0x15 10 00 00 1c 00
SENSE KEY: Illegal Request
ASC/ASCQ: Invalid Field In Parameter List
The reason is that the audio commands assume that the CD player has four
channels. All of the CD players I tested have 2 channels. The error
occurs because cd_scsibus_setvol() in /usr/src/sys/dev/scsipi/cd_scsi.c
has :
data.page.audio.port[2].volume = arg->vol[2];
data.page.audio.port[3].volume = arg->vol[3];
and cd_scsibus_setvol() is called as a result of a CDIOCPLAYTRACKS ioctl.
(I see that cd_scsibus_setchan() also sets channels 2 and 3.)
Note : This probably also applies to ATAPI CD players as well, but I only
have access to SCSI ones.
>How-To-Repeat:
Try to play an audio CD using CDIOCPLAYTRACKS and friends.
>Fix:
The simple solution is just to comment out the code that refers to these
channels (see below). However, the SCSI-2 spec mentions that the number of
audio channels is returned in control bit 3 of a READ SUB-CHANNEL call on
sub-channel Q. Also, I see that struct scsi_cd_write_params_page{} in
scsi_cd.h has a reference to TRACK_MODE_4CHAN, but I don't see what this
is used for.
*** /usr/src/sys/dev/scsipi/cd_scsi.c.dist Tue Sep 1 12:10:10 1998
--- /usr/src/sys/dev/scsipi/cd_scsi.c Mon Mar 15 09:55:31 1999
***************
*** 237,244 ****
--- 237,246 ----
return (error);
data.page.audio.port[LEFT_PORT].channels = p0;
data.page.audio.port[RIGHT_PORT].channels = p1;
+ /*
data.page.audio.port[2].channels = p2;
data.page.audio.port[3].channels = p3;
+ */
return (cd_scsibus_set_mode(cd, &data, AUDIOPAGESIZE, flags));
}
***************
*** 257,264 ****
--- 259,268 ----
return (error);
arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
+ /*
arg->vol[2] = data.page.audio.port[2].volume;
arg->vol[3] = data.page.audio.port[3].volume;
+ */
return (0);
}
***************
*** 278,285 ****
--- 282,291 ----
data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
+ /*
data.page.audio.port[2].volume = arg->vol[2];
data.page.audio.port[3].volume = arg->vol[3];
+ */
return (cd_scsibus_set_mode(cd, &data, AUDIOPAGESIZE, flags));
}
>Audit-Trail:
>Unformatted: