Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Oct 2008 22:22:25 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r184034 - head/sys/dev/mmc
Message-ID:  <200810182222.m9IMMPk4027184@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Oct 18 22:22:25 2008
New Revision: 184034
URL: http://svn.freebsd.org/changeset/base/184034

Log:
  Coalesce sequentional BIO_DELETE requests to slightly relax size and alignment
  constraints required by the card.

Modified:
  head/sys/dev/mmc/mmcsd.c

Modified: head/sys/dev/mmc/mmcsd.c
==============================================================================
--- head/sys/dev/mmc/mmcsd.c	Sat Oct 18 16:17:04 2008	(r184033)
+++ head/sys/dev/mmc/mmcsd.c	Sat Oct 18 22:22:25 2008	(r184034)
@@ -77,6 +77,7 @@ struct mmcsd_softc {
 	struct disk *disk;
 	struct proc *p;
 	struct bio_queue_head bio_queue;
+	daddr_t eblock, eend;	/* Range remaining after the last erase. */
 	int running;
 };
 
@@ -162,6 +163,7 @@ mmcsd_attach(device_t dev)
 	bioq_init(&sc->bio_queue);
 
 	sc->running = 1;
+	sc->eblock = sc->eend = 0;
 	kproc_create(&mmcsd_task, sc, &sc->p, 0, 0, "task: mmc/sd card");
 
 	return (0);
@@ -296,17 +298,23 @@ mmcsd_delete(struct mmcsd_softc *sc, str
 
 	block = bp->bio_pblkno;
 	end = bp->bio_pblkno + (bp->bio_bcount / sz);
-
+	/* Coalesce with part remaining from previous request. */
+	if (block > sc->eblock && block <= sc->eend)
+		block = sc->eblock;
+	if (end >= sc->eblock && end < sc->eend)
+		end = sc->eend;
 	/* Safe round to the erase sector boundaries. */
 	erase_sector = mmc_get_erase_sector(dev);
 	start = block + erase_sector - 1;	 /* Round up. */
 	start -= start % erase_sector;
 	stop = end;				/* Round down. */
 	stop -= end % erase_sector;	 
-
-	/* We can't erase areas smaller then sector. */
-	if (start >= stop)
+	/* We can't erase area smaller then sector, store it for later. */
+	if (start >= stop) {
+		sc->eblock = block;
+		sc->eend = end;
 		return (end);
+	}
 
 	/* Set erase start position. */
 	memset(&req, 0, sizeof(req));
@@ -358,7 +366,14 @@ mmcsd_delete(struct mmcsd_softc *sc, str
 	    printf("erase err3 %d\n", req.cmd->error);
 	    return (block);
 	}
-
+	/* Store one of remaining parts for the next call. */
+	if (bp->bio_pblkno >= sc->eblock || block == start) {
+		sc->eblock = stop;	/* Predict next forward. */
+		sc->eend = end;
+	} else {
+		sc->eblock = block;	/* Predict next backward. */
+		sc->eend = start;
+	}
 	return (end);
 }
 
@@ -396,12 +411,12 @@ mmcsd_task(void *arg)
 		block = bp->bio_pblkno;
 		end = bp->bio_pblkno + (bp->bio_bcount / sz);
 		if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
+			/* Access to the remaining erase block obsoletes it. */
+			if (block < sc->eend && end > sc->eblock)
+				sc->eblock = sc->eend = 0;
 			block = mmcsd_rw(sc, bp);
 		} else if (bp->bio_cmd == BIO_DELETE) {
 			block = mmcsd_delete(sc, bp);
-		} else {
-			/* UNSUPPORTED COMMAND */
-			block = bp->bio_pblkno;
 		}
 		MMCBUS_RELEASE_BUS(device_get_parent(dev), dev);
 		if (block < end) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810182222.m9IMMPk4027184>