Subject: Error code for "No Media"
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-kern
Date: 01/27/1999 17:52:03
--YZ5djTAD1cGYuMQK
Content-Type: text/plain; charset=us-ascii

Hi,
I made the necessery changes to the sd and cd drivers to get a different
error code for the "no media" case. For now I use ENODEV, this can easily be
changed. 
As pointed out, FreeBSD returns ENXIO, which I don't like very much
(ENXIO  is also used for device doesn't exist, or partition doesn't exist).

Also, I'm planning to retrict open for the raw block device too (you could
open only the raw character device when the drive is empty).
The reason is that a read on the block device returns a short read
instead of and error (a 'mount /cdrom' will complain for EINVAL instead
of ENODEV, and dd if=/dev/cd0d will return no error, just 0 block transfered).

Comments ?

--
Manuel Bouyer <bouyer@antioche.eu.org>
--

--YZ5djTAD1cGYuMQK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="scsi.diff"

Index: cd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/cd.c,v
retrieving revision 1.119
diff -u -r1.119 cd.c
--- cd.c	1999/01/26 13:59:44	1.119
+++ cd.c	1999/01/27 16:39:15
@@ -257,7 +257,8 @@
 		 * If any partition is open, but the disk has been invalidated,
 		 * disallow further opens.
 		 */
-		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
+		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0 &&
+			part != RAW_PART) {
 			error = EIO;
 			goto bad3;
 		}
@@ -420,7 +421,10 @@
 	 * maybe the media changed
 	 */
 	if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
-		bp->b_error = EIO;
+		if (cd->sc_link->flags & SDEV_OPEN)
+			bp->b_error = EIO;
+		else
+			bp->b_error = ENODEV;
 		goto bad;
 	}
 	/*
@@ -529,7 +533,7 @@
 		dp->b_actf = bp->b_actf;
 
 		/*
-		 * If the deivce has become invalid, abort all the
+		 * If the device has become invalid, abort all the
 		 * reads and writes until all files have been closed and
 		 * re-opened
 		 */
@@ -730,6 +734,7 @@
 		case CDIOCSETLEFT:
 		case CDIOCSETRIGHT:
 		case CDIOCCLOSE:
+		case CDIOCEJECT:
 		case CDIOCALLOW:
 		case CDIOCPREVENT:
 		case CDIOCSETDEBUG:
@@ -741,7 +746,10 @@
 				break;
 		/* FALLTHROUGH */
 		default:
-			return (EIO);
+			if ((cd->sc_link->flags & SDEV_OPEN) == 0)
+				return (ENODEV);
+			else
+				return (EIO);
 		}
 	}
 
Index: scsipi_base.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipi_base.c,v
retrieving revision 1.18
diff -u -r1.18 scsipi_base.c
--- scsipi_base.c	1999/01/19 10:57:11	1.18
+++ scsipi_base.c	1999/01/27 16:39:16
@@ -287,9 +287,13 @@
 				sc_link->flags &= ~SDEV_MEDIA_LOADED;
 			if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
 				return (0);
+			if (sense->add_sense_code == 0x3A &&
+			    sense->add_sense_code_qual == 0x00)
+				error = ENODEV; /* Medium not present */
+			else
+				error = EIO;
 			if ((xs->flags & SCSI_SILENT) != 0)
-				return (EIO);
-			error = EIO;
+				return (error);
 			break;
 		case SKEY_ILLEGAL_REQUEST:
 			if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
Index: sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.140
diff -u -r1.140 sd.c
--- sd.c	1999/01/26 13:59:44	1.140
+++ sd.c	1999/01/27 16:39:17
@@ -469,7 +469,10 @@
 	 * If the device has been made invalid, error out
 	 */
 	if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
-		bp->b_error = EIO;
+		if (sd->sc_link->flags & SDEV_OPEN)
+			bp->b_error = EIO;
+		else
+			bp->b_error = ENODEV;
 		goto bad;
 	}
 	/*
@@ -762,7 +765,10 @@
 				break;
 		/* FALLTHROUGH */
 		default:
-			return (EIO);
+			if ((sd->sc_link->flags & SDEV_OPEN) == 0)
+				return (ENODEV);
+			else
+				return (EIO);
 		}
 	}
 

--YZ5djTAD1cGYuMQK--