[PATCH] cdrom stuff

From: Andries.Brouwer@cwi.nl
Date: Thu Jun 08 2000 - 19:34:48 EST


Jeff complained about dd errors while reading a CDROM,
and I also get such errors at the end, after reading all.
The reason is that the READ CD-ROM CAPACITY command is
not guaranteed to be precise, and indeed is not precise
on my hardware.
In 2.3.16 some better code was introduced, but it was
backed out again in 2.3.17 after people complained that
it yielded error messages. This better code uses the
READ DISC INFORMATION command. According to my docs,
this is a CD-R/RW only command, unavailable on an ordinary
CDROM reader. (And my hardware agrees with my docs.)

Thus, the patch below resurrects the 2.3.16 stuff, but
only on CD-R/RW. This means that dd now reads an image
correctly on CD-R/RW, but still gets EIO at the end on
a CDROM drive.

Andries

diff -u --recursive --new-file ../linux-2.3.99p9/linux/drivers/cdrom/cdrom.c ./linux/drivers/cdrom/cdrom.c
--- ../linux-2.3.99p9/linux/drivers/cdrom/cdrom.c Sat May 13 03:18:23 2000
+++ ./linux/drivers/cdrom/cdrom.c Fri Jun 9 01:47:40 2000
@@ -193,7 +193,7 @@
 
   3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
   -- Do same "read header length" trick in cdrom_get_disc_info() as
- we do in cdrom_get_track_info() -- some drive don't obbey specs and
+ we do in cdrom_get_track_info() -- some drive don't obey specs and
   fail if they can't supply the full Mt Fuji size table.
   -- Deleted stuff related to setting up write modes. It has a different
   home now.
@@ -285,7 +285,7 @@
 
 /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
    a lot of places. This macro makes the code more clear. */
-#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & type)
+#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
 
 /* used in the audio ioctls */
 #define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
@@ -2158,6 +2158,7 @@
         return cdo->generic_packet(cdi, &cgc);
 }
 
+/* requires CD R/RW */
 int cdrom_get_disc_info(kdev_t dev, disc_information *di)
 {
         struct cdrom_device_info *cdi = cdrom_find_device(dev);
@@ -2199,6 +2200,9 @@
         int ret = -1;
 
         if (!CDROM_CAN(CDC_GENERIC_PACKET))
+ goto use_toc;
+
+ if (!CDROM_CAN(CDC_CD_R | CDC_CD_RW))
                 goto use_toc;
 
         if ((ret = cdrom_get_disc_info(dev, &di)))
diff -u --recursive --new-file ../linux-2.3.99p9/linux/drivers/ide/ide-cd.c ./linux/drivers/ide/ide-cd.c
--- ../linux-2.3.99p9/linux/drivers/ide/ide-cd.c Sat May 13 03:18:24 2000
+++ ./linux/drivers/ide/ide-cd.c Fri Jun 9 02:03:14 2000
@@ -426,11 +426,13 @@
 
                         while (hi > lo) {
                                 mid = (lo + hi) / 2;
- if (packet_command_texts[mid].packet_command == failed_command->c[0]) {
+ if (packet_command_texts[mid].packet_command ==
+ failed_command->c[0]) {
                                         s = packet_command_texts[mid].text;
                                         break;
                                 }
- else if (packet_command_texts[mid].packet_command > failed_command->c[0])
+ if (packet_command_texts[mid].packet_command >
+ failed_command->c[0])
                                         hi = mid;
                                 else
                                         lo = mid+1;
@@ -1624,7 +1626,8 @@
 /* Try to read the entire TOC for the disk into our internal buffer. */
 static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
 {
- int stat, ntracks, i;
+ int minor, stat, ntracks, i;
+ kdev_t dev;
         struct cdrom_info *info = drive->driver_data;
         struct atapi_toc *toc = info->toc;
         struct {
@@ -1663,8 +1666,10 @@
 #endif /* not STANDARD_ATAPI */
 
         ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
- if (ntracks <= 0) return -EIO;
- if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
+ if (ntracks <= 0)
+ return -EIO;
+ if (ntracks > MAX_TRACKS)
+ ntracks = MAX_TRACKS;
 
         /* Now read the whole schmeer. */
         stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
@@ -1755,13 +1760,13 @@
         toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
 
         /* Now try to get the total cdrom capacity. */
-#if 0
- stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
- (long *)&toc->capacity);
+ minor = (drive->select.b.unit) << PARTN_BITS;
+ dev = MKDEV(HWIF(drive)->major, minor);
+ stat = cdrom_get_last_written(dev, (long *)&toc->capacity);
         if (stat)
-#endif
- stat = cdrom_read_capacity(drive, &toc->capacity, sense);
- if (stat) toc->capacity = 0x1fffff;
+ stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+ if (stat)
+ toc->capacity = 0x1fffff;
 
         /* Remember that we've read this stuff. */
         CDROM_STATE_FLAGS (drive)->toc_valid = 1;
@@ -2552,7 +2557,8 @@
 {
         unsigned capacity;
 
- return cdrom_read_capacity(drive, &capacity, NULL) ? 0 : capacity * SECTORS_PER_FRAME;
+ return cdrom_read_capacity(drive, &capacity, NULL)
+ ? 0 : capacity * SECTORS_PER_FRAME;
 }
 
 static

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:16 EST