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_ */

Reply via email to