Subject: Re: kern/30288: eject and raw SCSI access to a CDROM drive don't work when the medium is bad
To: None <gnats-bugs@NetBSD.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: netbsd-bugs
Date: 05/20/2005 13:31:49
--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, May 20, 2005 at 11:03:00AM +0000, Pavel Cahyna wrote:
> >Description:
> 
> 
> When there is an unreadable CD-RW medium in my SCSI CD drive, even the tools
> that don't access the medium don't work.  For example scsictl:
> $ scsictl cd1 identify                                        
> scsictl: cd1: Device not configured
> 
> or eject:
> $ eject cd1
> eject: open: /dev/rcd1d: Device not configured
> 
> When I attempt to do this, the kernel prints:
> cd1(ahc1:0:5:0):  Check Condition on CDB: 0x25 00 00 00 00 00 00 00 00 00
>     SENSE KEY:  Not Ready
>      ASC/ASCQ:  Cannot Read Medium - Incompatible Format
> 
> When there is a good medium, scsictl works normally:
> $ scsictl cd1 identify 
> /dev/rcd1d: scsibus0 target 5 lun 0 <YAMAHA, CRW6416S, 1.0c>
> 
> eject too.
> [...]
> >Fix:
> 
> 
> Unknown. Somehow always allow to access the raw device? 

Yes, this is how it should work. Can you try the (untested) patch attached ?

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--

--6TrnltStXW4iwmi0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: cd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/cd.c,v
retrieving revision 1.222
diff -u -r1.222 cd.c
--- cd.c	25 Apr 2005 17:52:30 -0000	1.222
+++ cd.c	20 May 2005 11:29:47 -0000
@@ -348,6 +348,7 @@
 	struct scsipi_adapter *adapt;
 	int unit, part;
 	int error;
+	int rawpart;
 
 	unit = CDUNIT(dev);
 	if (unit >= cd_cd.cd_ndevs)
@@ -375,20 +376,21 @@
 	if ((error = lockmgr(&cd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
 		goto bad4;
 
+	rawpart = (part == RAW_PART && fmt == S_IFCHR);
 	if ((periph->periph_flags & PERIPH_OPEN) != 0) {
 		/*
 		 * If any partition is open, but the disk has been invalidated,
 		 * disallow further opens.
 		 */
 		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0 &&
-			(part != RAW_PART || fmt != S_IFCHR )) {
+			!rawpart) {
 			error = EIO;
 			goto bad3;
 		}
 	} else {
 		int silent;
 
-		if (part == RAW_PART && fmt == S_IFCHR)
+		if (rawpart)
 			silent = XS_CTL_SILENT;
 		else
 			silent = 0;
@@ -420,7 +422,7 @@
 			}
 		}
 		if (error) {
-			if (silent)
+			if (rawpart)
 				goto out;
 			goto bad3;
 		}
@@ -432,17 +434,21 @@
 		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE);
 		SC_DEBUG(periph, SCSIPI_DB1,
 		    ("cdopen: scsipi_prevent, error=%d\n", error));
-		if (error)
+		if (error) {
+			if (rawpart)
+				goto out;
 			goto bad;
+		}
 
 		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
-			periph->periph_flags |= PERIPH_MEDIA_LOADED;
-
 			/* Load the physical device parameters. */
 			if (cd_get_parms(cd, 0) != 0) {
+				if (rawpart)
+					goto out;
 				error = ENXIO;
-				goto bad2;
+				goto bad;
 			}
+			periph->periph_flags |= PERIPH_MEDIA_LOADED;
 			SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
 
 			/* Fabricate a disk label. */
@@ -475,7 +481,6 @@
 	lockmgr(&cd->sc_lock, LK_RELEASE, NULL);
 	return (0);
 
-bad2:
 	periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
 
 bad:

--6TrnltStXW4iwmi0--