[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