Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 May 2001 15:23:28 -0700 (PDT)
From:      bpk@Hungry.COM
To:        freebsd-hackers@freebsd.org
Cc:        sos@freebsd.dk
Subject:   Fix for ATAPI CDRW problem: MODE_SELECT_BIG - ILLEGAL REQUEST asc=1a
Message-ID:  <200105242223.f4OMNSm16593@starvation.hungry.com>

next in thread | raw e-mail | index | archive | help

I recently acquired a new Yamaha 2100E ATAPI CDRW drive, and encountered
this error during the fixation stage with burncd on a FreeBSD 4.3 release
system:

burncd: ioctl(CDRIOCCLOSEDISK): Input/output error

and the kernel complains:

acd0: MODE_SELECT_BIG - ILLEGAL REQUEST asc=1a ascq=00 error=00

After perusing the ATA/ATAPI-5 and MMC-3 specifications I realized that the
asc=1a error (PARAMETER LENGTH LIST ERROR) was telling me that the CDRW
drive wasn't happy with the length of the CLOSE DISK mode page that was
being sent to it.

In atapi-cd.c the acd_close_disk() function is sending the write_param
mode page structure in the CLOSE DISK command to the drive.

Upon examination of struct write_param in atapi-cd.h I noticed sure enough
the last four bytes of the page were commented out:
/*
    u_int8_t    vendor_specific_byte0;
    u_int8_t    vendor_specific_byte1;
    u_int8_t    vendor_specific_byte2;
    u_int8_t    vendor_specific_byte3;
*/

I uncommented these lines, recompiled/rebooted, and tried burncd again. 
This time it failed right away on the CDRIOCOPENDISK ioctl, with the kernel
error being something about an invalid parameter.

So I reverted struct write_param back to the original commented version. 
But I copied write_param to a new struct called full_write_param and
uncommented the last 4 bytes.  I then changed acd_close_disk() to use the
full_write_param struct rather than the original write_param struct.

Recompiled/rebooted.

The result: success!

The Yamaha 2100E doesn't want the last 4 bytes in the mode page for OPEN
DISK but does for CLOSE DISK.

Here's a cvs diff off the FreeBSD 4.3 release files:

Index: atapi-cd.h
===================================================================
RCS file: /d1/FreeBSD/FreeBSD_CVS/src/sys/dev/ata/atapi-cd.h,v
retrieving revision 1.15.2.6
diff -r1.15.2.6 atapi-cd.h
269a270,338
> /* 
>   CDROM Write Parameters Mode Page (Burners ONLY) 
>   Contains the last 4 vendor specific bytes.
> */
> struct full_write_param {
>     /* mode page data header */
>     u_int16_t	data_length;
>     u_int8_t	medium_type;
>     u_int8_t	dev_spec;
>     u_int8_t	unused[2];
>     u_int16_t	blk_desc_len;
> 
>     /* write parameters page */
>     u_int8_t	page_code;
> #define ATAPI_CDROM_WRITE_PARAMETERS_PAGE      0x05
> 
>     u_int8_t	page_length;		/* 0x32 */
>     u_int8_t	write_type	:4;	/* write stream type */
> #define CDR_WTYPE_PACKET	0x00
> #define CDR_WTYPE_TRACK		0x01
> #define CDR_WTYPE_SESSION	0x02
> #define CDR_WTYPE_RAW		0x03
> 
>     u_int8_t	test_write	:1;	/* test write enable */
>     u_int8_t	reserved2_5	:1;
>     u_int8_t	burnproof	:1;	/* BurnProof enable */
>     u_int8_t	reserved2_7	:1;
>     u_int8_t	track_mode	:4;	/* track mode */
> #define CDR_TMODE_AUDIO		0x00
> #define CDR_TMODE_AUDIO_PREEMP	0x01
> #define CDR_TMODE_ALLOW_COPY	0x02
> #define CDR_TMODE_DATA		0x04
> #define CDR_TMODE_QUAD_AUDIO	0x08
> 
>     u_int8_t	copy		:1;	/* generation stamp */
>     u_int8_t	fp		:1;	/* fixed packet type */
>     u_int8_t	session_type	:2;	/* session type */
> #define CDR_SESS_NONE		0x00
> #define CDR_SESS_FINAL		0x01
> #define CDR_SESS_RESERVED	0x02
> #define CDR_SESS_MULTI		0x03
> 
>     u_int8_t	datablock_type	:4;	/* data type code (see cdrio.h) */
>     u_int8_t	reserved4_4567	:4;
>     u_int8_t	reserved5;
>     u_int8_t	reserved6;
>     u_int8_t	host_app_code	:6;	/* host application code */
>     u_int8_t	reserved7_67	:2;
>     u_int8_t	session_format;		/* session format */
> #define CDR_SESS_CDROM		0x00
> #define CDR_SESS_CDI		0x10
> #define CDR_SESS_CDROM_XA	0x20
> 
>     u_int8_t	reserved9;
>     u_int32_t	packet_size;		/* packet size in bytes */
>     u_int16_t	audio_pause_length;	/* audio pause length in secs */
>     u_int8_t	media_catalog_number[16];
>     u_int8_t	isr_code[16];
>     u_int8_t	sub_hdr_byte0;
>     u_int8_t	sub_hdr_byte1;
>     u_int8_t	sub_hdr_byte2;
>     u_int8_t	sub_hdr_byte3;
> 
>     u_int8_t	vendor_specific_byte0;
>     u_int8_t	vendor_specific_byte1;
>     u_int8_t	vendor_specific_byte2;
>     u_int8_t	vendor_specific_byte3;
> } __attribute__((packed));
> 
Index: atapi-cd.c
===================================================================
RCS file: /d1/FreeBSD/FreeBSD_CVS/src/sys/dev/ata/atapi-cd.c,v
retrieving revision 1.48.2.10
diff -r1.48.2.10 atapi-cd.c
1371c1371
<     struct write_param param;
---
>     struct full_write_param param;


-- 
Brian Koehmstedt
bpk@hungry.com

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105242223.f4OMNSm16593>