Subject: kern/7299: CDIOCPLAYTRACKS, etc. fail on CD players with 2 audio channels
To: None <>
From: Julian Coleman <>
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
>Originator:     Julian Coleman
Computing Service, University of Newcastle upon Tyne, UK
>Release:        1.3 -> -current
NetBSD/sparc /i386 & /atari

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 :[2].volume = arg->vol[2];[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.


Try to play an audio CD using CDIOCPLAYTRACKS and friends.


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);[LEFT_PORT].channels = p0;[RIGHT_PORT].channels = p1;
+ /*[2].channels = p2;[3].channels = p3;
+ */
	return (cd_scsibus_set_mode(cd, &data, AUDIOPAGESIZE, flags));

*** 257,264 ****
--- 259,268 ----
		return (error);
	arg->vol[LEFT_PORT] =[LEFT_PORT].volume;
	arg->vol[RIGHT_PORT] =[RIGHT_PORT].volume;
+ /*
	arg->vol[2] =[2].volume;
	arg->vol[3] =[3].volume;
+ */
	return (0);
*** 278,285 ****
--- 282,291 ----[LEFT_PORT].volume = arg->vol[LEFT_PORT];[RIGHT_PORT].channels = CHANNEL_1;[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
+ /*[2].volume = arg->vol[2];[3].volume = arg->vol[3];
+ */
	return (cd_scsibus_set_mode(cd, &data, AUDIOPAGESIZE, flags));