Module Name:    src
Committed By:   mlelstv
Date:           Fri Mar 27 11:15:33 UTC 2020

Modified Files:
        src/sys/dev/scsipi: cd.c

Log Message:
Allow open of RAWPART even when no medium is loaded.
Keep errors silent if no medium is loaded.

Fixes PR kern/55104


To generate a diff of this commit:
cvs rdiff -u -r1.342 -r1.343 src/sys/dev/scsipi/cd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/scsipi/cd.c
diff -u src/sys/dev/scsipi/cd.c:1.342 src/sys/dev/scsipi/cd.c:1.343
--- src/sys/dev/scsipi/cd.c:1.342	Mon Sep  3 16:29:33 2018
+++ src/sys/dev/scsipi/cd.c	Fri Mar 27 11:15:33 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd.c,v 1.342 2018/09/03 16:29:33 riastradh Exp $	*/
+/*	$NetBSD: cd.c,v 1.343 2020/03/27 11:15:33 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001, 2003, 2004, 2005, 2008 The NetBSD Foundation,
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.342 2018/09/03 16:29:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.343 2020/03/27 11:15:33 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -401,8 +401,8 @@ cd_firstopen(device_t self, dev_t dev, i
         else
                 silent = 0;
 
-	/* make cdclose() loud again */
-	cd->flags &= ~CDF_EJECTED;
+	/* make cdclose() silent */
+	cd->flags |= CDF_EJECTED;
 
 	/* Check that it is still responding and ok. */
 	error = scsipi_test_unit_ready(periph,
@@ -419,8 +419,11 @@ cd_firstopen(device_t self, dev_t dev, i
 		if (error == EINVAL)
 			error = EIO;
 	}
-	if (error)
+	if (error) {
+		if (part == RAW_PART)
+			goto out;
 		goto bad;
+	}
 
 	/* Lock the pack in. */
 	error = scsipi_prevent(periph, SPAMR_PREVENT_DT,
@@ -448,6 +451,9 @@ cd_firstopen(device_t self, dev_t dev, i
 		SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
 
 		cd_set_geometry(cd);
+
+		/* make cdclose() loud again */
+		cd->flags &= ~CDF_EJECTED;
 	}
 
 	periph->periph_flags |= PERIPH_OPEN;
@@ -519,7 +525,8 @@ cd_lastclose(device_t self)
 	struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
 	int silent;
 
-	if (cd->flags & CDF_EJECTED)
+	if ((cd->flags & CDF_EJECTED) != 0 ||
+	    (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0)
 		silent = XS_CTL_SILENT;
 	else
 		silent = 0;
@@ -1213,6 +1220,14 @@ cdioctl(dev_t dev, u_long cmd, void *add
 		return (EIO);
 
 	switch (cmd) {
+	case DIOCTUR: {
+		/* test unit ready */
+		error = scsipi_test_unit_ready(cd->sc_periph, XS_CTL_SILENT);
+		*((int*)addr) = (error == 0);
+		if (error == ENODEV || error == EIO || error == 0)
+			return 0;                       
+		return error;
+	}
 	case CDIOCPLAYTRACKS: {
 		/* PLAY_MSF command */
 		struct ioc_play_track *args = addr;
@@ -1447,15 +1462,18 @@ static void
 cd_label(device_t self, struct disklabel *lp)
 {
 	struct cd_softc *cd = device_private(self);
+	struct scsipi_periph *periph = cd->sc_periph;
 	struct cd_formatted_toc toc;
-	int lastsession;
+	int lastsession = 0;
 
 	strncpy(lp->d_typename, "optical media", 16);
 	lp->d_rpm = 300;
-	lp->d_flags |= D_REMOVABLE | D_SCSI_MMC;
+	lp->d_flags |= D_REMOVABLE;
 
-	if (cdreadmsaddr(cd, &toc, &lastsession) != 0)
-		lastsession = 0;
+	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) != 0) {
+		lp->d_flags |= D_SCSI_MMC;
+		(void) cdreadmsaddr(cd, &toc, &lastsession);
+	}
 
 	lp->d_partitions[0].p_offset = 0;
 	lp->d_partitions[0].p_size = lp->d_secperunit;

Reply via email to