From 69ece32c464618e23617d846c43b078240d99f3a Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Wed, 19 Jul 2006 01:21:29 +0000 Subject: Add cd_powerhook(). Use it to lock CD drives having open partitions when PWR_RESUME occurs. The drives may have forgotten they were locked. Noted and original diff by Alexey Vatchenko. "I agree with the intent." miod@ "Looks acceptable." deraadt@ --- sys/scsi/cd.c | 26 +++++++++++++++++++++++++- sys/scsi/cd.h | 3 ++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 4ae7920d7ff..4e1ed9e1d33 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.107 2006/05/11 00:45:59 krw Exp $ */ +/* $OpenBSD: cd.c,v 1.108 2006/07/19 01:21:28 krw Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -133,6 +133,8 @@ int dvd_read_bca(struct cd_softc *, union dvd_struct *); int dvd_read_manufact(struct cd_softc *, union dvd_struct *); int dvd_read_struct(struct cd_softc *, union dvd_struct *); +void cd_powerhook(int why, void *arg); + struct cfattach cd_ca = { sizeof(struct cd_softc), cdmatch, cdattach, cddetach, cdactivate @@ -221,6 +223,10 @@ cdattach(parent, self, aux) cd->flags |= CDF_ANCIENT; printf("\n"); + + if ((cd->sc_cdpwrhook = powerhook_establish(cd_powerhook, cd)) == NULL) + printf("%s: WARNING: unable to establish power hook\n", + cd->sc_dev.dv_xname); } @@ -275,6 +281,10 @@ cddetach(self, flags) if (cdevsw[cmaj].d_open == cdopen) vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR); + /* Get rid of the power hook. */ + if (sc->sc_cdpwrhook != NULL) + powerhook_disestablish(sc->sc_cdpwrhook); + /* Detach disk. */ disk_detach(&sc->sc_dk); @@ -1995,3 +2005,17 @@ dvd_read_struct(cd, s) return (EINVAL); } } + +void +cd_powerhook(int why, void *arg) +{ + struct cd_softc *cd = arg; + + /* + * When resuming, hardware may have forgotten we locked it. So if + * there are any open partitions, lock the CD. + */ + if (why == PWR_RESUME && cd->sc_dk.dk_openmask != 0) + scsi_prevent(cd->sc_link, PR_PREVENT, + SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE); +} diff --git a/sys/scsi/cd.h b/sys/scsi/cd.h index 93a25e8ed93..d3a3cee140e 100644 --- a/sys/scsi/cd.h +++ b/sys/scsi/cd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.h,v 1.12 2006/06/02 01:20:41 mjc Exp $ */ +/* $OpenBSD: cd.h,v 1.13 2006/07/19 01:21:28 krw Exp $ */ /* $NetBSD: scsi_cd.h,v 1.6 1996/03/19 03:06:39 mycroft Exp $ */ /* @@ -298,6 +298,7 @@ struct cd_softc { struct cd_parms orig_params; /* filled in when CD-DA mode starts */ #endif struct buf buf_queue; + void *sc_cdpwrhook; /* our power hook */ }; #endif /* _KERNEL */ -- cgit v1.2.3