linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tobias Diedrich <ranma@gmx.at>
To: Jens Axboe <axboe@suse.de>
Cc: linux-kernel@vger.kernel.org
Subject: Re: cdrom blocksize reset bug with 2.4.x kernels
Date: Sun, 9 Nov 2003 15:56:51 +0100	[thread overview]
Message-ID: <20031109145651.GA1203@melchior.yamamaya.is-a-geek.org> (raw)
In-Reply-To: <20030702111835.GC839@suse.de>

As it seems Attila did not write a follow up, I had a look at his patch
and the problem.  The following patch fixes it for me (Plextor PX-32TS).

Please CC me on replies, I am not subscribed to the list.

--- linux-2.4.22/include/linux/cdrom.h	2003-10-28 01:30:34.000000000 +0100
+++ linux/include/linux/cdrom.h	2003-11-09 15:44:20.000000000 +0100
@@ -743,7 +743,8 @@
     	char name[20];                  /* name of the device type */
 /* per-device flags */
         __u8 sanyo_slot		: 2;	/* Sanyo 3 CD changer support */
-        __u8 reserved		: 6;	/* not used yet */
+        __u8 use_read10	: 1;		/* Use READ10 instead of READCD */
+        __u8 reserved		: 5;	/* not used yet */
 	struct cdrom_write_settings write;
 };
 
--- linux-2.4.22/drivers/cdrom/cdrom.c	2003-11-07 23:46:49.000000000 +0100
+++ linux/drivers/cdrom/cdrom.c	2003-11-09 15:52:14.000000000 +0100
@@ -1400,6 +1400,8 @@
 	return 0;
 }
 
+static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size);
+
 /*
  * Specific READ_10 interface
  */
@@ -1408,6 +1410,7 @@
 			 int blocksize, int nblocks)
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
+	int ret = 0;
 
 	memset(&cgc->cmd, 0, sizeof(cgc->cmd));
 	cgc->cmd[0] = GPCMD_READ_10;
@@ -1419,7 +1422,22 @@
 	cgc->cmd[7] = (nblocks >>  8) & 0xff;
 	cgc->cmd[8] = nblocks & 0xff;
 	cgc->buflen = blocksize * nblocks;
-	return cdo->generic_packet(cdi, cgc);
+
+	if (blocksize != CD_FRAMESIZE) {
+		ret = cdrom_switch_blocksize(cdi, blocksize);
+		ret |= cdo->generic_packet(cdi, cgc);
+		ret |= cdrom_switch_blocksize(cdi, CD_FRAMESIZE);
+	} else ret = cdo->generic_packet(cdi, cgc);
+
+	/*
+	 * Switch cdrom_read_block back to default behaviour
+	 * if we get an error.
+	 * FIXME: Maybe this should not be done on all errors.
+	 */
+	if (ret != 0)
+		cdi->use_read10 = 0;
+
+	return ret;
 }
 
 /* very generic interface for reading the various types of blocks */
@@ -1428,8 +1446,15 @@
 			    int lba, int nblocks, int format, int blksize)
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
+	int ret;
+
+	if (cdi->use_read10)
+		return cdrom_read_cd(cdi, cgc, lba, blksize, nblocks);
 
 	memset(&cgc->cmd, 0, sizeof(cgc->cmd));
+	/*
+	 * SCSI-II devices are not required to support READ_CD.
+	 */
 	cgc->cmd[0] = GPCMD_READ_CD;
 	/* expected sector size - cdda,mode1,etc. */
 	cgc->cmd[1] = format << 2;
@@ -1452,7 +1477,15 @@
 	default			: cgc->cmd[9] = 0x10;
 	}
 	
-	return cdo->generic_packet(cdi, cgc);
+	ret = cdo->generic_packet(cdi, cgc);
+	if (ret && cgc->sense && cgc->sense->sense_key==0x05 && cgc->sense->asc==0x20 && cgc->sense->ascq==0x00) {
+		ret = cdrom_read_cd(cdi, cgc, lba, blksize, nblocks);
+		if (ret == 0) {
+			cdi->use_read10 = 1;
+			printk(KERN_INFO "cdrom.c: drive does not like READ_CD for blksize=%d, switching to READ_10.\n", blksize);
+		}
+	}
+	return ret;
 }
 
 /* Just about every imaginable ioctl is supported in the Uniform layer
@@ -1956,20 +1989,6 @@
 		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {
-			/*
-			 * SCSI-II devices are not required to support
-			 * READ_CD, so let's try switching block size
-			 */
-			/* FIXME: switch back again... */
-			if ((ret = cdrom_switch_blocksize(cdi, blocksize))) {
-				kfree(cgc.buffer);
-				return ret;
-			}
-			cgc.sense = NULL;
-			ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1);
-			ret |= cdrom_switch_blocksize(cdi, blocksize);
-		}
 		if (!ret && copy_to_user((char *)arg, cgc.buffer, blocksize))
 			ret = -EFAULT;
 		kfree(cgc.buffer);

-- 
Tobias						PGP: http://9ac7e0bc.2ya.com

  reply	other threads:[~2003-11-09 14:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-01 22:25 cdrom blocksize reset bug with 2.4.x kernels Attila Kinali
2003-07-02 11:18 ` Jens Axboe
2003-11-09 14:56   ` Tobias Diedrich [this message]
2003-11-12 16:06     ` Tobias Diedrich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031109145651.GA1203@melchior.yamamaya.is-a-geek.org \
    --to=ranma@gmx.at \
    --cc=axboe@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).