Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jun 2012 22:28:53 GMT
From:      Brooks Davis <brooks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 212283 for review
Message-ID:  <201206042228.q54MSr4k026477@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@212283?ac=10

Change 212283 by brooks@brooks_ecr_current on 2012/06/04 22:28:34

	Alter rwatson's retry algorithm to try to fix any wrong 16-bit words
	with a single write during the first pass.  If we find any of these,
	do a single pass rescan as per normal and fall back to the prior
	whole buffer rewrite scheme on failure.
	
	With this change I make it to multi user mode with an single fixup
	instead of nearly 18k retrys in some cases with the full sector
	mode.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/sdcard/altera_sdcard_io.c#13 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/sdcard/altera_sdcard_io.c#13 (text+ko) ====

@@ -232,8 +232,8 @@
 altera_sdcard_write_rxtx_buffer(struct altera_sdcard_softc *sc, void *data,
     size_t len)
 {
-	u_int differences, i, retry_counter;
-	uint16_t v;
+	u_int corrections, differences, i, retry_counter;
+	uint16_t d, v;
 
 	KASSERT((uintptr_t)data % 2 == 0,
 	    ("%s: unaligned data %p", __func__, data));
@@ -252,12 +252,30 @@
 		 *
 		 * XXXRW: Do we want a limit counter for retries here?
 		 */
+recheck:
+		corrections = 0;
 		differences = 0;
 		if (altera_sdcard_verify_rxtx_writes) {
 			for (i = 0; i < ALTERA_SDCARD_SECTORSIZE; i += 2) {
 				v = bus_read_2(sc->as_res,
 				    ALTERA_SDCARD_OFF_RXTX_BUFFER + i);
-				if (v != *(uint16_t *)((uint8_t *)data + i)) {
+				d = *(uint16_t *)((uint8_t *)data + i);
+				if (v != d) {
+					if (retry_counter == 0) {
+						bus_write_2(sc->as_res,
+						    ALTERA_SDCARD_OFF_RXTX_BUFFER + i,
+						    d);
+						v = bus_read_2(sc->as_res,
+						    ALTERA_SDCARD_OFF_RXTX_BUFFER + i);
+						if (v == d) {
+							corrections++;
+							device_printf(sc->as_dev,
+							    "%s: single word rewrite worked"
+							    " at offset %u\n", 
+							    __func__, i);
+							continue;
+						}
+					}
 					differences++;
 					device_printf(sc->as_dev,
 					    "%s: retrying write -- difference"
@@ -266,8 +284,12 @@
 					    retry_counter);
 				}
 			}
-			if (differences)
+			if (differences != 0) {
 				retry_counter++;
+				if (retry_counter == 1 &&
+				    corrections == differences)
+					goto recheck;
+			}
 		}
 	} while (differences != 0);
 	if (retry_counter)



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