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
[EMAIL PROTECTED]

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to