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 <non...@netbsd.org> @@ -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_ */