lkml.org 
[lkml]   [2003]   [Nov]   [7]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateFri, 7 Nov 2003 09:38:36 -0500 (EST)
FromMauricio Martinez <>
Subject[PATCH] 2.4.22 drivers/cdrom/cdu31a.c
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@coe.neu.edu
--- 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);
 			}
\
 
 \ /
  Last update: 2005-03-22 13:58    [from the cache]
©2003-2008