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

Signed-off-by: Michael Karcher <[email protected]>
---
 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


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to