[flashrom] [PATCH] Simplify chunking logic

Michael Karcher flashrom at mkarcher.dialup.fu-berlin.de
Sun Jul 11 18:42:57 CEST 2010


Read function tested for chunk size 62 and with start offset 3, works
as expected.

Signed-off-by: Michael Karcher <flashrom at mkarcher.dialup.fu-berlin.de>
---
 spi25.c |   80 +++++++++++++++++++++++++-------------------------------------
 1 files changed, 32 insertions(+), 48 deletions(-)

diff --git a/spi25.c b/spi25.c
index 51be397..260dd1c 100644
--- a/spi25.c
+++ b/spi25.c
@@ -879,35 +879,27 @@ int spi_nbyte_read(int address, uint8_t *bytes, int len)
 int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
 {
 	int rc = 0;
-	int i, j, starthere, lenhere;
+	int ofs, startofs, endofs;	/* offsets relative to page begin */
 	int page_size = flash->page_size;
-	int toread;
-
-	/* Warning: This loop has a very unusual condition and body.
-	 * The loop needs to go through each page with at least one affected
-	 * byte. The lowest page number is (start / page_size) since that
-	 * division rounds down. The highest page number we want is the page
-	 * where the last byte of the range lives. That last byte has the
-	 * address (start + len - 1), thus the highest page number is
-	 * (start + len - 1) / page_size. Since we want to include that last
-	 * page as well, the loop condition uses <=.
-	 */
-	for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
-		/* Byte position of the first byte in the range in this page. */
-		/* starthere is an offset to the base address of the chip. */
-		starthere = max(start, i * page_size);
-		/* Length of bytes in the range in this page. */
-		lenhere = min(start + len, (i + 1) * page_size) - starthere;
-		for (j = 0; j < lenhere; j += chunksize) {
-			toread = min(chunksize, lenhere - j);
-			rc = spi_nbyte_read(starthere + j, buf + starthere - start + j, toread);
+	int pageaddr, toread;
+
+	startofs = start % page_size;
+	/* iterate over all affected pages */
+	for (pageaddr = start - startofs; pageaddr < start + len;
+             pageaddr += page_size) {
+     		endofs = min(page_size, start + len - pageaddr);
+     		/*  iterate over all chunks in the current page */
+		for (ofs = startofs; ofs < endofs; ofs += chunksize) {
+			toread = min(chunksize, endofs - ofs);
+			rc = spi_nbyte_read(pageaddr + ofs, buf, toread);
+			buf += toread;
 			if (rc)
-				break;
+				goto leave_page_loop;
 		}
-		if (rc)
-			break;
+		startofs = 0;	/* all further pages processed from start */
 	}
 
+leave_page_loop:
 	return rc;
 }
 
@@ -918,42 +910,34 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
 int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
 {
 	int rc = 0;
-	int i, j, starthere, lenhere;
+	int ofs, startofs, endofs;	/* offsets relative to page begin */
 	/* FIXME: page_size is the wrong variable. We need max_writechunk_size
 	 * in struct flashchip to do this properly. All chips using
 	 * spi_chip_write_256 have page_size set to max_writechunk_size, so
 	 * we're OK for now.
 	 */
 	int page_size = flash->page_size;
-	int towrite;
-
-	/* Warning: This loop has a very unusual condition and body.
-	 * The loop needs to go through each page with at least one affected
-	 * byte. The lowest page number is (start / page_size) since that
-	 * division rounds down. The highest page number we want is the page
-	 * where the last byte of the range lives. That last byte has the
-	 * address (start + len - 1), thus the highest page number is
-	 * (start + len - 1) / page_size. Since we want to include that last
-	 * page as well, the loop condition uses <=.
-	 */
-	for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
-		/* Byte position of the first byte in the range in this page. */
-		/* starthere is an offset to the base address of the chip. */
-		starthere = max(start, i * page_size);
-		/* Length of bytes in the range in this page. */
-		lenhere = min(start + len, (i + 1) * page_size) - starthere;
-		for (j = 0; j < lenhere; j += chunksize) {
-			towrite = min(chunksize, lenhere - j);
-			rc = spi_nbyte_program(starthere + j, buf + starthere - start + j, towrite);
+	int pageaddr, towrite;
+
+	startofs = start % page_size;
+	/* iterate over all affected pages */
+	for (pageaddr = start - startofs; pageaddr < start + len;
+             pageaddr += page_size) {
+     		endofs = min(page_size, start + len - pageaddr);
+     		/*  iterate over all chunks in the current page */
+		for (ofs = startofs; ofs < endofs; ofs += chunksize) {
+			towrite = min(chunksize, endofs - ofs);
+			rc = spi_nbyte_program(pageaddr + ofs, buf, towrite);
+			buf += towrite;
 			if (rc)
-				break;
+				goto leave_page_loop;
 			while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
 				programmer_delay(10);
 		}
-		if (rc)
-			break;
+		startofs = 0;	/* all further pages processed from start */
 	}
 
+leave_page_loop:
 	return rc;
 }
 
-- 
1.7.1





More information about the flashrom mailing list