summaryrefslogtreecommitdiff
path: root/sys/dev
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
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')
-rw-r--r--sys/dev/i2o/ld_iop.c31
-rw-r--r--sys/dev/ic/ld_icp.c30
-rw-r--r--sys/dev/ic/ld_nvme.c33
-rw-r--r--sys/dev/ld.c65
-rw-r--r--sys/dev/ldvar.h7
-rw-r--r--sys/dev/pci/ld_twa.c29
-rw-r--r--sys/dev/pci/ld_twe.c31
-rw-r--r--sys/dev/pci/ld_virtio.c5
8 files changed, 169 insertions, 62 deletions
diff --git a/sys/dev/i2o/ld_iop.c b/sys/dev/i2o/ld_iop.c
index 6e2526a5dcc..51d13bd359c 100644
--- a/sys/dev/i2o/ld_iop.c
+++ b/sys/dev/i2o/ld_iop.c
@@ -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, int);
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 self, void *aux)
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 *data, int blkno, int blkcnt)
}
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 flags)
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;
diff --git a/sys/dev/ic/ld_icp.c b/sys/dev/ic/ld_icp.c
index ed3e688e76c..4ef3359cd1d 100644
--- a/sys/dev/ic/ld_icp.c
+++ b/sys/dev/ic/ld_icp.c
@@ -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 self, void *aux)
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 *data, int blkno, int blkcnt)
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 flags)
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)
{
diff --git a/sys/dev/ic/ld_nvme.c b/sys/dev/ic/ld_nvme.c
index fee77eb3af2..a0f26afc3cc 100644
--- a/sys/dev/ic/ld_nvme.c
+++ b/sys/dev/ic/ld_nvme.c
@@ -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 <nonaka@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 ld_nvme_softc),
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 self, void *aux)
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, uint16_t cmd_status)
}
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)
{
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
diff --git a/sys/dev/ldvar.h b/sys/dev/ldvar.h
index 0bec99ecdc1..37625e88fef 100644
--- a/sys/dev/ldvar.h
+++ b/sys/dev/ldvar.h
@@ -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);
diff --git a/sys/dev/pci/ld_twa.c b/sys/dev/pci/ld_twa.c
index 4a8de777317..f3b44c4d433 100644
--- a/sys/dev/pci/ld_twa.c
+++ b/sys/dev/pci/ld_twa.c
@@ -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 self, void *aux)
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 *data, int blkno, int blkcnt)
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 flags)
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)
{
diff --git a/sys/dev/pci/ld_twe.c b/sys/dev/pci/ld_twe.c
index 9c13634cb82..dc4e0f3e8f1 100644
--- a/sys/dev/pci/ld_twe.c
+++ b/sys/dev/pci/ld_twe.c
@@ -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 self, void *aux)
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 *data, int blkno, int blkcnt)
}
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 flags)
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 flags)
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)
{
diff --git a/sys/dev/pci/ld_virtio.c b/sys/dev/pci/ld_virtio.c
index 7bcfd433181..fa33cdec19f 100644
--- a/sys/dev/pci/ld_virtio.c
+++ b/sys/dev/pci/ld_virtio.c
@@ -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_t self, void *aux)
goto err;
ld->sc_dump = ld_virtio_dump;
- ld->sc_flush = NULL;
ld->sc_start = ld_virtio_start;
ld->sc_flags = LDF_ENABLED;