Module Name: src Committed By: mlelstv Date: Sun Aug 20 15:58:44 UTC 2017
Modified Files: src/sys/dev: ld.c ldvar.h src/sys/dev/sdmmc: ld_sdmmc.c sdmmc_mem.c sdmmcvar.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.102 -r1.103 src/sys/dev/ld.c cvs rdiff -u -r1.31 -r1.32 src/sys/dev/ldvar.h cvs rdiff -u -r1.33 -r1.34 src/sys/dev/sdmmc/ld_sdmmc.c cvs rdiff -u -r1.61 -r1.62 src/sys/dev/sdmmc/sdmmc_mem.c cvs rdiff -u -r1.28 -r1.29 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/ld.c diff -u src/sys/dev/ld.c:1.102 src/sys/dev/ld.c:1.103 --- src/sys/dev/ld.c:1.102 Wed Aug 9 16:44:39 2017 +++ src/sys/dev/ld.c Sun Aug 20 15:58:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld.c,v 1.102 2017/08/09 16:44:39 mlelstv Exp $ */ +/* $NetBSD: ld.c,v 1.103 2017/08/20 15:58:43 mlelstv 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.102 2017/08/09 16:44:39 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.103 2017/08/20 15:58:43 mlelstv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -595,22 +595,45 @@ static int ld_discard(device_t dev, off_t pos, off_t len) { struct ld_softc *sc = device_private(dev); - int rc; + struct buf dbuf, *bp = &dbuf; + int error = 0; + + KASSERT(len <= INT_MAX); if (sc->sc_discard == NULL) return (ENODEV); if ((sc->sc_flags & LDF_MPSAFE) == 0) KERNEL_LOCK(1, curlwp); - mutex_enter(&sc->sc_mutex); - rc = (*sc->sc_discard)(sc, pos, len); + 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); - mutex_exit(&sc->sc_mutex); if ((sc->sc_flags & LDF_MPSAFE) == 0) KERNEL_UNLOCK_ONE(curlwp); - return rc; + 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.31 src/sys/dev/ldvar.h:1.32 --- src/sys/dev/ldvar.h:1.31 Wed Aug 9 16:44:39 2017 +++ src/sys/dev/ldvar.h Sun Aug 20 15:58:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ldvar.h,v 1.31 2017/08/09 16:44:39 mlelstv Exp $ */ +/* $NetBSD: ldvar.h,v 1.32 2017/08/20 15:58:43 mlelstv Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ 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 */ @@ -75,5 +75,6 @@ void ldattach(struct ld_softc *, const c 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/sdmmc/ld_sdmmc.c diff -u src/sys/dev/sdmmc/ld_sdmmc.c:1.33 src/sys/dev/sdmmc/ld_sdmmc.c:1.34 --- src/sys/dev/sdmmc/ld_sdmmc.c:1.33 Fri Aug 11 18:41:42 2017 +++ src/sys/dev/sdmmc/ld_sdmmc.c Sun Aug 20 15:58:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ld_sdmmc.c,v 1.33 2017/08/11 18:41:42 jmcneill Exp $ */ +/* $NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.33 2017/08/11 18:41:42 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_sdmmc.h" @@ -75,14 +75,9 @@ struct ld_sdmmc_task { struct ld_sdmmc_softc *task_sc; - /* bio tasks */ struct buf *task_bp; int task_retries; /* number of xfer retry */ struct callout task_restart_ch; - - /* discard tasks */ - off_t task_pos; - off_t task_len; }; struct ld_sdmmc_softc { @@ -105,7 +100,7 @@ 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 *); @@ -342,22 +337,30 @@ ld_sdmmc_dodiscard(void *arg) { struct ld_sdmmc_task *task = arg; struct ld_sdmmc_softc *sc = task->task_sc; - const off_t pos = task->task_pos; - const off_t len = task->task_len; + 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, pos, len); + 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); @@ -367,8 +370,7 @@ ld_sdmmc_discard(struct ld_softc *ld, of return 0; } - task->task_pos = pos; - task->task_len = len; + task->task_bp = bp; sdmmc_init_task(&task->task, ld_sdmmc_dodiscard, task); Index: src/sys/dev/sdmmc/sdmmc_mem.c diff -u src/sys/dev/sdmmc/sdmmc_mem.c:1.61 src/sys/dev/sdmmc/sdmmc_mem.c:1.62 --- src/sys/dev/sdmmc/sdmmc_mem.c:1.61 Sun Jul 16 17:11:46 2017 +++ src/sys/dev/sdmmc/sdmmc_mem.c Sun Aug 20 15:58:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmc_mem.c,v 1.61 2017/07/16 17:11:46 jmcneill Exp $ */ +/* $NetBSD: sdmmc_mem.c,v 1.62 2017/08/20 15:58:43 mlelstv 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.61 2017/07/16 17:11:46 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.62 2017/08/20 15:58:43 mlelstv 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.28 src/sys/dev/sdmmc/sdmmcvar.h:1.29 --- src/sys/dev/sdmmc/sdmmcvar.h:1.28 Sun Jul 16 17:11:46 2017 +++ src/sys/dev/sdmmc/sdmmcvar.h Sun Aug 20 15:58:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sdmmcvar.h,v 1.28 2017/07/16 17:11:46 jmcneill Exp $ */ +/* $NetBSD: sdmmcvar.h,v 1.29 2017/08/20 15:58:43 mlelstv 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_ */