Subject: kern/4267: SCSI CDROM cannot play audio CD
To: None <gnats-bugs@gnats.netbsd.org, t-nkyma@tcp-ip.or.jp>
From: None <t-nkyma@tcp-ip.or.jp>
List: netbsd-bugs
Date: 10/14/1997 00:43:52
>Number: 4267
>Category: kern
>Synopsis: SCSI CDROM cannot play audio CD
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Oct 13 08:50:03 1997
>Last-Modified:
>Originator: Takeshi Nakayama
>Organization:
Tokai Communication Platform for Inter Person
>Release: NetBSD-current [Oct 11 1997]
>Environment:
NetBSD/i386 and ncr driver
NetBSD/x68k and mmspc driver (not included in -current yet)
>Description:
The ncr driver puts the next message when I play an audio CD in the
SCSI CDROM:
cd0(ncr0:6:0): Check Condition on opcode 0x15
SENSE KEY: Illegal Request
ASC/ASCQ: Parameter List
SKSV: Error in CDB, Offset
And also, in NetBSD/x68k with the mmspc driver, causes a kernel
panic for its poor error handling.
>How-To-Repeat:
Try to use ioctls CDIOCPLAYTRACS, CDIOCSETVOL....
>Fix:
The following patch refer to cd_atapi.c solves this probrem.
*** src/sys/dev/scsipi/cd_scsi.c Fri Oct 10 21:24:29 1997
--- obj/sys/dev/scsipi/cd_scsi.c Sun Oct 12 18:51:39 1997
***************
*** 73,81 ****
#endif
void cd_scsibus_attach __P((struct device *, struct device *, void *));
int cd_scsibus_get_mode __P((struct cd_softc *,
! struct scsi_cd_mode_data *, int));
int cd_scsibus_set_mode __P((struct cd_softc *,
! struct scsi_cd_mode_data *));
struct cfattach cd_scsibus_ca = {
sizeof(struct cd_softc), cd_scsibus_match, cd_scsibus_attach
--- 73,81 ----
#endif
void cd_scsibus_attach __P((struct device *, struct device *, void *));
int cd_scsibus_get_mode __P((struct cd_softc *,
! struct scsi_cd_mode_data *, int, int));
int cd_scsibus_set_mode __P((struct cd_softc *,
! struct scsi_cd_mode_data *, int));
struct cfattach cd_scsibus_ca = {
sizeof(struct cd_softc), cd_scsibus_match, cd_scsibus_attach
***************
*** 157,166 ****
* Get the requested page into the buffer given
*/
int
! cd_scsibus_get_mode(cd, data, page)
struct cd_softc *cd;
struct scsi_cd_mode_data *data;
! int page;
{
struct scsi_mode_sense scsipi_cmd;
--- 157,166 ----
* Get the requested page into the buffer given
*/
int
! cd_scsibus_get_mode(cd, data, page, len)
struct cd_softc *cd;
struct scsi_cd_mode_data *data;
! int page, len;
{
struct scsi_mode_sense scsipi_cmd;
***************
*** 168,174 ****
bzero(data, sizeof(*data));
scsipi_cmd.opcode = SCSI_MODE_SENSE;
scsipi_cmd.page = page;
! scsipi_cmd.length = sizeof(*data) & 0xff;
return ((*cd->sc_link->scsipi_cmd)(cd->sc_link,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
(u_char *)data, sizeof(*data), CDRETRIES, 20000, NULL,
--- 168,174 ----
bzero(data, sizeof(*data));
scsipi_cmd.opcode = SCSI_MODE_SENSE;
scsipi_cmd.page = page;
! scsipi_cmd.length = len & 0xff;
return ((*cd->sc_link->scsipi_cmd)(cd->sc_link,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
(u_char *)data, sizeof(*data), CDRETRIES, 20000, NULL,
***************
*** 179,194 ****
* Get the requested page into the buffer given
*/
int
! cd_scsibus_set_mode(cd, data)
struct cd_softc *cd;
struct scsi_cd_mode_data *data;
{
struct scsi_mode_select scsipi_cmd;
bzero(&scsipi_cmd, sizeof(scsipi_cmd));
scsipi_cmd.opcode = SCSI_MODE_SELECT;
scsipi_cmd.byte2 |= SMS_PF;
! scsipi_cmd.length = sizeof(*data) & 0xff;
data->header.data_length = 0;
return ((*cd->sc_link->scsipi_cmd)(cd->sc_link,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
--- 179,195 ----
* Get the requested page into the buffer given
*/
int
! cd_scsibus_set_mode(cd, data, len)
struct cd_softc *cd;
struct scsi_cd_mode_data *data;
+ int len;
{
struct scsi_mode_select scsipi_cmd;
bzero(&scsipi_cmd, sizeof(scsipi_cmd));
scsipi_cmd.opcode = SCSI_MODE_SELECT;
scsipi_cmd.byte2 |= SMS_PF;
! scsipi_cmd.length = len & 0xff;
data->header.data_length = 0;
return ((*cd->sc_link->scsipi_cmd)(cd->sc_link,
(struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
***************
*** 203,213 ****
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE)) != 0)
return (error);
data.page.audio.flags &= ~CD_PA_SOTC;
data.page.audio.flags |= CD_PA_IMMED;
! return (cd_scsibus_set_mode(cd, &data));
}
int
--- 204,215 ----
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE,
! AUDIOPAGESIZE)) != 0)
return (error);
data.page.audio.flags &= ~CD_PA_SOTC;
data.page.audio.flags |= CD_PA_IMMED;
! return (cd_scsibus_set_mode(cd, &data, AUDIOPAGESIZE));
}
int
***************
*** 218,230 ****
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE)) != 0)
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));
}
int
--- 220,233 ----
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE,
! AUDIOPAGESIZE)) != 0)
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));
}
int
***************
*** 236,242 ****
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE)) != 0)
return (error);
arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
--- 239,246 ----
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE,
! AUDIOPAGESIZE)) != 0)
return (error);
arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
***************
*** 253,259 ****
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE)) != 0)
return (error);
data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
--- 257,264 ----
struct scsi_cd_mode_data data;
int error;
! if ((error = cd_scsibus_get_mode(cd, &data, SCSI_AUDIO_PAGE,
! AUDIOPAGESIZE)) != 0)
return (error);
data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
***************
*** 261,265 ****
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));
}
--- 266,270 ----
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));
}
*** src/sys/dev/scsipi/scsi_cd.h Fri Oct 3 20:23:41 1997
--- obj/sys/dev/scsipi/scsi_cd.h Sun Oct 12 18:51:51 1997
***************
*** 83,87 ****
struct scsi_blk_desc blk_desc;
union scsi_cd_pages page;
};
- #endif /*_SCSI_SCSI_CD_H*/
--- 83,91 ----
struct scsi_blk_desc blk_desc;
union scsi_cd_pages page;
};
+ #define AUDIOPAGESIZE \
+ (sizeof(struct scsi_mode_header) + sizeof(struct scsi_blk_desc) \
+ + sizeof(struct cd_audio_page))
+
+ #endif /*_SCSI_SCSI_CD_H*/
>Audit-Trail:
>Unformatted: