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: