summaryrefslogtreecommitdiff
path: root/sys/dev/ld.c
diff options
context:
space:
mode:
authorjdolecek <jdolecek@NetBSD.org>2017-02-27 21:32:33 +0000
committerjdolecek <jdolecek@NetBSD.org>2017-02-27 21:32:33 +0000
commit141e580a02b235aaa20bbecb460d1fc77d187cac (patch)
tree75c6d3c8c744246fdeba54a67d3494dc34e5dee1 /sys/dev/ld.c
parentcb85970f3b66566d3f60953f906df56cd379af92 (diff)
refactor the ld(4) DIOCCACHESYNC hook into general ioctl hook, so that attachments
would be able to implement arbitrary other ioctls
Diffstat (limited to 'sys/dev/ld.c')
-rw-r--r--sys/dev/ld.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/sys/dev/ld.c b/sys/dev/ld.c
index f026db387ce..d0669004d20 100644
--- a/sys/dev/ld.c
+++ b/sys/dev/ld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ld.c,v 1.99 2016/11/26 12:32:03 mlelstv Exp $ */
+/* $NetBSD: ld.c,v 1.100 2017/02/27 21:32:33 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.99 2016/11/26 12:32:03 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.100 2017/02/27 21:32:33 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -70,6 +70,7 @@ static void ld_set_geometry(struct ld_softc *);
static void ld_config_interrupts (device_t);
static int ld_lastclose(device_t);
static int ld_discard(device_t, off_t, off_t);
+static int ld_flush(device_t, bool);
extern struct cfdriver ld_cd;
@@ -247,15 +248,12 @@ ldenddetach(struct ld_softc *sc)
pmf_device_deregister(dksc->sc_dev);
/*
- * XXX We can't really flush the cache here, beceause the
+ * XXX We can't really flush the cache here, because the
* XXX device may already be non-existent from the controller's
* XXX perspective.
*/
#if 0
- /* Flush the device's cache. */
- if (sc->sc_flush != NULL)
- if ((*sc->sc_flush)(sc, 0) != 0)
- device_printf(dksc->sc_dev, "unable to flush cache\n");
+ ld_flush(dksc->sc_dev, false);
#endif
cv_destroy(&sc->sc_drain);
mutex_destroy(&sc->sc_mutex);
@@ -272,14 +270,8 @@ ld_suspend(device_t dev, const pmf_qual_t *qual)
static bool
ld_shutdown(device_t dev, int flags)
{
- struct ld_softc *sc = device_private(dev);
- struct dk_softc *dksc = &sc->sc_dksc;
-
- if ((flags & RB_NOSYNC) == 0 && sc->sc_flush != NULL
- && (*sc->sc_flush)(sc, LDFL_POLL) != 0) {
- device_printf(dksc->sc_dev, "unable to flush cache\n");
+ if ((flags & RB_NOSYNC) == 0 && ld_flush(dev, true) != 0)
return false;
- }
return true;
}
@@ -303,10 +295,7 @@ ldopen(dev_t dev, int flags, int fmt, struct lwp *l)
static int
ld_lastclose(device_t self)
{
- struct ld_softc *sc = device_private(self);
-
- if (sc->sc_flush != NULL && (*sc->sc_flush)(sc, 0) != 0)
- device_printf(self, "unable to flush cache\n");
+ ld_flush(self, false);
return 0;
}
@@ -356,6 +345,10 @@ ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l)
error = 0;
+ /*
+ * Some common checks so that individual attachments wouldn't need
+ * to duplicate them.
+ */
switch (cmd) {
case DIOCCACHESYNC:
/*
@@ -364,18 +357,40 @@ ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l)
*/
if ((flag & FWRITE) == 0)
error = EBADF;
- else if (sc->sc_flush)
- error = (*sc->sc_flush)(sc, 0);
else
- error = 0; /* XXX Error out instead? */
+ error = 0;
break;
+ }
- default:
- error = dk_ioctl(dksc, dev, cmd, addr, flag, l);
- break;
+ if (error != 0)
+ return (error);
+
+ if (sc->sc_ioctl) {
+ error = (*sc->sc_ioctl)(sc, cmd, addr, flag, 0);
+ if (error != EPASSTHROUGH)
+ return (error);
}
- return (error);
+ /* something not handled by the attachment */
+ return dk_ioctl(dksc, dev, cmd, addr, flag, l);
+}
+
+/*
+ * Flush the device's cache.
+ */
+static int
+ld_flush(device_t self, bool poll)
+{
+ int error = 0;
+ struct ld_softc *sc = device_private(self);
+
+ if (sc->sc_ioctl) {
+ error = (*sc->sc_ioctl)(sc, DIOCCACHESYNC, NULL, 0, poll);
+ if (error != 0)
+ device_printf(self, "unable to flush cache\n");
+ }
+
+ return error;
}
static void