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;