summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-12-19 19:52:12 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-12-19 19:52:12 +0000
commit248015a6412e777398093e0a0321d77a4a740576 (patch)
treeee7cf5f9ce01d8fceb787bff36d4beac59abb205 /sys
parentacb0a240be37d315b0ef46200c71a79b3fdf4808 (diff)
Temporarily bring back the shutdown hook, but only use it to flush the disk
cache. This shouldn't interfere with the hibernate code and makes sure we still flush the cache for controller that don't pass DVACT_POWRDOWN down to their children yet. This will be removed when the autoconf subsystem gets changed to do that for us by default. ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/scsi/sd.c35
-rw-r--r--sys/scsi/sdvar.h3
2 files changed, 36 insertions, 2 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 275e17e93af..e7b8ed619f1 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.244 2012/10/15 16:29:07 deraadt Exp $ */
+/* $OpenBSD: sd.c,v 1.245 2012/12/19 19:52:11 kettenis Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -87,6 +87,7 @@ int sddetach(struct device *, int);
void sdminphys(struct buf *);
int sdgetdisklabel(dev_t, struct sd_softc *, struct disklabel *, int);
void sdstart(struct scsi_xfer *);
+void sd_shutdown(void *);
int sd_interpret_sense(struct scsi_xfer *);
int sd_read_cap_10(struct sd_softc *, int);
int sd_read_cap_16(struct sd_softc *, int);
@@ -259,6 +260,19 @@ sdattach(struct device *parent, struct device *self, void *aux)
sd_ioctl_cache(sc, DIOCSCACHE, &dkc);
}
+ /*
+ * Establish a shutdown hook so that we can ensure that
+ * our data has actually made it onto the platter at
+ * shutdown time. Note that this relies on the fact
+ * that the shutdown hook code puts us at the head of
+ * the list (thus guaranteeing that our hook runs before
+ * our ancestors').
+ */
+ if ((sc->sc_sdhook =
+ shutdownhook_establish(sd_shutdown, sc)) == NULL)
+ printf("%s: WARNING: unable to establish shutdown hook\n",
+ sc->sc_dev.dv_xname);
+
/* Attach disk. */
disk_attach(&sc->sc_dev, &sc->sc_dk);
}
@@ -311,6 +325,10 @@ sddetach(struct device *self, int flags)
disk_gone(sdopen, self->dv_unit);
+ /* Get rid of the shutdown hook. */
+ if (sc->sc_sdhook != NULL)
+ shutdownhook_disestablish(sc->sc_sdhook);
+
/* Detach disk. */
bufq_destroy(&sc->sc_bufq);
disk_detach(&sc->sc_dk);
@@ -1109,6 +1127,21 @@ sdgetdisklabel(dev_t dev, struct sd_softc *sc, struct disklabel *lp,
return readdisklabel(DISKLABELDEV(dev), sdstrategy, lp, spoofonly);
}
+
+void
+sd_shutdown(void *arg)
+{
+ struct sd_softc *sc = (struct sd_softc *)arg;
+
+ /*
+ * If the disk cache needs to be flushed, and the disk supports
+ * it, flush it. We're cold at this point, so we poll for
+ * completion.
+ */
+ if ((sc->flags & SDF_DIRTY) != 0)
+ sd_flush(sc, SCSI_AUTOCONF);
+}
+
/*
* Check Errors
*/
diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h
index 4e2accdfde1..220190965ad 100644
--- a/sys/scsi/sdvar.h
+++ b/sys/scsi/sdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdvar.h,v 1.39 2012/10/08 21:47:51 deraadt Exp $ */
+/* $OpenBSD: sdvar.h,v 1.40 2012/12/19 19:52:11 kettenis Exp $ */
/* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */
/*-
@@ -69,6 +69,7 @@ struct sd_softc {
u_int32_t unmap_sectors; /* maximum sectors/unmap */
u_int32_t unmap_descs; /* maximum descriptors/unmap */
} params;
+ void *sc_sdhook; /* our shutdown hook */
struct timeout sc_timeout;
struct scsi_xshandler sc_xsh;