patch-2.0.21 linux/drivers/block/ide-cd.c

Next file: linux/drivers/block/ide_modes.h
Previous file: linux/arch/i386/kernel/setup.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.20/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
@@ -106,6 +106,8 @@
  *                        <jeffml@netcom.com>
  * 3.15a July 9, 1996 -- Improved Sanyo 3 CD changer identification
  * 3.16  Jul 28, 1996 -- Fix from Gadi to reduce kernel stack usage for ioctl.
+ * 3.17  Sep 17, 1996 -- Tweak audio reads for some drives.
+ *                       Start changing CDROMLOADFROMSLOT to CDROM_SELECT_DISC.
  *
  * NOTE: Direct audio reads will only work on some types of drive.
  * So far, i've received reports of success for Sony and Toshiba drives.
@@ -132,6 +134,7 @@
 #include <linux/errno.h>
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>
+#include <linux/ucdrom.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
@@ -168,6 +171,13 @@
 #endif
 
 
+/* Size of buffer to allocate, in blocks, for audio reads. */
+
+#ifndef CDROM_NBLOCKS_BUFFER
+#define CDROM_NBLOCKS_BUFFER 8
+#endif
+
+
 /************************************************************************/
 
 #define SECTOR_SIZE 512
@@ -1918,7 +1928,7 @@
 
 
 static int
-cdrom_read_block (ide_drive_t *drive, int format, int lba,
+cdrom_read_block (ide_drive_t *drive, int format, int lba, int nblocks,
 		  char *buf, int buflen,
 		  struct atapi_request_sense *reqbuf)
 {
@@ -1944,8 +1954,13 @@
 
 	pc.c[1] = (format << 2);
 	put_unaligned(htonl(lba), (unsigned int *) &pc.c[2]);
-	pc.c[8] = 1;  /* one block */
-	pc.c[9] = 0x10;
+	pc.c[8] = (nblocks & 0xff);
+	pc.c[7] = ((nblocks>>8) & 0xff);
+	pc.c[6] = ((nblocks>>16) & 0xff);
+	if (format <= 1)
+		pc.c[9] = 0xf0;
+	else
+		pc.c[9] = 0x10;
 
 	stat = cdrom_queue_packet_command (drive, &pc);
 
@@ -1959,8 +1974,8 @@
 			"trying opcode 0xd4\n",
 			drive->name);
 		CDROM_CONFIG_FLAGS (drive)->old_readcd = 1;
-		return cdrom_read_block (drive, format, lba, buf, buflen,
-					 reqbuf);
+		return cdrom_read_block (drive, format, lba, nblocks,
+					 buf, buflen, reqbuf);
 	}
 #endif  /* not STANDARD_ATAPI */
 
@@ -2343,19 +2358,25 @@
 		if (lba < 0 || lba >= toc->capacity)
 			return -EINVAL;
 
-		buf = (char *) kmalloc (CD_FRAMESIZE_RAW, GFP_KERNEL);
+		buf = (char *) kmalloc (CDROM_NBLOCKS_BUFFER*CD_FRAMESIZE_RAW,
+					GFP_KERNEL);
 		if (buf == NULL)
 			return -ENOMEM;
 
 		while (ra.nframes > 0) {
-			stat = cdrom_read_block (drive, 1, lba, buf,
-						 CD_FRAMESIZE_RAW, NULL);
+			int this_nblocks = ra.nframes;
+			if (this_nblocks > CDROM_NBLOCKS_BUFFER)
+				this_nblocks = CDROM_NBLOCKS_BUFFER;
+			stat = cdrom_read_block
+				(drive, 1, lba, this_nblocks,
+				 buf, this_nblocks * CD_FRAMESIZE_RAW, NULL);
 			if (stat) break;
 
-			memcpy_tofs (ra.buf, buf, CD_FRAMESIZE_RAW);
-			ra.buf += CD_FRAMESIZE_RAW;
-			--ra.nframes;
-			++lba;
+			memcpy_tofs (ra.buf, buf,
+				     this_nblocks * CD_FRAMESIZE_RAW);
+			ra.buf += this_nblocks * CD_FRAMESIZE_RAW;
+			ra.nframes -= this_nblocks;
+			lba += this_nblocks;
 		}
 
 		kfree (buf);
@@ -2399,7 +2420,7 @@
 		if (buf == NULL)
 			return -ENOMEM;
 
-		stat = cdrom_read_block (drive, format, lba, buf, blocksize,
+		stat = cdrom_read_block (drive, format, lba, 1, buf, blocksize,
 					 NULL);
 		if (stat == 0)
 			memcpy_tofs ((char *)arg, buf, blocksize);
@@ -2432,7 +2453,12 @@
 		return stat;
 	}
 
-	case CDROMLOADFROMSLOT: {
+	case CDROMLOADFROMSLOT:
+		printk ("%s: Use CDROM_SELECT_DISC "
+			" instead of CDROMLOADFROMSLOT.\n", drive->name);
+		/* Fall through. */
+
+	case CDROM_SELECT_DISC: {
 		struct atapi_request_sense my_reqbuf;
 		int stat;
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov