Module Name: src
Committed By: martin
Date: Fri Sep 1 09:59:11 UTC 2017
Modified Files:
src/sys/dev [netbsd-8]: dksubr.c ld.c ldvar.h
src/sys/dev/i2o [netbsd-8]: ld_iop.c
src/sys/dev/ic [netbsd-8]: ld_cac.c ld_nvme.c
src/sys/dev/pci [netbsd-8]: ld_virtio.c
src/sys/dev/sdmmc [netbsd-8]: ld_sdmmc.c sdmmc_mem.c sdmmcvar.h
Log Message:
Pull up following revision(s) (requested by mlelstv in ticket #261):
sys/dev/sdmmc/ld_sdmmc.c: revision 1.32
sys/dev/sdmmc/ld_sdmmc.c: revision 1.33
sys/dev/sdmmc/ld_sdmmc.c: revision 1.34
sys/dev/sdmmc/sdmmc_mem.c: revision 1.62
sys/dev/i2o/ld_iop.c: revision 1.39
sys/dev/ld.c: revision 1.102
sys/dev/ld.c: revision 1.103
sys/dev/dksubr.c: revision 1.98
sys/dev/dksubr.c: revision 1.99
sys/dev/sdmmc/sdmmcvar.h: revision 1.29
sys/dev/ic/ld_nvme.c: revision 1.17
sys/dev/ldvar.h: revision 1.31
sys/dev/ldvar.h: revision 1.32
sys/dev/ic/ld_cac.c: revision 1.31
sys/dev/pci/ld_virtio.c: revision 1.16
While ld(4) is MP safe, many backends are not.
Add a flag for backends that are MP safe. Take KERNEL_LOCK when calling
into a backend that doesn't have the flag set. Do the same for the
discard routine.
Fixes PR 52462.
Defer sdmmc discard operations to the sdmmc task queue. Fixes a panic
introduced by ld.c r1.102.
validate length for discard operation and split operation when byte length
doesn't fit into 'int'.
make the sc_discard interface for the ld backend asynchronous and
signal completion through new callback lddiscardend. Use a standard
struct buf to pass disk address and range instead of two off_t values.
make lddiscard synchronous again. This is a requirement of the current
ffs discard code.
Initialize error also in the case where len=0, which just succeeds.
while here, assert that the len is indeed non-negative. this is already
confirmed by sys_fdiscard, but let's be sure.
reported by: GCC, but with different compile flags
To generate a diff of this commit:
cvs rdiff -u -r1.97 -r1.97.2.1 src/sys/dev/dksubr.c
cvs rdiff -u -r1.101 -r1.101.2.1 src/sys/dev/ld.c
cvs rdiff -u -r1.30 -r1.30.2.1 src/sys/dev/ldvar.h
cvs rdiff -u -r1.37 -r1.37.6.1 src/sys/dev/i2o/ld_iop.c
cvs rdiff -u -r1.30 -r1.30.8.1 src/sys/dev/ic/ld_cac.c
cvs rdiff -u -r1.16 -r1.16.2.1 src/sys/dev/ic/ld_nvme.c
cvs rdiff -u -r1.15 -r1.15.6.1 src/sys/dev/pci/ld_virtio.c
cvs rdiff -u -r1.26.4.4 -r1.26.4.5 src/sys/dev/sdmmc/ld_sdmmc.c
cvs rdiff -u -r1.56.4.3 -r1.56.4.4 src/sys/dev/sdmmc/sdmmc_mem.c
cvs rdiff -u -r1.23.6.3 -r1.23.6.4 src/sys/dev/sdmmc/sdmmcvar.h
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/dksubr.c
diff -u src/sys/dev/dksubr.c:1.97 src/sys/dev/dksubr.c:1.97.2.1
--- src/sys/dev/dksubr.c:1.97 Thu Apr 27 17:07:22 2017
+++ src/sys/dev/dksubr.c Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: dksubr.c,v 1.97 2017/04/27 17:07:22 jdolecek Exp $ */
+/* $NetBSD: dksubr.c,v 1.97.2.1 2017/09/01 09:59:10 martin Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.97 2017/04/27 17:07:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.97.2.1 2017/09/01 09:59:10 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -497,7 +497,10 @@ dk_discard(struct dk_softc *dksc, dev_t
const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver;
unsigned secsize = dksc->sc_dkdev.dk_geom.dg_secsize;
struct buf tmp, *bp = &tmp;
- int error;
+ int maxsz;
+ int error = 0;
+
+ KASSERT(len >= 0);
DPRINTF_FOLLOW(("%s(%s, %p, 0x"PRIx64", %jd, %jd)\n", __func__,
dksc->sc_xname, dksc, (intmax_t)pos, (intmax_t)len));
@@ -507,22 +510,32 @@ dk_discard(struct dk_softc *dksc, dev_t
return ENXIO;
}
- if (secsize == 0 || (pos % secsize) != 0)
+ if (secsize == 0 || (pos % secsize) != 0 || (len % secsize) != 0)
return EINVAL;
- /* enough data to please the bounds checking code */
- bp->b_dev = dev;
- bp->b_blkno = (daddr_t)(pos / secsize);
- bp->b_bcount = len;
- bp->b_flags = B_WRITE;
+ /* largest value that b_bcount can store */
+ maxsz = rounddown(INT_MAX, secsize);
- error = dk_translate(dksc, bp);
- if (error >= 0)
- return error;
+ while (len > 0) {
+ /* enough data to please the bounds checking code */
+ bp->b_dev = dev;
+ bp->b_blkno = (daddr_t)(pos / secsize);
+ bp->b_bcount = min(len, maxsz);
+ bp->b_flags = B_WRITE;
+
+ error = dk_translate(dksc, bp);
+ if (error >= 0)
+ break;
+
+ error = dkd->d_discard(dksc->sc_dev,
+ (off_t)bp->b_rawblkno * secsize,
+ (off_t)bp->b_bcount);
+ if (error)
+ break;
- error = dkd->d_discard(dksc->sc_dev,
- (off_t)bp->b_rawblkno * secsize,
- (off_t)bp->b_bcount);
+ pos += bp->b_bcount;
+ len -= bp->b_bcount;
+ }
return error;
}
Index: src/sys/dev/ld.c
diff -u src/sys/dev/ld.c:1.101 src/sys/dev/ld.c:1.101.2.1
--- src/sys/dev/ld.c:1.101 Thu Apr 27 17:07:22 2017
+++ src/sys/dev/ld.c Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld.c,v 1.101 2017/04/27 17:07:22 jdolecek Exp $ */
+/* $NetBSD: ld.c,v 1.101.2.1 2017/09/01 09:59:10 martin 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.101 2017/04/27 17:07:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.101.2.1 2017/09/01 09:59:10 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -419,6 +419,9 @@ ld_diskstart(device_t dev, struct buf *b
if (sc->sc_queuecnt >= sc->sc_maxqueuecnt)
return EAGAIN;
+ if ((sc->sc_flags & LDF_MPSAFE) == 0)
+ KERNEL_LOCK(1, curlwp);
+
mutex_enter(&sc->sc_mutex);
if (sc->sc_queuecnt >= sc->sc_maxqueuecnt)
@@ -431,6 +434,9 @@ ld_diskstart(device_t dev, struct buf *b
mutex_exit(&sc->sc_mutex);
+ if ((sc->sc_flags & LDF_MPSAFE) == 0)
+ KERNEL_UNLOCK_ONE(curlwp);
+
return error;
}
@@ -589,11 +595,45 @@ static int
ld_discard(device_t dev, off_t pos, off_t len)
{
struct ld_softc *sc = device_private(dev);
+ struct buf dbuf, *bp = &dbuf;
+ int error = 0;
+
+ KASSERT(len <= INT_MAX);
if (sc->sc_discard == NULL)
return (ENODEV);
- return (*sc->sc_discard)(sc, pos, len);
+ if ((sc->sc_flags & LDF_MPSAFE) == 0)
+ KERNEL_LOCK(1, curlwp);
+
+ buf_init(bp);
+ bp->b_vp = NULL;
+ bp->b_data = NULL;
+ bp->b_bufsize = 0;
+ bp->b_rawblkno = pos / sc->sc_secsize;
+ bp->b_bcount = len;
+ bp->b_flags = B_WRITE;
+ bp->b_cflags = BC_BUSY;
+
+ error = (*sc->sc_discard)(sc, bp);
+ if (error == 0)
+ error = biowait(bp);
+
+ buf_destroy(bp);
+
+ if ((sc->sc_flags & LDF_MPSAFE) == 0)
+ KERNEL_UNLOCK_ONE(curlwp);
+
+ return error;
+}
+
+void
+lddiscardend(struct ld_softc *sc, struct buf *bp)
+{
+
+ if (bp->b_error)
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
}
static int
Index: src/sys/dev/ldvar.h
diff -u src/sys/dev/ldvar.h:1.30 src/sys/dev/ldvar.h:1.30.2.1
--- src/sys/dev/ldvar.h:1.30 Thu Apr 27 17:07:22 2017
+++ src/sys/dev/ldvar.h Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ldvar.h,v 1.30 2017/04/27 17:07:22 jdolecek Exp $ */
+/* $NetBSD: ldvar.h,v 1.30.2.1 2017/09/01 09:59:10 martin Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -61,18 +61,20 @@ struct ld_softc {
int (*sc_dump)(struct ld_softc *, void *, int, 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);
+ int (*sc_discard)(struct ld_softc *, struct buf *);
};
/* sc_flags */
#define LDF_ENABLED 0x001 /* device enabled */
#define LDF_DRAIN 0x020 /* maxqueuecnt has changed; drain */
#define LDF_NO_RND 0x040 /* do not attach rnd source */
+#define LDF_MPSAFE 0x080 /* backend is MPSAFE */
int ldadjqparam(struct ld_softc *, int);
void ldattach(struct ld_softc *, const char *);
int ldbegindetach(struct ld_softc *, int);
void ldenddetach(struct ld_softc *);
void lddone(struct ld_softc *, struct buf *);
+void lddiscardend(struct ld_softc *, struct buf *);
#endif /* !_DEV_LDVAR_H_ */
Index: src/sys/dev/i2o/ld_iop.c
diff -u src/sys/dev/i2o/ld_iop.c:1.37 src/sys/dev/i2o/ld_iop.c:1.37.6.1
--- src/sys/dev/i2o/ld_iop.c:1.37 Mon Feb 27 21:32:33 2017
+++ src/sys/dev/i2o/ld_iop.c Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_iop.c,v 1.37 2017/02/27 21:32:33 jdolecek Exp $ */
+/* $NetBSD: ld_iop.c,v 1.37.6.1 2017/09/01 09:59:10 martin 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.37 2017/02/27 21:32:33 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.37.6.1 2017/09/01 09:59:10 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -171,6 +171,7 @@ ld_iop_attach(device_t parent, device_t
ld->sc_dump = ld_iop_dump;
ld->sc_ioctl = ld_iop_ioctl;
ld->sc_start = ld_iop_start;
+ ld->sc_flags = LDF_MPSAFE;
/* Say what the device is. */
printf(":");
@@ -221,7 +222,7 @@ ld_iop_attach(device_t parent, device_t
if ((le32toh(param.p.bdi.capabilities) & I2O_RBS_CAP_REMOVABLE_MEDIA)
!= 0) {
- /* ld->sc_flags = LDF_REMOVABLE; */
+ /* ld->sc_flags |= LDF_REMOVABLE; */
fixedstr = "removable";
enable = 0;
} else
Index: src/sys/dev/ic/ld_cac.c
diff -u src/sys/dev/ic/ld_cac.c:1.30 src/sys/dev/ic/ld_cac.c:1.30.8.1
--- src/sys/dev/ic/ld_cac.c:1.30 Tue Sep 27 03:33:32 2016
+++ src/sys/dev/ic/ld_cac.c Fri Sep 1 09:59:11 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_cac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $ */
+/* $NetBSD: ld_cac.c,v 1.30.8.1 2017/09/01 09:59:11 martin Exp $ */
/*-
* Copyright (c) 2000, 2006 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.30 2016/09/27 03:33:32 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_cac.c,v 1.30.8.1 2017/09/01 09:59:11 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -131,7 +131,7 @@ ld_cac_attach(device_t parent, device_t
aprint_normal(": %s array\n", type);
/* XXX We should verify this... */
- ld->sc_flags = LDF_ENABLED;
+ ld->sc_flags = LDF_ENABLED | LDF_MPSAFE;
ldattach(ld, BUFQ_DISK_DEFAULT_STRAT);
}
Index: src/sys/dev/ic/ld_nvme.c
diff -u src/sys/dev/ic/ld_nvme.c:1.16 src/sys/dev/ic/ld_nvme.c:1.16.2.1
--- src/sys/dev/ic/ld_nvme.c:1.16 Thu Apr 27 17:07:22 2017
+++ src/sys/dev/ic/ld_nvme.c Fri Sep 1 09:59:11 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_nvme.c,v 1.16 2017/04/27 17:07:22 jdolecek Exp $ */
+/* $NetBSD: ld_nvme.c,v 1.16.2.1 2017/09/01 09:59:11 martin Exp $ */
/*-
* Copyright (C) 2016 NONAKA Kimihiro <[email protected]>
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.16 2017/04/27 17:07:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_nvme.c,v 1.16.2.1 2017/09/01 09:59:11 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -128,7 +128,7 @@ ld_nvme_attach(device_t parent, device_t
ld->sc_start = ld_nvme_start;
ld->sc_dump = ld_nvme_dump;
ld->sc_ioctl = ld_nvme_ioctl;
- ld->sc_flags = LDF_ENABLED | LDF_NO_RND;
+ ld->sc_flags = LDF_ENABLED | LDF_NO_RND | LDF_MPSAFE;
ldattach(ld, "fcfs");
}
Index: src/sys/dev/pci/ld_virtio.c
diff -u src/sys/dev/pci/ld_virtio.c:1.15 src/sys/dev/pci/ld_virtio.c:1.15.6.1
--- src/sys/dev/pci/ld_virtio.c:1.15 Sat Mar 25 18:02:06 2017
+++ src/sys/dev/pci/ld_virtio.c Fri Sep 1 09:59:11 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_virtio.c,v 1.15 2017/03/25 18:02:06 jdolecek Exp $ */
+/* $NetBSD: ld_virtio.c,v 1.15.6.1 2017/09/01 09:59:11 martin Exp $ */
/*
* Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.15 2017/03/25 18:02:06 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.15.6.1 2017/09/01 09:59:11 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -345,7 +345,7 @@ ld_virtio_attach(device_t parent, device
ld->sc_dump = ld_virtio_dump;
ld->sc_start = ld_virtio_start;
- ld->sc_flags = LDF_ENABLED;
+ ld->sc_flags = LDF_ENABLED | LDF_MPSAFE;
ldattach(ld, BUFQ_DISK_DEFAULT_STRAT);
return;
Index: src/sys/dev/sdmmc/ld_sdmmc.c
diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.26.4.4 src/sys/dev/sdmmc/ld_sdmmc.c:1.26.4.5
--- src/sys/dev/sdmmc/ld_sdmmc.c:1.26.4.4 Tue Jul 25 01:49:13 2017
+++ src/sys/dev/sdmmc/ld_sdmmc.c Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_sdmmc.c,v 1.26.4.4 2017/07/25 01:49:13 snj Exp $ */
+/* $NetBSD: ld_sdmmc.c,v 1.26.4.5 2017/09/01 09:59:10 martin Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.26.4.4 2017/07/25 01:49:13 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.26.4.5 2017/09/01 09:59:10 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -65,12 +65,16 @@ __KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v
#define LD_SDMMC_IORETRIES 5 /* number of retries before giving up */
#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */
+#define LD_SDMMC_MAXQUEUECNT 4 /* number of queued bio requests */
+#define LD_SDMMC_MAXTASKCNT 8 /* number of tasks in task pool */
+
struct ld_sdmmc_softc;
struct ld_sdmmc_task {
struct sdmmc_task task;
struct ld_sdmmc_softc *task_sc;
+
struct buf *task_bp;
int task_retries; /* number of xfer retry */
struct callout task_restart_ch;
@@ -81,9 +85,12 @@ struct ld_sdmmc_softc {
int sc_hwunit;
struct sdmmc_function *sc_sf;
-#define LD_SDMMC_MAXQUEUECNT 4
- struct ld_sdmmc_task sc_task[LD_SDMMC_MAXQUEUECNT];
+ struct ld_sdmmc_task sc_task[LD_SDMMC_MAXTASKCNT];
pcq_t *sc_freeq;
+
+ struct evcnt sc_ev_discard; /* discard counter */
+ struct evcnt sc_ev_discarderr; /* discard error counter */
+ struct evcnt sc_ev_discardbusy; /* discard busy counter */
};
static int ld_sdmmc_match(device_t, cfdata_t, void *);
@@ -93,11 +100,12 @@ static int ld_sdmmc_detach(device_t, int
static int ld_sdmmc_dump(struct ld_softc *, void *, int, int);
static int ld_sdmmc_start(struct ld_softc *, struct buf *);
static void ld_sdmmc_restart(void *);
-static int ld_sdmmc_discard(struct ld_softc *, off_t, off_t);
+static int ld_sdmmc_discard(struct ld_softc *, struct buf *);
static int ld_sdmmc_ioctl(struct ld_softc *, u_long, void *, int32_t, bool);
static void ld_sdmmc_doattach(void *);
static void ld_sdmmc_dobio(void *);
+static void ld_sdmmc_dodiscard(void *);
CFATTACH_DECL_NEW(ld_sdmmc, sizeof(struct ld_sdmmc_softc),
ld_sdmmc_match, ld_sdmmc_attach, ld_sdmmc_detach, NULL);
@@ -132,6 +140,13 @@ ld_sdmmc_attach(device_t parent, device_
sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt);
aprint_naive("\n");
+ evcnt_attach_dynamic(&sc->sc_ev_discard, EVCNT_TYPE_MISC,
+ NULL, device_xname(self), "sdmmc discard count");
+ evcnt_attach_dynamic(&sc->sc_ev_discarderr, EVCNT_TYPE_MISC,
+ NULL, device_xname(self), "sdmmc discard errors");
+ evcnt_attach_dynamic(&sc->sc_ev_discardbusy, EVCNT_TYPE_MISC,
+ NULL, device_xname(self), "sdmmc discard busy");
+
const int ntask = __arraycount(sc->sc_task);
sc->sc_freeq = pcq_create(ntask, KM_SLEEP);
for (i = 0; i < ntask; i++) {
@@ -144,7 +159,7 @@ ld_sdmmc_attach(device_t parent, device_
sc->sc_hwunit = 0; /* always 0? */
sc->sc_sf = sa->sf;
- ld->sc_flags = LDF_ENABLED;
+ ld->sc_flags = LDF_ENABLED | LDF_MPSAFE;
ld->sc_secperunit = sc->sc_sf->csd.capacity;
ld->sc_secsize = SDMMC_SECTOR_SIZE;
ld->sc_maxxfer = MAXPHYS;
@@ -208,6 +223,9 @@ ld_sdmmc_detach(device_t dev, int flags)
callout_destroy(&sc->sc_task[i].task_restart_ch);
pcq_destroy(sc->sc_freeq);
+ evcnt_detach(&sc->sc_ev_discard);
+ evcnt_detach(&sc->sc_ev_discarderr);
+ evcnt_detach(&sc->sc_ev_discardbusy);
return 0;
}
@@ -309,12 +327,51 @@ ld_sdmmc_dump(struct ld_softc *ld, void
blkcnt * ld->sc_secsize);
}
+static void
+ld_sdmmc_dodiscard(void *arg)
+{
+ struct ld_sdmmc_task *task = arg;
+ struct ld_sdmmc_softc *sc = task->task_sc;
+ struct buf *bp = task->task_bp;
+ uint32_t sblkno, nblks;
+ int error;
+
+ /* first and last block to erase */
+ sblkno = bp->b_rawblkno;
+ nblks = howmany(bp->b_bcount, sc->sc_ld.sc_secsize);
+
+ /* An error from discard is non-fatal */
+ error = sdmmc_mem_discard(sc->sc_sf, sblkno, sblkno + nblks - 1);
+ if (error != 0)
+ sc->sc_ev_discarderr.ev_count++;
+ else
+ sc->sc_ev_discard.ev_count++;
+ pcq_put(sc->sc_freeq, task);
+
+ if (error)
+ bp->b_error = error;
+
+ lddiscardend(&sc->sc_ld, bp);
+}
+
static int
-ld_sdmmc_discard(struct ld_softc *ld, off_t pos, off_t len)
+ld_sdmmc_discard(struct ld_softc *ld, struct buf *bp)
{
struct ld_sdmmc_softc *sc = device_private(ld->sc_dv);
+ struct ld_sdmmc_task *task = pcq_get(sc->sc_freeq);
+
+ if (task == NULL) {
+ sc->sc_ev_discardbusy.ev_count++;
+ return 0;
+ }
- return sdmmc_mem_discard(sc->sc_sf, pos, len);
+ task->task_bp = bp;
+
+ sdmmc_init_task(&task->task, ld_sdmmc_dodiscard, task);
+
+ sdmmc_add_task(sc->sc_sf->sc, &task->task);
+
+ return 0;
}
static int
Index: src/sys/dev/sdmmc/sdmmc_mem.c
diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.56.4.3 src/sys/dev/sdmmc/sdmmc_mem.c:1.56.4.4
--- src/sys/dev/sdmmc/sdmmc_mem.c:1.56.4.3 Tue Jul 25 01:49:13 2017
+++ src/sys/dev/sdmmc/sdmmc_mem.c Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sdmmc_mem.c,v 1.56.4.3 2017/07/25 01:49:13 snj Exp $ */
+/* $NetBSD: sdmmc_mem.c,v 1.56.4.4 2017/09/01 09:59:10 martin Exp $ */
/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */
/*
@@ -45,7 +45,7 @@
/* Routines for SD/MMC memory cards. */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.56.4.3 2017/07/25 01:49:13 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.56.4.4 2017/09/01 09:59:10 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -2152,7 +2152,7 @@ out:
}
int
-sdmmc_mem_discard(struct sdmmc_function *sf, off_t pos, off_t len)
+sdmmc_mem_discard(struct sdmmc_function *sf, uint32_t sblkno, uint32_t eblkno)
{
struct sdmmc_softc *sc = sf->sc;
struct sdmmc_command cmd;
@@ -2161,13 +2161,8 @@ sdmmc_mem_discard(struct sdmmc_function
if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE))
return ENODEV; /* XXX not tested */
- /* Erase what we can in the specified range. */
- const off_t start = roundup(pos, SDMMC_SECTOR_SIZE);
- const off_t end = rounddown(pos + len, SDMMC_SECTOR_SIZE) - 1;
- if (end < start)
+ if (eblkno < sblkno)
return EINVAL;
- const uint32_t sblkno = start / SDMMC_SECTOR_SIZE;
- const uint32_t eblkno = end / SDMMC_SECTOR_SIZE;
SDMMC_LOCK(sc);
mutex_enter(&sc->sc_mtx);
Index: src/sys/dev/sdmmc/sdmmcvar.h
diff -u src/sys/dev/sdmmc/sdmmcvar.h:1.23.6.3 src/sys/dev/sdmmc/sdmmcvar.h:1.23.6.4
--- src/sys/dev/sdmmc/sdmmcvar.h:1.23.6.3 Tue Jul 25 01:49:13 2017
+++ src/sys/dev/sdmmc/sdmmcvar.h Fri Sep 1 09:59:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sdmmcvar.h,v 1.23.6.3 2017/07/25 01:49:13 snj Exp $ */
+/* $NetBSD: sdmmcvar.h,v 1.23.6.4 2017/09/01 09:59:10 martin Exp $ */
/* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */
/*
@@ -381,7 +381,7 @@ int sdmmc_mem_read_block(struct sdmmc_fu
size_t);
int sdmmc_mem_write_block(struct sdmmc_function *, uint32_t, u_char *,
size_t);
-int sdmmc_mem_discard(struct sdmmc_function *, off_t, off_t);
+int sdmmc_mem_discard(struct sdmmc_function *, uint32_t, uint32_t);
int sdmmc_mem_flush_cache(struct sdmmc_function *, bool);
#endif /* _SDMMCVAR_H_ */