summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2006-07-19 01:21:29 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2006-07-19 01:21:29 +0000
commit69ece32c464618e23617d846c43b078240d99f3a (patch)
tree88a64a6c5d7e0e01acb30c69bfff95a39d24fa30
parent8a5eb1af81f09320bd5da3b94c89803b328e6bb2 (diff)
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@
-rw-r--r--sys/scsi/cd.c26
-rw-r--r--sys/scsi/cd.h3
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 */