diff options
| author | jdolecek <jdolecek@NetBSD.org> | 2017-02-27 21:32:33 +0000 |
|---|---|---|
| committer | jdolecek <jdolecek@NetBSD.org> | 2017-02-27 21:32:33 +0000 |
| commit | 141e580a02b235aaa20bbecb460d1fc77d187cac (patch) | |
| tree | 75c6d3c8c744246fdeba54a67d3494dc34e5dee1 /sys/dev/ld.c | |
| parent | cb85970f3b66566d3f60953f906df56cd379af92 (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.c | 65 |
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 |
