The following patches (attached and in-lined below) add support for "graceful" handling of certain errors and in particular the read/write errors that occur on newer Intel chipsets. With a little work, it could be extended to handle SPI hardware write protection schema, too.<div>

<br></div><div>Note: I think we should probably add a "I_want_a_brick" programmer parameter for those daring enough to try this. I suspect certain OEM tools use unknown <a href="http://support.dell.com/support/edocs/systems/latd630/en/amt/MEBX.htm">Mebx commands</a> to disable ME read/write protection when they do updates. Perhaps that stuff can be added later as a board_enable thing.<br>

<div><br></div><div>The impetus for this is to overcome difficulties in dealing with new Intel platforms which use their flash descriptor layout, like this (using Pontus' H57 verbose output):</div><div><div><font face="'courier new', monospace">0x54: 0x00000000 (FREG0: Flash Descriptor)</font></div>

<div><font face="'courier new', monospace">0x00000000-0x00000fff is read-only</font></div><div><font face="'courier new', monospace">0x58: 0x07ff0600 (FREG1: BIOS)</font></div><div><font face="'courier new', monospace">0x00600000-0x007fffff is read-write</font></div>

<div><font face="'courier new', monospace">0x5C: 0x05ff0001 (FREG2: Management Engine)</font></div><div><font face="'courier new', monospace">0x00001000-0x005fffff is locked</font></div><div><font face="'courier new', monospace">0x60: 0x00000fff (FREG3: Gigabit Ethernet)</font></div>

<div><font face="'courier new', monospace">Gigabit Ethernet region is unused.</font></div><div><font face="'courier new', monospace">0x64: 0x00000fff (FREG4: Platform Data)</font></div><div><font face="'courier new', monospace">Platform Data region is unused.</font></div>

</div><div><br></div><div>In this case, the flashrom will abort due to a transaction error when it attempts to read or write offsets 0x001000-0x05fffff, or when it attempt to write new content to 0x000000-0x000fff.</div>
<div>
<br></div><div>With the patches applied, the low-level ICH code will handle all the details of checking the address associated with an opcode against the permissions set in the flash descriptor. If an operation cannot be performed on a given region, an error code is propagated up the stack so that high-level read/write logic can decide to skip that region. As is, the patch will make the high-level logic fill in unreadable regions with 0xff bytes (for reads) and will quietly skip over unwriteable regions (for writes).</div>

<div><br></div><div>The biggest downside is, of course, that read/write operations no longer do exactly what one might expect. A full read operation (flashrom -r) will give you a ROM-sized image with 0xff bytes wherever read is forbidden (e.g. where the management engine firmware lives). A full write operation will skip forbidden regions (e.g. flash descriptor and ME) which may leave stuff in an inconsistent and potentially unusable state (thanks, Intel!).</div>

<div><br></div><div>Signed-off-by: David Hendricks <<a href="mailto:dhendrix@google.com">dhendrix@google.com</a>></div><div><div><div><div><br></div><div><div><font face="'courier new', monospace">1-3_error_handling_helper_function.diff:</font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/flash.h</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/flash.h</font></div><div><font face="'courier new', monospace">+++ flashrom-me/flash.h</font></div><div><font face="'courier new', monospace">@@ -226,12 +226,25 @@ int write_buf_to_file(unsigned char *buf</font></div>

<div><font face="'courier new', monospace"> #define OK 0</font></div><div><font face="'courier new', monospace"> #define NT 1    /* Not tested */</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">+/* what to do in case of an error */</font></div><div><font face="'courier new', monospace">+enum error_action {</font></div><div><font face="'courier new', monospace">+       error_fail,     /* fail immediately */</font></div>

<div><font face="'courier new', monospace">+       error_ignore,   /* non-fatal error; continue */</font></div><div><font face="'courier new', monospace">+};</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace"> /* Something happened that shouldn't happen, but we can go on. */</font></div><div><font face="'courier new', monospace"> #define ERROR_NONFATAL 0x100</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> /* Something happened that shouldn't happen, we'll abort. */</font></div><div><font face="'courier new', monospace"> #define ERROR_FATAL -0xee</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">+/* Operation failed due to access restriction set in programmer or flash chip */</font></div><div><font face="'courier new', monospace">+#define ACCESS_DENIED -7</font></div>

<div><font face="'courier new', monospace">+extern enum error_action access_denied_action;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+/* convenience function for checking return codes */</font></div>

<div><font face="'courier new', monospace">+extern int ignore_error(int x);</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace"> /* cli_output.c */</font></div>

<div><font face="'courier new', monospace"> /* Let gcc and clang check for correct printf-style format strings. */</font></div><div><font face="'courier new', monospace"> int print(int type, const char *fmt, ...) __attribute__((format(printf, 2, 3)));</font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/flashrom.c</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/flashrom.c</font></div><div><font face="'courier new', monospace">+++ flashrom-me/flashrom.c</font></div><div><font face="'courier new', monospace">@@ -42,6 +42,25 @@ const char flashrom_version[] = FLASHROM</font></div>

<div><font face="'courier new', monospace"> char *chip_to_probe = NULL;</font></div><div><font face="'courier new', monospace"> int verbose = 0;</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">+/* error handling stuff */</font></div><div><font face="'courier new', monospace">+enum error_action access_denied_action = error_ignore;</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+/* returns boolean (1 if caller should ignore error code, 0 if not) */</font></div><div><font face="'courier new', monospace">+int ignore_error(int err) {</font></div>

<div><font face="'courier new', monospace">+       int ret = 0;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+       switch(err) {</font></div>

<div><font face="'courier new', monospace">+       case ACCESS_DENIED:</font></div><div><font face="'courier new', monospace">+               if (access_denied_action == error_ignore)</font></div><div><font face="'courier new', monospace">+                       ret = 1;</font></div>

<div><font face="'courier new', monospace">+               break;</font></div><div><font face="'courier new', monospace">+       default:</font></div><div><font face="'courier new', monospace">+               break;</font></div>

<div><font face="'courier new', monospace">+       }</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+       return ret;</font></div>

<div><font face="'courier new', monospace">+}</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace"> static enum programmer programmer = PROGRAMMER_INVALID;</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> static char *programmer_param = NULL;</font></div><div><font face="'courier new', monospace"><br>

</font></div><div><font face="'courier new', monospace">2-3_update_spi_error_handling.diff:</font></div><div><font face="'courier new', monospace">Index: flashrom-me/spi.c</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/spi.c</font></div><div><font face="'courier new', monospace">+++ flashrom-me/spi.c</font></div><div><font face="'courier new', monospace">@@ -100,25 +100,35 @@ int default_spi_send_multicommand(struct</font></div>

<div><font face="'courier new', monospace"> int default_spi_read(struct flashchip *flash, uint8_t *buf, unsigned int start, unsigned int len)</font></div><div><font face="'courier new', monospace"> {</font></div>

<div><font face="'courier new', monospace">        unsigned int max_data = spi_programmer->max_data_read;</font></div><div><font face="'courier new', monospace">+       int ret;</font></div><div><font face="'courier new', monospace">        if (max_data == MAX_DATA_UNSPECIFIED) {</font></div>

<div><font face="'courier new', monospace">                msg_perr("%s called, but SPI read chunk size not defined "</font></div><div><font face="'courier new', monospace">                         "on this hardware. Please report a bug at "</font></div>

<div><font face="'courier new', monospace">                         "<a href="mailto:flashrom@flashrom.org">flashrom@flashrom.org</a>\n", __func__);</font></div><div><font face="'courier new', monospace">                return 1;</font></div>

<div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">-       return spi_read_chunked(flash, buf, start, len, max_data);</font></div><div><font face="'courier new', monospace">+       rc = spi_read_chunked(flash, buf, start, len, max_data);</font></div>

<div><font face="'courier new', monospace">+       /* translate SPI-specific access denied error to generic error */</font></div><div><font face="'courier new', monospace">+       if (ret == SPI_ACCESS_DENIED)</font></div>

<div><font face="'courier new', monospace">+               rc = ACCESS_DENIED;</font></div><div><font face="'courier new', monospace">+       return ret;</font></div><div><font face="'courier new', monospace"> }</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> int default_spi_write_256(struct flashchip *flash, uint8_t *buf, unsigned int start, unsigned int len)</font></div>

<div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">        unsigned int max_data = spi_programmer->max_data_write;</font></div><div><font face="'courier new', monospace">+       int ret;</font></div>

<div><font face="'courier new', monospace">        if (max_data == MAX_DATA_UNSPECIFIED) {</font></div><div><font face="'courier new', monospace">                msg_perr("%s called, but SPI write chunk size not defined "</font></div>

<div><font face="'courier new', monospace">                         "on this hardware. Please report a bug at "</font></div><div><font face="'courier new', monospace">                         "<a href="mailto:flashrom@flashrom.org">flashrom@flashrom.org</a>\n", __func__);</font></div>

<div><font face="'courier new', monospace">                return 1;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">-       return spi_write_chunked(flash, buf, start, len, max_data);</font></div>

<div><font face="'courier new', monospace">+       ret = spi_write_chunked(flash, buf, start, len, max_data);</font></div><div><font face="'courier new', monospace">+       /* translate SPI-specific access denied error to generic error */</font></div>

<div><font face="'courier new', monospace">+       if (ret == SPI_ACCESS_DENIED)</font></div><div><font face="'courier new', monospace">+               ret = ACCESS_DENIED;</font></div><div><font face="'courier new', monospace">+       return ret;</font></div>

<div><font face="'courier new', monospace"> }</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> int spi_chip_read(struct flashchip *flash, uint8_t *buf, unsigned int start, unsigned int len)</font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/spi.h</font></div><div><font face="'courier new', monospace">===================================================================</font></div><div>

<font face="'courier new', monospace">--- flashrom-me.orig/spi.h</font></div><div><font face="'courier new', monospace">+++ flashrom-me/spi.h</font></div><div><font face="'courier new', monospace">@@ -125,5 +125,6 @@</font></div>

<div><font face="'courier new', monospace"> #define SPI_INVALID_LENGTH     -4</font></div><div><font face="'courier new', monospace"> #define SPI_FLASHROM_BUG       -5</font></div><div><font face="'courier new', monospace"> #define SPI_PROGRAMMER_ERROR   -6</font></div>

<div><font face="'courier new', monospace">+#define SPI_ACCESS_DENIED      -7</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> #endif         /* !__SPI_H__ */</font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/spi25.c</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/spi25.c</font></div><div><font face="'courier new', monospace">+++ flashrom-me/spi25.c</font></div><div><font face="'courier new', monospace">@@ -916,8 +916,10 @@ int spi_nbyte_program(unsigned int addr,</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">        result = spi_send_multicommand(cmds);</font></div><div><font face="'courier new', monospace">        if (result) {</font></div>

<div><font face="'courier new', monospace">-               msg_cerr("%s failed during command execution at address 0x%x\n",</font></div><div><font face="'courier new', monospace">-                       __func__, addr);</font></div>

<div><font face="'courier new', monospace">+               if (result != SPI_ACCESS_DENIED) {</font></div><div><font face="'courier new', monospace">+                       msg_cerr("%s failed during command execution at address 0x%x\n",</font></div>

<div><font face="'courier new', monospace">+                               __func__, addr);</font></div><div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">        }</font></div>

<div><font face="'courier new', monospace">        return result;</font></div><div><font face="'courier new', monospace"> }</font></div><div><font face="'courier new', monospace">@@ -970,7 +972,7 @@ int spi_nbyte_read(unsigned int address,</font></div>

<div><font face="'courier new', monospace">  */</font></div><div><font face="'courier new', monospace"> int spi_read_chunked(struct flashchip *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize)</font></div>

<div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">-       int rc = 0;</font></div><div><font face="'courier new', monospace">+       int rc = 0, chunk_status = 0;</font></div>

<div><font face="'courier new', monospace">        unsigned int i, j, starthere, lenhere, toread;</font></div><div><font face="'courier new', monospace">        unsigned int page_size = flash->page_size;</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">@@ -990,12 +992,26 @@ int spi_read_chunked(struct flashchip *f</font></div><div><font face="'courier new', monospace">                /* Length of bytes in the range in this page. */</font></div>

<div><font face="'courier new', monospace">                lenhere = min(start + len, (i + 1) * page_size) - starthere;</font></div><div><font face="'courier new', monospace">                for (j = 0; j < lenhere; j += chunksize) {</font></div>

<div><font face="'courier new', monospace">+                       uint8_t *bytes = buf + starthere - start + j;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">                        toread = min(chunksize, lenhere - j);</font></div>

<div><font face="'courier new', monospace">-                       rc = spi_nbyte_read(starthere + j, buf + starthere - start + j, toread);</font></div><div><font face="'courier new', monospace">-                       if (rc)</font></div>

<div><font face="'courier new', monospace">-                               break;</font></div><div><font face="'courier new', monospace">+                       chunk_status = spi_nbyte_read(starthere + j, bytes, toread);</font></div>

<div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+                       if (chunk_status) {</font></div><div><font face="'courier new', monospace">+                               if (ignore_error(chunk_status)) {</font></div>

<div><font face="'courier new', monospace">+                                       /* fill this chunk with 0xff bytes and</font></div><div><font face="'courier new', monospace">+                                          let caller know about the error */</font></div>

<div><font face="'courier new', monospace">+                                       memset(bytes, 0xff, toread);</font></div><div><font face="'courier new', monospace">+                                       rc = chunk_status;</font></div>

<div><font face="'courier new', monospace">+                                       chunk_status = 0;</font></div><div><font face="'courier new', monospace">+                                       continue;</font></div>

<div><font face="'courier new', monospace">+                               } else {</font></div><div><font face="'courier new', monospace">+                                       rc = chunk_status;</font></div>

<div><font face="'courier new', monospace">+                                       break;</font></div><div><font face="'courier new', monospace">+                               }</font></div><div><font face="'courier new', monospace">+                       }</font></div>

<div><font face="'courier new', monospace">                }</font></div><div><font face="'courier new', monospace">-               if (rc)</font></div><div><font face="'courier new', monospace">+               if (chunk_status)</font></div>

<div><font face="'courier new', monospace">                        break;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/flashrom.c</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/flashrom.c</font></div><div><font face="'courier new', monospace">+++ flashrom-me/flashrom.c</font></div><div><font face="'courier new', monospace">@@ -583,6 +583,7 @@ int verify_range(struct flashchip *flash</font></div>

<div><font face="'courier new', monospace">        unsigned int i;</font></div><div><font face="'courier new', monospace">        uint8_t *readbuf = malloc(len);</font></div><div><font face="'courier new', monospace">        int ret = 0, failcount = 0;</font></div>

<div><font face="'courier new', monospace">+       unsigned int chunksize;</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">        if (!len)</font></div>

<div><font face="'courier new', monospace">                goto out_free;</font></div><div><font face="'courier new', monospace">@@ -606,23 +607,35 @@ int verify_range(struct flashchip *flash</font></div>
<div>
<font face="'courier new', monospace">        if (!message)</font></div><div><font face="'courier new', monospace">                message = "VERIFY";</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">-       ret = flash->read(flash, readbuf, start, len);</font></div><div><font face="'courier new', monospace">-       if (ret) {</font></div><div><font face="'courier new', monospace">-               msg_gerr("Verification impossible because read failed "</font></div>

<div><font face="'courier new', monospace">-                        "at 0x%x (len 0x%x)\n", start, len);</font></div><div><font face="'courier new', monospace">-               return ret;</font></div>

<div><font face="'courier new', monospace">-       }</font></div><div><font face="'courier new', monospace">+       chunksize = min(flash->page_size, len);</font></div><div><font face="'courier new', monospace">+       for (i = 0; i < len; i += chunksize) {</font></div>

<div><font face="'courier new', monospace">+               int tmp, j;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+               tmp = flash->read(flash, readbuf + i, start + i, chunksize);</font></div>

<div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+               if (tmp) {</font></div><div><font face="'courier new', monospace">+                       ret = tmp;</font></div>

<div><font face="'courier new', monospace">+                       if (ignore_error(tmp)) {</font></div><div><font face="'courier new', monospace">+                               chunksize = min(flash->page_size, len - i);</font></div>

<div><font face="'courier new', monospace">+                               continue;</font></div><div><font face="'courier new', monospace">+                       } else {</font></div><div><font face="'courier new', monospace">+                               goto out_free;</font></div>

<div><font face="'courier new', monospace">+                       }</font></div><div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">-       for (i = 0; i < len; i++) {</font></div><div><font face="'courier new', monospace">-               if (cmpbuf[i] != readbuf[i]) {</font></div><div><font face="'courier new', monospace">-                       /* Only print the first failure. */</font></div>

<div><font face="'courier new', monospace">-                       if (!failcount++)</font></div><div><font face="'courier new', monospace">-                               msg_cerr("%s FAILED at 0x%08x! "</font></div>

<div><font face="'courier new', monospace">-                                        "Expected=0x%02x, Read=0x%02x,",</font></div><div><font face="'courier new', monospace">-                                        message, start + i, cmpbuf[i],</font></div>

<div><font face="'courier new', monospace">-                                        readbuf[i]);</font></div><div><font face="'courier new', monospace">+               for (j = 0; j < chunksize; j++) {</font></div>

<div><font face="'courier new', monospace">+                       if (cmpbuf[i + j] != readbuf[i + j]) {</font></div><div><font face="'courier new', monospace">+                               /* Only print the first failure. */</font></div>

<div><font face="'courier new', monospace">+                               if (!failcount++)</font></div><div><font face="'courier new', monospace">+                                       msg_cerr("%s FAILED at 0x%08x! "</font></div>

<div><font face="'courier new', monospace">+                                                "Expected=0x%02x, Read=0x%02x,",</font></div><div><font face="'courier new', monospace">+                                                message, start + i + j, cmpbuf[i + j],</font></div>

<div><font face="'courier new', monospace">+                                                readbuf[j]);</font></div><div><font face="'courier new', monospace">+                       }</font></div><div><font face="'courier new', monospace">                }</font></div>

<div><font face="'courier new', monospace">+               chunksize = min(flash->page_size, len - i);</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">        if (failcount) {</font></div><div><font face="'courier new', monospace">                msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",</font></div>

<div><font face="'courier new', monospace">                         start, start + len - 1, failcount);</font></div><div><font face="'courier new', monospace">@@ -1057,6 +1070,16 @@ int verify_flash(struct flashchip *flash</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">        ret = verify_range(flash, buf, 0, total_size, NULL);</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">+       if (ret == ACCESS_DENIED) {</font></div><div><font face="'courier new', monospace">+               msg_gdbg("Could not fully verify due to access error, ");</font></div>

<div><font face="'courier new', monospace">+               if (access_denied_action == error_ignore) {</font></div><div><font face="'courier new', monospace">+                       msg_gdbg("ignoring\n");</font></div>

<div><font face="'courier new', monospace">+                       ret = 0;</font></div><div><font face="'courier new', monospace">+               } else {</font></div><div><font face="'courier new', monospace">+                       msg_gdbg("aborting\n");</font></div>

<div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">+       }</font></div><div><font face="'courier new', monospace">+</font></div><div>

<font face="'courier new', monospace">        if (!ret)</font></div><div><font face="'courier new', monospace">                msg_cinfo("VERIFIED.          \n");</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">@@ -1139,10 +1162,15 @@ int read_flash_to_file(struct flashchip </font></div><div><font face="'courier new', monospace">                ret = 1;</font></div><div>

<font face="'courier new', monospace">                goto out_free;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">-       if (flash->read(flash, buf, 0, size)) {</font></div>

<div><font face="'courier new', monospace">-               msg_cerr("Read operation failed!\n");</font></div><div><font face="'courier new', monospace">-               ret = 1;</font></div><div>
<font face="'courier new', monospace">-               goto out_free;</font></div>
<div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+       ret = flash->read(flash, buf, 0, size);</font></div><div><font face="'courier new', monospace">+       if (ret) {</font></div>

<div><font face="'courier new', monospace">+               if (ignore_error(ret)) {</font></div><div><font face="'courier new', monospace">+                       ret = 0;</font></div><div><font face="'courier new', monospace">+               } else {</font></div>

<div><font face="'courier new', monospace">+                       msg_cerr("Read operation failed!\n");</font></div><div><font face="'courier new', monospace">+                       goto out_free;</font></div>

<div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> </font></div><div>

<font face="'courier new', monospace">        ret = write_buf_to_file(buf, size, filename);</font></div><div><font face="'courier new', monospace">@@ -1243,8 +1271,14 @@ static int erase_and_write_block_helper(</font></div>

<div><font face="'courier new', monospace">        if (need_erase(curcontents, newcontents, len, gran)) {</font></div><div><font face="'courier new', monospace">                msg_cdbg("E");</font></div>

<div><font face="'courier new', monospace">                ret = erasefn(flash, start, len);</font></div><div><font face="'courier new', monospace">-               if (ret)</font></div><div><font face="'courier new', monospace">+               if (ret) {</font></div>

<div><font face="'courier new', monospace">+                       if (ret == ACCESS_DENIED)</font></div><div><font face="'courier new', monospace">+                               msg_cdbg("D");</font></div>

<div><font face="'courier new', monospace">+                       else</font></div><div><font face="'courier new', monospace">+                               msg_cerr("ERASE FAILED!\n");</font></div>

<div><font face="'courier new', monospace">                        return ret;</font></div><div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">                if (check_erased_range(flash, start, len)) {</font></div><div><font face="'courier new', monospace">                        msg_cerr("ERASE FAILED!\n");</font></div>

<div><font face="'courier new', monospace">                        return -1;</font></div><div><font face="'courier new', monospace">@@ -1262,8 +1296,11 @@ static int erase_and_write_block_helper(</font></div>

<div><font face="'courier new', monospace">                /* Needs the partial write function signature. */</font></div><div><font face="'courier new', monospace">                ret = flash->write(flash, newcontents + starthere,</font></div>

<div><font face="'courier new', monospace">                                   start + starthere, lenhere);</font></div><div><font face="'courier new', monospace">-               if (ret)</font></div><div>
<font face="'courier new', monospace">+               if (ret) {</font></div>
<div><font face="'courier new', monospace">+                       if (ret == ACCESS_DENIED)</font></div><div><font face="'courier new', monospace">+                               msg_cdbg("D");</font></div>

<div><font face="'courier new', monospace">                        return ret;</font></div><div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">                starthere += lenhere;</font></div>

<div><font face="'courier new', monospace">                skip = 0;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">@@ -1284,7 +1321,7 @@ static int walk_eraseregions(struct flas</font></div>

<div><font face="'courier new', monospace">                                                        unsigned int len)),</font></div><div><font face="'courier new', monospace">                             void *param1, void *param2)</font></div>

<div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">-       int i, j;</font></div><div><font face="'courier new', monospace">+       int i, j, ret = 0;</font></div>

<div><font face="'courier new', monospace">        unsigned int start = 0;</font></div><div><font face="'courier new', monospace">        unsigned int len;</font></div><div><font face="'courier new', monospace">        struct block_eraser eraser = flash->block_erasers[erasefunction];</font></div>

<div><font face="'courier new', monospace">@@ -1300,15 +1337,19 @@ static int walk_eraseregions(struct flas</font></div><div><font face="'courier new', monospace">                                msg_cdbg(", ");</font></div>

<div><font face="'courier new', monospace">                        msg_cdbg("0x%06x-0x%06x", start,</font></div><div><font face="'courier new', monospace">                                     start + len - 1);</font></div>

<div><font face="'courier new', monospace">-                       if (do_something(flash, start, len, param1, param2,</font></div><div><font face="'courier new', monospace">-                                        eraser.block_erase)) {</font></div>

<div><font face="'courier new', monospace">-                               return 1;</font></div><div><font face="'courier new', monospace">+                       ret = do_something(flash, start, len, param1, param2,</font></div>

<div><font face="'courier new', monospace">+                                          eraser.block_erase);</font></div><div><font face="'courier new', monospace">+                       if (ret) {</font></div>

<div><font face="'courier new', monospace">+                               if (ignore_error(ret))</font></div><div><font face="'courier new', monospace">+                                       ret = 0;</font></div>

<div><font face="'courier new', monospace">+                               else</font></div><div><font face="'courier new', monospace">+                                       return ret;</font></div><div>
<font face="'courier new', monospace">                        }</font></div>
<div><font face="'courier new', monospace">                        start += len;</font></div><div><font face="'courier new', monospace">                }</font></div><div><font face="'courier new', monospace">        }</font></div>

<div><font face="'courier new', monospace">        msg_cdbg("\n");</font></div><div><font face="'courier new', monospace">-       return 0;</font></div><div><font face="'courier new', monospace">+       return ret;</font></div>

<div><font face="'courier new', monospace"> }</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> static int check_block_eraser(const struct flashchip *flash, int k, int log)</font></div>

<div><font face="'courier new', monospace">@@ -1695,7 +1736,7 @@ int doit(struct flashchip *flash, int fo</font></div><div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">        uint8_t *oldcontents;</font></div>

<div><font face="'courier new', monospace">        uint8_t *newcontents;</font></div><div><font face="'courier new', monospace">-       int ret = 0;</font></div><div><font face="'courier new', monospace">+       int ret = 0, tmp;</font></div>

<div><font face="'courier new', monospace">        unsigned long size = flash->total_size * 1024;</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">        if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) {</font></div>

<div><font face="'courier new', monospace">@@ -1768,10 +1809,15 @@ int doit(struct flashchip *flash, int fo</font></div><div><font face="'courier new', monospace">         * takes time as well.</font></div>

<div><font face="'courier new', monospace">         */</font></div><div><font face="'courier new', monospace">        msg_cinfo("Reading old flash chip contents... ");</font></div><div><font face="'courier new', monospace">-       if (flash->read(flash, oldcontents, 0, size)) {</font></div>

<div><font face="'courier new', monospace">-               ret = 1;</font></div><div><font face="'courier new', monospace">-               msg_cinfo("FAILED.\n");</font></div><div><font face="'courier new', monospace">-               goto out;</font></div>

<div><font face="'courier new', monospace">+       tmp = flash->read(flash, oldcontents, 0, size);</font></div><div><font face="'courier new', monospace">+       if (tmp) {</font></div><div><font face="'courier new', monospace">+               if (ignore_error(tmp)) {</font></div>

<div><font face="'courier new', monospace">+                       msg_gdbg("ignoring error\n");</font></div><div><font face="'courier new', monospace">+               } else {</font></div><div>
<font face="'courier new', monospace">+                       ret = 1;</font></div>
<div><font face="'courier new', monospace">+                       msg_cinfo("FAILED.\n");</font></div><div><font face="'courier new', monospace">+                       goto out;</font></div><div>

<font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace">        msg_cinfo("done.\n");</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"><br></font></div><div><font face="'courier new', monospace">3-3_ichspi_deal_with_locked_regions.diff:</font></div>

<div><font face="'courier new', monospace">Index: flashrom-me/ichspi.c</font></div><div><font face="'courier new', monospace">===================================================================</font></div>

<div><font face="'courier new', monospace">--- flashrom-me.orig/ichspi.c</font></div><div><font face="'courier new', monospace">+++ flashrom-me/ichspi.c</font></div><div><font face="'courier new', monospace">@@ -983,6 +983,95 @@ static int run_opcode(OPCODE op, uint32_</font></div>

<div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> }</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">+#define DEFAULT_NUM_FD_REGIONS 5</font></div>

<div><font face="'courier new', monospace">+static int num_fd_regions;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+const char *const region_names[] = {</font></div>

<div><font face="'courier new', monospace">+       "Flash Descriptor", "BIOS", "Management Engine",</font></div><div><font face="'courier new', monospace">+       "Gigabit Ethernet", "Platform Data"</font></div>

<div><font face="'courier new', monospace">+};</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+enum fd_access_level {</font></div><div>

<font face="'courier new', monospace">+       FD_REGION_LOCKED,</font></div><div><font face="'courier new', monospace">+       FD_REGION_READ_ONLY,</font></div><div><font face="'courier new', monospace">+       FD_REGION_WRITE_ONLY,</font></div>

<div><font face="'courier new', monospace">+       FD_REGION_READ_WRITE,</font></div><div><font face="'courier new', monospace">+};</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+struct fd_region_permission {</font></div><div><font face="'courier new', monospace">+       enum fd_access_level level;</font></div><div><font face="'courier new', monospace">+       const char *name;</font></div>

<div><font face="'courier new', monospace">+} fd_region_permissions[] = {</font></div><div><font face="'courier new', monospace">+       /* order corresponds to FRAP bitfield */</font></div><div><font face="'courier new', monospace">+       { FD_REGION_LOCKED, "locked" },</font></div>

<div><font face="'courier new', monospace">+       { FD_REGION_READ_ONLY, "read-only" },</font></div><div><font face="'courier new', monospace">+       { FD_REGION_WRITE_ONLY, "write-only" },</font></div>

<div><font face="'courier new', monospace">+       { FD_REGION_READ_WRITE, "read-write" },</font></div><div><font face="'courier new', monospace">+};</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+/* FIXME: Replace usage of access_names with the region_access struct */</font></div><div><font face="'courier new', monospace">+const char *const access_names[4] = {</font></div>

<div><font face="'courier new', monospace">+       "locked", "read-only", "write-only", "read-write"</font></div><div><font face="'courier new', monospace">+};</font></div>

<div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+struct fd_region {</font></div><div><font face="'courier new', monospace">+       const char *name;</font></div>

<div><font face="'courier new', monospace">+       struct fd_region_permission *permission;</font></div><div><font face="'courier new', monospace">+       uint32_t base;</font></div><div><font face="'courier new', monospace">+       uint32_t limit;</font></div>

<div><font face="'courier new', monospace">+} fd_regions[] = {</font></div><div><font face="'courier new', monospace">+       /* order corresponds to flash descriptor */</font></div><div><font face="'courier new', monospace">+       { .name = "Flash Descriptor" },</font></div>

<div><font face="'courier new', monospace">+       { .name = "BIOS" },</font></div><div><font face="'courier new', monospace">+       { .name = "Management Engine" },</font></div><div>
<font face="'courier new', monospace">+       { .name = "Gigabit Ethernet" },</font></div>
<div><font face="'courier new', monospace">+       { .name = "Platform Data" },</font></div><div><font face="'courier new', monospace">+};</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+static int check_fd_permissions(OPCODE *opcode, uint32_t addr, int count)</font></div><div><font face="'courier new', monospace">+{</font></div><div><font face="'courier new', monospace">+       int i;</font></div>

<div><font face="'courier new', monospace">+       uint8_t type = opcode->spi_type;</font></div><div><font face="'courier new', monospace">+       int ret = 0;</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+       /* check flash descriptor permissions (if present) */</font></div><div><font face="'courier new', monospace">+       for (i = 0; i < num_fd_regions; i++) {</font></div>

<div><font face="'courier new', monospace">+               const char *name = fd_regions[i].name;</font></div><div><font face="'courier new', monospace">+               enum fd_access_level level;</font></div>

<div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+               if ((addr + count - 1 < fd_regions[i].base) ||</font></div><div><font face="'courier new', monospace">+                   (addr > fd_regions[i].limit))</font></div>

<div><font face="'courier new', monospace">+                       continue;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+               if (!fd_regions[i].permission) {</font></div>

<div><font face="'courier new', monospace">+                       msg_perr("No permissions set for flash region %s\n",</font></div><div><font face="'courier new', monospace">+                                 fd_regions[i].name);</font></div>

<div><font face="'courier new', monospace">+                       break;</font></div><div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+               level = fd_regions[i].permission->level;</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">+               if (type == SPI_OPCODE_TYPE_READ_WITH_ADDRESS) {</font></div>

<div><font face="'courier new', monospace">+                       if (level != FD_REGION_READ_ONLY &&</font></div><div><font face="'courier new', monospace">+                           level != FD_REGION_READ_WRITE) {</font></div>

<div><font face="'courier new', monospace">+                               msg_pspew("%s: Cannot read address 0x%08x in "</font></div><div><font face="'courier new', monospace">+                                         "region %s\n", __func__,addr,name);</font></div>

<div><font face="'courier new', monospace">+                               ret = SPI_ACCESS_DENIED;</font></div><div><font face="'courier new', monospace">+                       }</font></div><div><font face="'courier new', monospace">+               } else if (type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) {</font></div>

<div><font face="'courier new', monospace">+                       if (level != FD_REGION_WRITE_ONLY &&</font></div><div><font face="'courier new', monospace">+                           level != FD_REGION_READ_WRITE) {</font></div>

<div><font face="'courier new', monospace">+                               msg_pspew("%s: Cannot write to address 0x%08x in"</font></div><div><font face="'courier new', monospace">+                                         "region %s\n", __func__,addr,name);</font></div>

<div><font face="'courier new', monospace">+                               ret = SPI_ACCESS_DENIED;</font></div><div><font face="'courier new', monospace">+                       }</font></div><div><font face="'courier new', monospace">+               }</font></div>

<div><font face="'courier new', monospace">+               break;</font></div><div><font face="'courier new', monospace">+       }</font></div><div><font face="'courier new', monospace">+</font></div>

<div><font face="'courier new', monospace">+       return ret;</font></div><div><font face="'courier new', monospace">+}</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace"> static int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,</font></div>

<div><font face="'courier new', monospace">                    const unsigned char *writearr, unsigned char *readarr)</font></div><div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">@@ -1045,19 +1134,6 @@ static int ich_spi_send_command(unsigned</font></div>

<div><font face="'courier new', monospace">                return SPI_INVALID_LENGTH;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">-       /* if opcode-type requires an address */</font></div><div><font face="'courier new', monospace">-       if (opcode->spi_type == SPI_OPCODE_TYPE_READ_WITH_ADDRESS ||</font></div>

<div><font face="'courier new', monospace">-           opcode->spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) {</font></div><div><font face="'courier new', monospace">-               addr = (writearr[1] << 16) |</font></div>

<div><font face="'courier new', monospace">-                   (writearr[2] << 8) | (writearr[3] << 0);</font></div><div><font face="'courier new', monospace">-               if (addr < ichspi_bbar) {</font></div>

<div><font face="'courier new', monospace">-                       msg_perr("%s: Address 0x%06x below allowed "</font></div><div><font face="'courier new', monospace">-                                "range 0x%06x-0xffffff\n", __func__,</font></div>

<div><font face="'courier new', monospace">-                                addr, ichspi_bbar);</font></div><div><font face="'courier new', monospace">-                       return SPI_INVALID_ADDRESS;</font></div>

<div><font face="'courier new', monospace">-               }</font></div><div><font face="'courier new', monospace">-       }</font></div><div><font face="'courier new', monospace">-</font></div><div>

<font face="'courier new', monospace">        /* Translate read/write array/count.</font></div><div><font face="'courier new', monospace">         * The maximum data length is identical for the maximum read length and</font></div>

<div><font face="'courier new', monospace">         * for the maximum write length excluding opcode and address. Opcode and</font></div><div><font face="'courier new', monospace">@@ -1076,6 +1152,24 @@ static int ich_spi_send_command(unsigned</font></div>

<div><font face="'courier new', monospace">                count = readcnt;</font></div><div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">+       /* if opcode-type requires an address */</font></div><div><font face="'courier new', monospace">+       if (opcode->spi_type == SPI_OPCODE_TYPE_READ_WITH_ADDRESS ||</font></div>

<div><font face="'courier new', monospace">+           opcode->spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) {</font></div><div><font face="'courier new', monospace">+               addr = (writearr[1] << 16) |</font></div>

<div><font face="'courier new', monospace">+                   (writearr[2] << 8) | (writearr[3] << 0);</font></div><div><font face="'courier new', monospace">+               if (addr < ichspi_bbar) {</font></div>

<div><font face="'courier new', monospace">+                       msg_perr("%s: Address 0x%06x below allowed "</font></div><div><font face="'courier new', monospace">+                                "range 0x%06x-0xffffff\n", __func__,</font></div>

<div><font face="'courier new', monospace">+                                addr, ichspi_bbar);</font></div><div><font face="'courier new', monospace">+                       return SPI_INVALID_ADDRESS;</font></div>

<div><font face="'courier new', monospace">+               }</font></div><div><font face="'courier new', monospace">+               if (num_fd_regions > 0) {</font></div><div><font face="'courier new', monospace">+                       result = check_fd_permissions(opcode, addr, count);</font></div>

<div><font face="'courier new', monospace">+                       if (result)</font></div><div><font face="'courier new', monospace">+                               return result;</font></div><div><font face="'courier new', monospace">+               }</font></div>

<div><font face="'courier new', monospace">+       }</font></div><div><font face="'courier new', monospace">+</font></div><div><font face="'courier new', monospace">        result = run_opcode(*opcode, addr, count, data);</font></div>

<div><font face="'courier new', monospace">        if (result) {</font></div><div><font face="'courier new', monospace">                msg_pdbg("Running OPCODE 0x%02x failed ", opcode->opcode);</font></div>

<div><font face="'courier new', monospace">@@ -1421,32 +1515,25 @@ static int ich_spi_send_multicommand(str</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> static void do_ich9_spi_frap(uint32_t frap, int i)</font></div>

<div><font face="'courier new', monospace"> {</font></div><div><font face="'courier new', monospace">-       static const char *const access_names[4] = {</font></div><div><font face="'courier new', monospace">-               "locked", "read-only", "write-only", "read-write"</font></div>

<div><font face="'courier new', monospace">-       };</font></div><div><font face="'courier new', monospace">-       static const char *const region_names[5] = {</font></div><div><font face="'courier new', monospace">-               "Flash Descriptor", "BIOS", "Management Engine",</font></div>

<div><font face="'courier new', monospace">-               "Gigabit Ethernet", "Platform Data"</font></div><div><font face="'courier new', monospace">-       };</font></div><div><font face="'courier new', monospace">-       uint32_t base, limit;</font></div>

<div><font face="'courier new', monospace">        int rwperms = (((ICH_BRWA(frap) >> i) & 1) << 1) |</font></div><div><font face="'courier new', monospace">                      (((ICH_BRRA(frap) >> i) & 1) << 0);</font></div>

<div><font face="'courier new', monospace">        int offset = ICH9_REG_FREG0 + i * 4;</font></div><div><font face="'courier new', monospace">        uint32_t freg = mmio_readl(ich_spibar + offset);</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">        msg_pdbg("0x%02X: 0x%08x (FREG%i: %s)\n",</font></div><div><font face="'courier new', monospace">-                    offset, freg, i, region_names[i]);</font></div>

<div><font face="'courier new', monospace">+                    offset, freg, i, fd_regions[i].name);</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">-       base  = ICH_FREG_BASE(freg);</font></div>

<div><font face="'courier new', monospace">-       limit = ICH_FREG_LIMIT(freg);</font></div><div><font face="'courier new', monospace">-       if (base > limit) {</font></div><div><font face="'courier new', monospace">+       fd_regions[i].base  = ICH_FREG_BASE(freg);</font></div>

<div><font face="'courier new', monospace">+       fd_regions[i].limit = ICH_FREG_LIMIT(freg) | 0x0fff;</font></div><div><font face="'courier new', monospace">+       fd_regions[i].permission = &fd_region_permissions[rwperms];</font></div>

<div><font face="'courier new', monospace">+       if (fd_regions[i].base > fd_regions[i].limit) {</font></div><div><font face="'courier new', monospace">                /* this FREG is disabled */</font></div>

<div><font face="'courier new', monospace">                msg_pdbg("%s region is unused.\n", region_names[i]);</font></div><div><font face="'courier new', monospace">                return;</font></div>

<div><font face="'courier new', monospace">        }</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">-       msg_pdbg("0x%08x-0x%08x is %s\n", base, (limit | 0x0fff),</font></div>

<div><font face="'courier new', monospace">-                access_names[rwperms]);</font></div><div><font face="'courier new', monospace">+       msg_pdbg("0x%08x-0x%08x is %s\n", fd_regions[i].base,</font></div>

<div><font face="'courier new', monospace">+                fd_regions[i].limit, fd_regions[i].permission->name);</font></div><div><font face="'courier new', monospace"> }</font></div><div><font face="'courier new', monospace"> </font></div>

<div><font face="'courier new', monospace">        /* In contrast to FRAP and the master section of the descriptor the bits</font></div><div><font face="'courier new', monospace">@@ -1460,9 +1547,6 @@ static void do_ich9_spi_frap(uint32_t fr</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace"> static void prettyprint_ich9_reg_pr(int i)</font></div><div><font face="'courier new', monospace"> {</font></div>

<div><font face="'courier new', monospace">-       static const char *const access_names[4] = {</font></div><div><font face="'courier new', monospace">-               "locked", "read-only", "write-only", "read-write"</font></div>

<div><font face="'courier new', monospace">-       };</font></div><div><font face="'courier new', monospace">        uint8_t off = ICH9_REG_PR0 + (i * 4);</font></div><div><font face="'courier new', monospace">        uint32_t pr = mmio_readl(ich_spibar + off);</font></div>

<div><font face="'courier new', monospace">        int rwperms = ICH_PR_PERMS(pr);</font></div><div><font face="'courier new', monospace">@@ -1647,6 +1731,7 @@ int ich_init_spi(struct pci_dev *dev, ui</font></div>

<div><font face="'courier new', monospace">                ich_init_opcodes();</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">                if (desc_valid) {</font></div>

<div><font face="'courier new', monospace">+                       num_fd_regions = DEFAULT_NUM_FD_REGIONS;</font></div><div><font face="'courier new', monospace">                        tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFC);</font></div>

<div><font face="'courier new', monospace">                        msg_pdbg("0x06: 0x%04x (HSFC)\n", tmp2);</font></div><div><font face="'courier new', monospace">                        prettyprint_ich9_reg_hsfc(tmp2);</font></div>

<div><font face="'courier new', monospace">@@ -1664,15 +1749,15 @@ int ich_init_spi(struct pci_dev *dev, ui</font></div><div><font face="'courier new', monospace">                        msg_pdbg("BRRA 0x%02x\n", ICH_BRRA(tmp));</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">                        /* Decode and print FREGx and FRAP registers */</font></div><div><font face="'courier new', monospace">-                       for (i = 0; i < 5; i++)</font></div>

<div><font face="'courier new', monospace">+                       for (i = 0; i < num_fd_regions; i++)</font></div><div><font face="'courier new', monospace">                                do_ich9_spi_frap(tmp, i);</font></div>

<div><font face="'courier new', monospace">                }</font></div><div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">                /* try to disable PR locks before printing them */</font></div>

<div><font face="'courier new', monospace">                if (!ichspi_lock)</font></div><div><font face="'courier new', monospace">-                       for (i = 0; i < 5; i++)</font></div><div><font face="'courier new', monospace">+                       for (i = 0; i < num_fd_regions; i++)</font></div>

<div><font face="'courier new', monospace">                                ich9_set_pr(i, 0, 0);</font></div><div><font face="'courier new', monospace">-               for (i = 0; i < 5; i++)</font></div>

<div><font face="'courier new', monospace">+               for (i = 0; i < num_fd_regions; i++)</font></div><div><font face="'courier new', monospace">                        prettyprint_ich9_reg_pr(i);</font></div>

<div><font face="'courier new', monospace"> </font></div><div><font face="'courier new', monospace">                tmp = mmio_readl(ich_spibar + ICH9_REG_SSFS);</font></div><div><br></div>-- <br>David Hendricks (dhendrix)<br>

Systems Software Engineer, Google Inc.<br>
</div></div></div></div></div>