Module Name: src Committed By: jdolecek Date: Mon Feb 27 21:32:33 UTC 2017
Modified Files: src/sys/dev: ld.c ldvar.h src/sys/dev/i2o: ld_iop.c src/sys/dev/ic: ld_icp.c ld_nvme.c src/sys/dev/pci: ld_twa.c ld_twe.c ld_virtio.c Log Message: refactor the ld(4) DIOCCACHESYNC hook into general ioctl hook, so that attachments would be able to implement arbitrary other ioctls To generate a diff of this commit: cvs rdiff -u -r1.99 -r1.100 src/sys/dev/ld.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/ldvar.h cvs rdiff -u -r1.36 -r1.37 src/sys/dev/i2o/ld_iop.c cvs rdiff -u -r1.30 -r1.31 src/sys/dev/ic/ld_icp.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ic/ld_nvme.c cvs rdiff -u -r1.19 -r1.20 src/sys/dev/pci/ld_twa.c cvs rdiff -u -r1.39 -r1.40 src/sys/dev/pci/ld_twe.c cvs rdiff -u -r1.13 -r1.14 src/sys/dev/pci/ld_virtio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ld.c diff -u src/sys/dev/ld.c:1.99 src/sys/dev/ld.c:1.100 --- src/sys/dev/ld.c:1.99 Sat Nov 26 12:32:03 2016 +++ src/sys/dev/ld.c Mon Feb 27 21:32:33 2017 @@ -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_so 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_ 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, st 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 *add 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 *add */ 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 Index: src/sys/dev/ldvar.h diff -u src/sys/dev/ldvar.h:1.28 src/sys/dev/ldvar.h:1.29 --- src/sys/dev/ldvar.h:1.28 Fri Sep 16 15:20:50 2016 +++ src/sys/dev/ldvar.h Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ldvar.h,v 1.28 2016/09/16 15:20:50 jdolecek Exp $ */ +/* $NetBSD: ldvar.h,v 1.29 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ struct ld_softc { int sc_maxqueuecnt; /* maximum h/w queue depth */ int (*sc_dump)(struct ld_softc *, void *, int, int); - int (*sc_flush)(struct ld_softc *, int); + int (*sc_ioctl)(struct ld_softc *, u_long, void *, int32_t, bool); int (*sc_start)(struct ld_softc *, struct buf *); int (*sc_discard)(struct ld_softc *, off_t, off_t); }; @@ -68,9 +68,6 @@ struct ld_softc { #define LDF_ENABLED 0x001 /* device enabled */ #define LDF_DRAIN 0x020 /* maxqueuecnt has changed; drain */ -/* sc_flush() flags */ -#define LDFL_POLL 0x001 /* poll for completion */ - int ldadjqparam(struct ld_softc *, int); void ldattach(struct ld_softc *, const char *); int ldbegindetach(struct ld_softc *, int); Index: src/sys/dev/i2o/ld_iop.c diff -u src/sys/dev/i2o/ld_iop.c:1.36 src/sys/dev/i2o/ld_iop.c:1.37 --- src/sys/dev/i2o/ld_iop.c:1.36 Fri Sep 16 15:20:50 2016 +++ src/sys/dev/i2o/ld_iop.c Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_iop.c,v 1.36 2016/09/16 15:20:50 jdolecek Exp $ */ +/* $NetBSD: ld_iop.c,v 1.37 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.36 2016/09/16 15:20:50 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.37 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -73,7 +73,8 @@ static void ld_iop_adjqparam(device_t, i static void ld_iop_attach(device_t, device_t, void *); static int ld_iop_detach(device_t, int); static int ld_iop_dump(struct ld_softc *, void *, int, int); -static int ld_iop_flush(struct ld_softc *, int); +static int ld_iop_flush(struct ld_softc *, bool); +static int ld_iop_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_iop_intr(device_t, struct iop_msg *, void *); static void ld_iop_intr_event(device_t, struct iop_msg *, void *); static int ld_iop_match(device_t, cfdata_t, void *); @@ -168,7 +169,7 @@ ld_iop_attach(device_t parent, device_t ld->sc_maxxfer = IOP_MAX_XFER; ld->sc_dump = ld_iop_dump; - ld->sc_flush = ld_iop_flush; + ld->sc_ioctl = ld_iop_ioctl; ld->sc_start = ld_iop_start; /* Say what the device is. */ @@ -437,7 +438,7 @@ ld_iop_dump(struct ld_softc *ld, void *d } static int -ld_iop_flush(struct ld_softc *ld, int flags) +ld_iop_flush(struct ld_softc *ld, bool poll) { struct iop_msg *im; struct iop_softc *iop; @@ -461,7 +462,25 @@ ld_iop_flush(struct ld_softc *ld, int fl return (rv); } -void +static int +ld_iop_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) +{ + int error; + + switch (cmd) { + case DIOCCACHESYNC: + error = ld_iop_flush(ld, poll); + break; + + default: + error = EPASSTHROUGH; + break; + } + + return error; +} + +static void ld_iop_intr(device_t dv, struct iop_msg *im, void *reply) { struct i2o_rbs_reply *rb; Index: src/sys/dev/ic/ld_icp.c diff -u src/sys/dev/ic/ld_icp.c:1.30 src/sys/dev/ic/ld_icp.c:1.31 --- src/sys/dev/ic/ld_icp.c:1.30 Sun Feb 26 23:06:36 2017 +++ src/sys/dev/ic/ld_icp.c Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_icp.c,v 1.30 2017/02/26 23:06:36 jdolecek Exp $ */ +/* $NetBSD: ld_icp.c,v 1.31 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1.30 2017/02/26 23:06:36 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_icp.c,v 1.31 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -65,7 +65,8 @@ static int ld_icp_detach(device_t, int); static int ld_icp_dobio(struct ld_icp_softc *, void *, int, int, int, struct buf *); static int ld_icp_dump(struct ld_softc *, void *, int, int); -static int ld_icp_flush(struct ld_softc *, int); +static int ld_icp_flush(struct ld_softc *, bool); +static int ld_icp_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_icp_intr(struct icp_ccb *); static int ld_icp_match(device_t, cfdata_t, void *); static int ld_icp_start(struct ld_softc *, struct buf *); @@ -110,7 +111,7 @@ ld_icp_attach(device_t parent, device_t ld->sc_secsize = ICP_SECTOR_SIZE; ld->sc_start = ld_icp_start; ld->sc_dump = ld_icp_dump; - ld->sc_flush = ld_icp_flush; + ld->sc_ioctl = ld_icp_ioctl; ld->sc_secperunit = cd->cd_size; ld->sc_flags = LDF_ENABLED; ld->sc_maxqueuecnt = icp->icp_openings; @@ -254,8 +255,9 @@ ld_icp_dump(struct ld_softc *ld, void *d blkcnt * ld->sc_secsize, blkno, 1, NULL)); } +/* ARGSUSED */ static int -ld_icp_flush(struct ld_softc *ld, int flags) +ld_icp_flush(struct ld_softc *ld, bool poll) { struct ld_icp_softc *sc; struct icp_softc *icp; @@ -285,6 +287,24 @@ ld_icp_flush(struct ld_softc *ld, int fl return (rv); } +static int +ld_icp_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) +{ + int error; + + switch (cmd) { + case DIOCCACHESYNC: + error = ld_icp_flush(ld, poll); + break; + + default: + error = EPASSTHROUGH; + break; + } + + return error; +} + static void ld_icp_intr(struct icp_ccb *ic) { Index: src/sys/dev/ic/ld_nvme.c diff -u src/sys/dev/ic/ld_nvme.c:1.10 src/sys/dev/ic/ld_nvme.c:1.11 --- src/sys/dev/ic/ld_nvme.c:1.10 Tue Nov 1 14:39:38 2016 +++ src/sys/dev/ic/ld_nvme.c Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_nvme.c,v 1.10 2016/11/01 14:39:38 jdolecek Exp $ */ +/* $NetBSD: ld_nvme.c,v 1.11 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (C) 2016 NONAKA Kimihiro <non...@netbsd.org> @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.10 2016/11/01 14:39:38 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.11 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -60,7 +60,8 @@ CFATTACH_DECL_NEW(ld_nvme, sizeof(struct static int ld_nvme_start(struct ld_softc *, struct buf *); static int ld_nvme_dump(struct ld_softc *, void *, int, int); -static int ld_nvme_flush(struct ld_softc *, int); +static int ld_nvme_flush(struct ld_softc *, bool); +static int ld_nvme_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_nvme_biodone(void *, struct buf *, uint16_t); static void ld_nvme_syncdone(void *, struct buf *, uint16_t); @@ -112,7 +113,7 @@ ld_nvme_attach(device_t parent, device_t ld->sc_maxqueuecnt = naa->naa_qentries; ld->sc_start = ld_nvme_start; ld->sc_dump = ld_nvme_dump; - ld->sc_flush = ld_nvme_flush; + ld->sc_ioctl = ld_nvme_ioctl; ld->sc_flags = LDF_ENABLED; ldattach(ld, "fcfs"); } @@ -180,16 +181,34 @@ ld_nvme_biodone(void *xc, struct buf *bp } static int -ld_nvme_flush(struct ld_softc *ld, int flags) +ld_nvme_flush(struct ld_softc *ld, bool poll) { struct ld_nvme_softc *sc = device_private(ld->sc_dv); - /* wait for the sync to finish */ return nvme_ns_sync(sc->sc_nvme, sc->sc_nsid, sc, - (flags & LDFL_POLL) ? NVME_NS_CTX_F_POLL : 0, + poll ? NVME_NS_CTX_F_POLL : 0, ld_nvme_syncdone); } +static int +ld_nvme_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) +{ + int error; + struct ld_nvme_softc *sc = device_private(ld->sc_dv); + + switch (cmd) { + case DIOCCACHESYNC: + error = ld_nvme_flush(ld, poll); + break; + + default: + error = EPASSTHROUGH; + break; + } + + return error; +} + static void ld_nvme_syncdone(void *xc, struct buf *bp, uint16_t cmd_status) { Index: src/sys/dev/pci/ld_twa.c diff -u src/sys/dev/pci/ld_twa.c:1.19 src/sys/dev/pci/ld_twa.c:1.20 --- src/sys/dev/pci/ld_twa.c:1.19 Tue Sep 27 03:33:32 2016 +++ src/sys/dev/pci/ld_twa.c Mon Feb 27 21:32:33 2017 @@ -1,5 +1,5 @@ /* $wasabi: ld_twa.c,v 1.9 2006/02/14 18:44:37 jordanr Exp $ */ -/* $NetBSD: ld_twa.c,v 1.19 2016/09/27 03:33:32 pgoyette Exp $ */ +/* $NetBSD: ld_twa.c,v 1.20 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2000, 2001, 2002, 2003, 2004 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1.19 2016/09/27 03:33:32 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_twa.c,v 1.20 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -76,7 +76,8 @@ static int ld_twa_detach(device_t, int); static int ld_twa_dobio(struct ld_twa_softc *, void *, size_t, daddr_t, struct buf *); static int ld_twa_dump(struct ld_softc *, void *, int, int); -static int ld_twa_flush(struct ld_softc *, int); +static int ld_twa_flush(struct ld_softc *, bool); +static int ld_twa_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_twa_handler(struct twa_request *); static int ld_twa_match(device_t, cfdata_t, void *); static int ld_twa_start(struct ld_softc *, struct buf *); @@ -120,7 +121,7 @@ ld_twa_attach(device_t parent, device_t ld->sc_maxqueuecnt = twa->sc_units[sc->sc_hwunit].td_openings; ld->sc_start = ld_twa_start; ld->sc_dump = ld_twa_dump; - ld->sc_flush = ld_twa_flush; + ld->sc_ioctl = ld_twa_ioctl; ldattach(ld, BUFQ_DISK_DEFAULT_STRAT); } @@ -235,7 +236,7 @@ ld_twa_dump(struct ld_softc *ld, void *d static int -ld_twa_flush(struct ld_softc *ld, int flags) +ld_twa_flush(struct ld_softc *ld, bool poll) { int s, rv = 0; struct twa_request *tr; @@ -276,6 +277,24 @@ ld_twa_flush(struct ld_softc *ld, int fl return (rv); } +static int +ld_twa_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) +{ + int error; + + switch (cmd) { + case DIOCCACHESYNC: + error = ld_twa_flush(ld, poll); + break; + + default: + error = EPASSTHROUGH; + break; + } + + return error; +} + static void ld_twa_adjqparam(device_t self, int openings) { Index: src/sys/dev/pci/ld_twe.c diff -u src/sys/dev/pci/ld_twe.c:1.39 src/sys/dev/pci/ld_twe.c:1.40 --- src/sys/dev/pci/ld_twe.c:1.39 Tue Sep 27 03:33:32 2016 +++ src/sys/dev/pci/ld_twe.c Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_twe.c,v 1.39 2016/09/27 03:33:32 pgoyette Exp $ */ +/* $NetBSD: ld_twe.c,v 1.40 2017/02/27 21:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.39 2016/09/27 03:33:32 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.40 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -66,7 +66,8 @@ static int ld_twe_detach(device_t, int); static int ld_twe_dobio(struct ld_twe_softc *, void *, int, int, int, struct buf *); static int ld_twe_dump(struct ld_softc *, void *, int, int); -static int ld_twe_flush(struct ld_softc *, int); +static int ld_twe_flush(struct ld_softc *, bool); +static int ld_twe_ioctl(struct ld_softc *, u_long, void *, int32_t, bool); static void ld_twe_handler(struct twe_ccb *, int); static int ld_twe_match(device_t, cfdata_t, void *); static int ld_twe_start(struct ld_softc *, struct buf *); @@ -112,7 +113,7 @@ ld_twe_attach(device_t parent, device_t ld->sc_maxqueuecnt = twe->sc_openings; ld->sc_start = ld_twe_start; ld->sc_dump = ld_twe_dump; - ld->sc_flush = ld_twe_flush; + ld->sc_ioctl = ld_twe_ioctl; typestr = twe_describe_code(twe_table_unittype, td->td_type); if (typestr == NULL) { @@ -266,7 +267,7 @@ ld_twe_dump(struct ld_softc *ld, void *d } static int -ld_twe_flush(struct ld_softc *ld, int flags) +ld_twe_flush(struct ld_softc *ld, bool poll) { struct ld_twe_softc *sc = (void *) ld; struct twe_softc *twe = device_private(device_parent(ld->sc_dv)); @@ -286,7 +287,7 @@ ld_twe_flush(struct ld_softc *ld, int fl tc->tc_unit = sc->sc_hwunit; tc->tc_count = 0; - if (flags & LDFL_POLL) { + if (poll) { /* * Polled commands must not sit on the software queue. Wait * up to 2 seconds for the command to complete. @@ -315,6 +316,24 @@ ld_twe_flush(struct ld_softc *ld, int fl return (rv); } +static int +ld_twe_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll) +{ + int error; + + switch (cmd) { + case DIOCCACHESYNC: + error = ld_twe_flush(ld, poll); + break; + + default: + error = EPASSTHROUGH; + break; + } + + return error; +} + static void ld_twe_adjqparam(device_t self, int openings) { Index: src/sys/dev/pci/ld_virtio.c diff -u src/sys/dev/pci/ld_virtio.c:1.13 src/sys/dev/pci/ld_virtio.c:1.14 --- src/sys/dev/pci/ld_virtio.c:1.13 Wed Nov 30 01:36:38 2016 +++ src/sys/dev/pci/ld_virtio.c Mon Feb 27 21:32:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_virtio.c,v 1.13 2016/11/30 01:36:38 christos Exp $ */ +/* $NetBSD: ld_virtio.c,v 1.14 2017/02/27 21:32:33 jdolecek Exp $ */ /* * Copyright (c) 2010 Minoura Makoto. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.13 2016/11/30 01:36:38 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.14 2017/02/27 21:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -350,7 +350,6 @@ ld_virtio_attach(device_t parent, device goto err; ld->sc_dump = ld_virtio_dump; - ld->sc_flush = NULL; ld->sc_start = ld_virtio_start; ld->sc_flags = LDF_ENABLED;