IDE DVD sizing problem and *suggested* fix

From: Mark W. Eichin (eichin@thok.org)
Date: Sun Jul 23 2000 - 16:30:52 EST


As of 2.4.0-test4 (and it appears to also be true in test5-pre4),
cdrom_read_toc sets the wrong capacity for DVD media, at least in
Toshiba drives. It looks like the current code ends up using
cdrom_get_last_written to calculate it from the last written audio
track. In practice (ie. on several DVD's, including Princess Bride,
The Matrix, and Sneakers) that value is too small and excludes later
chunks of the disk, leading to "attempt to access beyond end of
device" errors. It turns out that cdrom_read_capacity gives the
correct value in these cases. Without broader experience, I might
suggest that a reasonable workaround is to query *both* functions, and
use the *larger* of the two values -- but I don't know why the test is
ordered the way it is now... but it does explain why DVD I/O started
having problems between 2.3.early and 2.4.almost.

Kludge-patch with debugging printk's follows. I hope that at least
the data points help.

                        _Mark_ <eichin@thok.org>
                        The Herd Of Kittens

diff -uwrp linux/drivers/ide/ide-cd.c /usr/src/kernel-source-2.4.0t4/drivers/ide/ide-cd.c
--- linux/drivers/ide/ide-cd.c Wed Jul 5 16:47:32 2000
+++ /usr/src/kernel-source-2.4.0t4/drivers/ide/ide-cd.c Sun Jul 23 12:57:22 2000
@@ -1763,10 +1764,23 @@ static int cdrom_read_toc(ide_drive_t *d
         minor = (drive->select.b.unit) << PARTN_BITS;
         dev = MKDEV(HWIF(drive)->major, minor);
         stat = cdrom_get_last_written(dev, (long *)&toc->capacity);
+ if (stat == 0) {
+ unsigned altcap;
+ printk("cdrom_read_toc: got last written %u\n",
+ toc->capacity);
+ stat = cdrom_read_capacity(drive, &altcap, sense);
+ printk("cdrom_read_toc *alternate*: got read capacity %u\n",
+ altcap);
+ if (altcap > toc->capacity) {
+ toc->capacity = altcap;
+ printk("cdrom_read_toc: using alternate.\n");
+ }
+ }
+
         if (stat)
                 stat = cdrom_read_capacity(drive, &toc->capacity, sense);
         if (stat)
                 toc->capacity = 0x1fffff;
 
         HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS] = (toc->capacity * SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
         drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;

-
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 : Sun Jul 23 2000 - 21:00:20 EST