[PATCH] 2.4.22 drivers/cdrom/cdu31a.c

From: Mauricio Martinez
Date: Fri Nov 07 2003 - 17:12:18 EST



This patch fixes a problem (multiple reads of the same data) while reading
from a CDU31 SONY CD-ROM drive.

The hack was originally suggested by Corey Minyard a few months ago (and
working well for months in my old P5/200), but for some reason it didn't
appear in the current stable release of the kernel - Patch submitted just
for the sake of code cleanliness.

-Mauricio Martinez
mauricio@xxxxxxxxxxx
--- drivers/cdrom/cdu31a.c.orig Fri Jun 13 09:51:32 2003
+++ drivers/cdrom/cdu31a.c Wed Oct 29 23:03:10 2003
@@ -1341,7 +1341,7 @@
#endif
}

-/* read data from the drive. Note the nsect must be <= 4. */
+/* read data from the drive. Note the nblocks must be <= 4. */
static void
read_data_block(char *buffer,
unsigned int block,
@@ -1361,12 +1361,10 @@
res_reg[0] = 0;
res_reg[1] = 0;
*res_size = 0;
- /* Make sure that bytesleft doesn't exceed the buffer size */
- if (nblocks > 4) nblocks = 4;
bytesleft = nblocks * 512;
offset = 0;

- /* If the data in the read-ahead does not match the block offset,
+ /* If the data in the read ahead does not match the block offset,
then fix things up. */
if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) {
sony_next_block += block % 4;
@@ -1535,7 +1533,7 @@

/*
* The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail. Reads to a read ahead of sony_buffer_size
+ * Writes obviously fail. Reads to a read ahead of sony_buffer_size
* bytes to help speed operations. This especially helps since the OS
* uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most
* data access on a CD is done sequentially, this saves a lot of operations.
@@ -1548,6 +1546,7 @@
unsigned int res_size;
int num_retries;
unsigned long flags;
+ char *buffer;


#if DEBUG
@@ -1618,6 +1617,7 @@

block = CURRENT->sector;
nblock = CURRENT->nr_sectors;
+ buffer = CURRENT->buffer;

if (!sony_toc_read) {
printk("CDU31A: TOC not read\n");
@@ -1697,8 +1697,17 @@
}
}

- read_data_block(CURRENT->buffer, block, nblock,
- res_reg, &res_size);
+ if (nblock >= 4) {
+ read_data_block(buffer, block, 4,
+ res_reg, &res_size);
+ nblock -= 4;
+ block += 4;
+ buffer += 4 * 512;
+ } else {
+ read_data_block(buffer, block, nblock,
+ res_reg, &res_size);
+ nblock = 0;
+ }
if (res_reg[0] == 0x20) {
if (num_retries > MAX_CDU31A_RETRIES) {
end_request(0);
@@ -1717,6 +1726,10 @@
block, nblock);
}
goto try_read_again;
+/* } else if (nblock > 0) {
+ printk("Number of blocks left: %d\n", nblock);
+ end_request(1);
+*/
} else {
end_request(1);
}