Counter-proposal (conversion from scratch). AFAICS the only differences
to your version regarding code flow are in cli_classic.c and flashrom.c.

Signed-off-by: Carl-Daniel Hailfinger <[email protected]>

Index: flashrom-flashctx_separate_struct_flashchip/flash.h
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/flash.h (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/flash.h (Arbeitskopie)
@@ -148,27 +148,8 @@
        } voltage;
 };
 
-/* struct flashctx must always contain struct flashchip at the beginning. */
 struct flashctx {
-       const char *vendor;
-       const char *name;
-       enum chipbustype bustype;
-       uint32_t manufacture_id;
-       uint32_t model_id;
-       int total_size;
-       int page_size;
-       int feature_bits;
-       uint32_t tested;
-       int (*probe) (struct flashctx *flash);
-       int probe_timing;
-       struct block_eraser block_erasers[NUM_ERASEFUNCTIONS];
-       int (*printlock) (struct flashctx *flash);
-       int (*unlock) (struct flashctx *flash);
-       int (*write) (struct flashctx *flash, uint8_t *buf, unsigned int start, 
unsigned int len);
-       int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, 
unsigned int len);
-       struct voltage voltage;
-       /* struct flashchip ends here. */
-       
+       struct flashchip *chip;
        chipaddr virtual_memory;
        /* Some flash devices have an additional register space. */
        chipaddr virtual_registers;
Index: flashrom-flashctx_separate_struct_flashchip/it87spi.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/it87spi.c       (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/it87spi.c       (Arbeitskopie)
@@ -331,7 +331,7 @@
        /* FIXME: The command below seems to be redundant or wrong. */
        OUTB(0x06, it8716f_flashport + 1);
        OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
-       for (i = 0; i < flash->page_size; i++)
+       for (i = 0; i < flash->chip->page_size; i++)
                mmio_writeb(buf[i], (void *)(bios + start + i));
        OUTB(0, it8716f_flashport);
        /* Wait until the Write-In-Progress bit is cleared.
@@ -355,7 +355,7 @@
         * the mainboard does not use IT87 SPI translation. This should be done
         * via a programmer parameter for the internal programmer.
         */
-       if ((flash->total_size * 1024 > 512 * 1024)) {
+       if ((flash->chip->total_size * 1024 > 512 * 1024)) {
                spi_read_chunked(flash, buf, start, len, 3);
        } else {
                mmio_readn((void *)(flash->virtual_memory + start), buf, len);
@@ -377,28 +377,28 @@
         * the mainboard does not use IT87 SPI translation. This should be done
         * via a programmer parameter for the internal programmer.
         */
-       if ((flash->total_size * 1024 > 512 * 1024) ||
-           (flash->page_size > 256)) {
+       if ((flash->chip->total_size * 1024 > 512 * 1024) ||
+           (flash->chip->page_size > 256)) {
                spi_chip_write_1(flash, buf, start, len);
        } else {
                unsigned int lenhere;
 
-               if (start % flash->page_size) {
+               if (start % flash->chip->page_size) {
                        /* start to the end of the page or to start + len,
                         * whichever is smaller.
                         */
-                       lenhere = min(len, flash->page_size - start % 
flash->page_size);
+                       lenhere = min(len, flash->chip->page_size - start % 
flash->chip->page_size);
                        spi_chip_write_1(flash, buf, start, lenhere);
                        start += lenhere;
                        len -= lenhere;
                        buf += lenhere;
                }
 
-               while (len >= flash->page_size) {
+               while (len >= flash->chip->page_size) {
                        it8716f_spi_page_program(flash, buf, start);
-                       start += flash->page_size;
-                       len -= flash->page_size;
-                       buf += flash->page_size;
+                       start += flash->chip->page_size;
+                       len -= flash->chip->page_size;
+                       buf += flash->chip->page_size;
                }
                if (len)
                        spi_chip_write_1(flash, buf, start, len);
Index: flashrom-flashctx_separate_struct_flashchip/jedec.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/jedec.c (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/jedec.c (Arbeitskopie)
@@ -93,9 +93,9 @@
                msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
 }
 
-static unsigned int getaddrmask(struct flashctx *flash)
+static unsigned int getaddrmask(const struct flashchip *chip)
 {
-       switch (flash->feature_bits & FEATURE_ADDR_MASK) {
+       switch (chip->feature_bits & FEATURE_ADDR_MASK) {
        case FEATURE_ADDR_FULL:
                return MASK_FULL;
                break;
@@ -129,11 +129,11 @@
        uint32_t flashcontent1, flashcontent2;
        int probe_timing_enter, probe_timing_exit;
 
-       if (flash->probe_timing > 0) 
-               probe_timing_enter = probe_timing_exit = flash->probe_timing;
-       else if (flash->probe_timing == TIMING_ZERO) { /* No delay. */
+       if (flash->chip->probe_timing > 0) 
+               probe_timing_enter = probe_timing_exit = 
flash->chip->probe_timing;
+       else if (flash->chip->probe_timing == TIMING_ZERO) { /* No delay. */
                probe_timing_enter = probe_timing_exit = 0;
-       } else if (flash->probe_timing == TIMING_FIXME) { /* == _IGNORED */
+       } else if (flash->chip->probe_timing == TIMING_FIXME) { /* == _IGNORED 
*/
                msg_cdbg("Chip lacks correct probe timing information, "
                             "using default 10mS/40uS. ");
                probe_timing_enter = 10000;
@@ -151,7 +151,7 @@
        if (probe_timing_enter)
                programmer_delay(probe_timing_enter);
        /* Reset chip to a clean slate */
-       if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
+       if ((flash->chip->feature_bits & FEATURE_RESET_MASK) == 
FEATURE_LONG_RESET)
        {
                chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
                if (probe_timing_exit)
@@ -194,7 +194,7 @@
        }
 
        /* Issue JEDEC Product ID Exit command */
-       if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
+       if ((flash->chip->feature_bits & FEATURE_RESET_MASK) == 
FEATURE_LONG_RESET)
        {
                chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
                if (probe_timing_exit)
@@ -231,10 +231,10 @@
                msg_cdbg(", id2 is normal flash content");
 
        msg_cdbg("\n");
-       if (largeid1 != flash->manufacture_id || largeid2 != flash->model_id)
+       if (largeid1 != flash->chip->manufacture_id || largeid2 != 
flash->chip->model_id)
                return 0;
 
-       if (flash->feature_bits & FEATURE_REGISTERMAP)
+       if (flash->chip->feature_bits & FEATURE_REGISTERMAP)
                map_flash_registers(flash);
 
        return 1;
@@ -245,7 +245,7 @@
 {
        chipaddr bios = flash->virtual_memory;
        int delay_us = 0;
-       if(flash->probe_timing != TIMING_ZERO)
+       if(flash->chip->probe_timing != TIMING_ZERO)
                delay_us = 10;
 
        /*  Issue the Sector Erase command   */
@@ -275,7 +275,7 @@
 {
        chipaddr bios = flash->virtual_memory;
        int delay_us = 0;
-       if(flash->probe_timing != TIMING_ZERO)
+       if(flash->chip->probe_timing != TIMING_ZERO)
                delay_us = 10;
 
        /*  Issue the Sector Erase command   */
@@ -304,7 +304,7 @@
 {
        chipaddr bios = flash->virtual_memory;
        int delay_us = 0;
-       if(flash->probe_timing != TIMING_ZERO)
+       if(flash->chip->probe_timing != TIMING_ZERO)
                delay_us = 10;
 
        /*  Issue the JEDEC Chip Erase command   */
@@ -366,7 +366,7 @@
        chipaddr olddst;
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
 
        olddst = dst;
        for (i = 0; i < len; i++) {
@@ -390,7 +390,7 @@
        chipaddr d = dst;
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
 
 retry:
        /* Issue JEDEC Start Program command */
@@ -438,7 +438,7 @@
         * write_jedec have page_size set to max_writechunk_size, so
         * we're OK for now.
         */
-       unsigned int page_size = flash->page_size;
+       unsigned int page_size = flash->chip->page_size;
 
        /* Warning: This loop has a very unusual condition and body.
         * The loop needs to go through each page with at least one affected
@@ -469,8 +469,8 @@
 {
        unsigned int mask;
 
-       mask = getaddrmask(flash);
-       if ((addr != 0) || (blocksize != flash->total_size * 1024)) {
+       mask = getaddrmask(flash->chip);
+       if ((addr != 0) || (blocksize != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;
@@ -482,7 +482,7 @@
 {
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
        return probe_jedec_common(flash, mask);
 }
 
@@ -491,7 +491,7 @@
 {
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
        return erase_sector_jedec_common(flash, page, size, mask);
 }
 
@@ -500,7 +500,7 @@
 {
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
        return erase_block_jedec_common(flash, page, size, mask);
 }
 
@@ -508,6 +508,6 @@
 {
        unsigned int mask;
 
-       mask = getaddrmask(flash);
+       mask = getaddrmask(flash->chip);
        return erase_chip_jedec_common(flash, mask);
 }
Index: flashrom-flashctx_separate_struct_flashchip/w39.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/w39.c   (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/w39.c   (Arbeitskopie)
@@ -138,11 +138,11 @@
 
 static int printlock_w39_fwh(struct flashctx *flash)
 {
-       unsigned int i, total_size = flash->total_size * 1024;
+       unsigned int i, total_size = flash->chip->total_size * 1024;
        int ret = 0;
        
        /* Print lock status of the complete chip */
-       for (i = 0; i < total_size; i += flash->page_size)
+       for (i = 0; i < total_size; i += flash->chip->page_size)
                ret |= printlock_w39_fwh_block(flash, i);
 
        return ret;
@@ -150,10 +150,10 @@
 
 static int unlock_w39_fwh(struct flashctx *flash)
 {
-       unsigned int i, total_size = flash->total_size * 1024;
+       unsigned int i, total_size = flash->chip->total_size * 1024;
        
        /* Unlock the complete chip */
-       for (i = 0; i < total_size; i += flash->page_size)
+       for (i = 0; i < total_size; i += flash->chip->page_size)
                if (unlock_w39_fwh_block(flash, i))
                        return -1;
 
Index: flashrom-flashctx_separate_struct_flashchip/sst49lfxxxc.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/sst49lfxxxc.c   (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/sst49lfxxxc.c   (Arbeitskopie)
@@ -38,7 +38,7 @@
 static int write_lockbits_49lfxxxc(struct flashctx *flash, unsigned char bits)
 {
        chipaddr registers = flash->virtual_registers;
-       unsigned int i, left = flash->total_size * 1024;
+       unsigned int i, left = flash->chip->total_size * 1024;
        unsigned long address;
 
        msg_cdbg("\nbios=0x%08lx\n", registers);
Index: flashrom-flashctx_separate_struct_flashchip/sst_fwhub.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/sst_fwhub.c     (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/sst_fwhub.c     (Arbeitskopie)
@@ -31,7 +31,7 @@
 
        blockstatus = chip_readb(flash, registers + offset + 2);
        msg_cdbg("Lock status for 0x%06x (size 0x%06x) is %02x, ",
-                    offset, flash->page_size, blockstatus);
+                    offset, flash->chip->page_size, blockstatus);
        switch (blockstatus & 0x3) {
        case 0x0:
                msg_cdbg("full access\n");
@@ -72,7 +72,7 @@
 {
        int i;
 
-       for (i = 0; i < flash->total_size * 1024; i += flash->page_size)
+       for (i = 0; i < flash->chip->total_size * 1024; i += 
flash->chip->page_size)
                check_sst_fwhub_block_lock(flash, i);
 
        return 0;
@@ -82,7 +82,7 @@
 {
        int i, ret=0;
 
-       for (i = 0; i < flash->total_size * 1024; i += flash->page_size)
+       for (i = 0; i < flash->chip->total_size * 1024; i += 
flash->chip->page_size)
        {
                if (clear_sst_fwhub_block_lock(flash, i))
                {
Index: flashrom-flashctx_separate_struct_flashchip/cli_classic.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/cli_classic.c   (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/cli_classic.c   (Arbeitskopie)
@@ -109,8 +109,8 @@
 {
        unsigned long size;
        /* Probe for up to three flash chips. */
-       const struct flashchip *flash;
-       struct flashctx flashes[3];
+       const struct flashchip *chip;
+       struct flashctx flashes[3] = {};
        struct flashctx *fill_flash;
        const char *name;
        int namelen, opt, i, j;
@@ -389,17 +389,16 @@
        }
        /* Does a chip with the requested name exist in the flashchips array? */
        if (chip_to_probe) {
-               for (flash = flashchips; flash && flash->name; flash++)
-                       if (!strcmp(flash->name, chip_to_probe))
+               for (chip = flashchips; chip && chip->name; chip++)
+                       if (!strcmp(chip->name, chip_to_probe))
                                break;
-               if (!flash || !flash->name) {
+               if (!chip || !chip->name) {
                        msg_cerr("Error: Unknown chip '%s' specified.\n", 
chip_to_probe);
                        msg_gerr("Run flashrom -L to view the hardware 
supported in this flashrom version.\n");
                        ret = 1;
                        goto out;
                }
-               /* Clean up after the check. */
-               flash = NULL;
+               /* Keep chip around for later usage. */
        }
 
        if (prog == PROGRAMMER_INVALID) {
@@ -419,16 +418,13 @@
                goto out_shutdown;
        }
        tempstr = flashbuses_to_text(get_buses_supported());
-       msg_pdbg("The following protocols are supported: %s.\n",
-                tempstr);
+       msg_pdbg("The following protocols are supported: %s.\n", tempstr);
        free(tempstr);
 
        for (j = 0; j < registered_programmer_count; j++) {
                startchip = 0;
                while (chipcount < ARRAY_SIZE(flashes)) {
-                       startchip = probe_flash(&registered_programmers[j],
-                                               startchip, 
-                                               &flashes[chipcount], 0);
+                       startchip = probe_flash(&registered_programmers[j], 
startchip, &flashes[chipcount], 0);
                        if (startchip == -1)
                                break;
                        chipcount++;
@@ -437,9 +433,9 @@
        }
 
        if (chipcount > 1) {
-               msg_cinfo("Multiple flash chips were detected: \"%s\"", 
flashes[0].name);
+               msg_cinfo("Multiple flash chips were detected: \"%s\"", 
flashes[0].chip->name);
                for (i = 1; i < chipcount; i++)
-                       msg_cinfo(", \"%s\"", flashes[i].name);
+                       msg_cinfo(", \"%s\"", flashes[i].chip->name);
                msg_cinfo("\nPlease specify which chip to use with the -c 
<chipname> option.\n");
                ret = 1;
                goto out_shutdown;
@@ -456,9 +452,15 @@
                        /* This loop just counts compatible controllers. */
                        for (j = 0; j < registered_programmer_count; j++) {
                                pgm = &registered_programmers[j];
-                               if (pgm->buses_supported & flashes[0].bustype)
+                               /* chip is still set from the chip_to_probe 
earlier in this function. */
+                               if (pgm->buses_supported & chip->bustype)
                                        compatible_programmers++;
                        }
+                       if (!compatible_programmers) {
+                               msg_cinfo("No compatible controller found for 
the requested flash chip.\n");
+                               ret = 1;
+                               goto out_shutdown;
+                       }
                        if (compatible_programmers > 1)
                                msg_cinfo("More than one compatible controller 
found for the requested flash "
                                          "chip, using the first one.\n");
@@ -469,6 +471,7 @@
                                        break;
                        }
                        if (startchip == -1) {
+                               // FIXME: This should never happen! Ask for a 
bug report?
                                msg_cinfo("Probing for flash chip '%s' 
failed.\n", chip_to_probe);
                                ret = 1;
                                goto out_shutdown;
@@ -481,19 +484,18 @@
                goto out_shutdown;
        } else if (!chip_to_probe) {
                /* repeat for convenience when looking at foreign logs */
-               tempstr = flashbuses_to_text(flashes[0].bustype);
+               tempstr = flashbuses_to_text(flashes[0].chip->bustype);
                msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
-                        flashes[0].vendor, flashes[0].name,
-                        flashes[0].total_size, tempstr);
+                        flashes[0].chip->vendor, flashes[0].chip->name, 
flashes[0].chip->total_size, tempstr);
                free(tempstr);
        }
 
        fill_flash = &flashes[0];
 
-       check_chip_supported(fill_flash);
+       check_chip_supported(fill_flash->chip);
 
-       size = fill_flash->total_size * 1024;
-       if (check_max_decode(fill_flash->pgm->buses_supported & 
fill_flash->bustype, size) && (!force)) {
+       size = fill_flash->chip->total_size * 1024;
+       if (check_max_decode(fill_flash->pgm->buses_supported & 
fill_flash->chip->bustype, size) && (!force)) {
                msg_cerr("Chip is too big for this programmer (-V gives 
details). Use --force to override.\n");
                ret = 1;
                goto out_shutdown;
Index: flashrom-flashctx_separate_struct_flashchip/layout.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/layout.c        (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/layout.c        (Arbeitskopie)
@@ -221,7 +221,7 @@
 {
        unsigned int start = 0;
        romlayout_t *entry;
-       unsigned int size = flash->total_size * 1024;
+       unsigned int size = flash->chip->total_size * 1024;
 
        /* If no regions were specified for inclusion, assume
         * that the user wants to write the complete new image.
Index: flashrom-flashctx_separate_struct_flashchip/ichspi.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/ichspi.c        (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/ichspi.c        (Arbeitskopie)
@@ -1193,9 +1193,9 @@
        else
                msg_cdbg(" with a");
        msg_cdbg(" density of %d kB.\n", total_size / 1024);
-       flash->total_size = total_size / 1024;
+       flash->chip->total_size = total_size / 1024;
 
-       eraser = &(flash->block_erasers[0]);
+       eraser = &(flash->chip->block_erasers[0]);
        boundary = (REGREAD32(ICH9_REG_FPB) & FPB_FPBA) << 12;
        size_high = total_size - boundary;
        erase_size_high = ich_hwseq_get_erase_block_size(boundary);
@@ -1228,7 +1228,7 @@
                msg_cdbg("In that range are %d erase blocks with %d B each.\n",
                         size_high / erase_size_high, erase_size_high);
        }
-       flash->tested = TEST_OK_PREW;
+       flash->chip->tested = TEST_OK_PREW;
        return 1;
 }
 
@@ -1256,7 +1256,7 @@
                return -1;
        }
 
-       if (addr + len > flash->total_size * 1024) {
+       if (addr + len > flash->chip->total_size * 1024) {
                msg_perr("Request to erase some inaccessible memory address(es)"
                         " (addr=0x%x, len=%d). "
                         "Not erasing anything.\n", addr, len);
@@ -1288,7 +1288,7 @@
        uint16_t timeout = 100 * 60;
        uint8_t block_len;
 
-       if (addr + len > flash->total_size * 1024) {
+       if (addr + len > flash->chip->total_size * 1024) {
                msg_perr("Request to read from an inaccessible memory address "
                         "(addr=0x%x, len=%d).\n", addr, len);
                return -1;
@@ -1326,7 +1326,7 @@
        uint16_t timeout = 100 * 60;
        uint8_t block_len;
 
-       if (addr + len > flash->total_size * 1024) {
+       if (addr + len > flash->chip->total_size * 1024) {
                msg_perr("Request to write to an inaccessible memory address "
                         "(addr=0x%x, len=%d).\n", addr, len);
                return -1;
Index: flashrom-flashctx_separate_struct_flashchip/82802ab.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/82802ab.c       (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/82802ab.c       (Arbeitskopie)
@@ -44,7 +44,7 @@
 {
        chipaddr bios = flash->virtual_memory;
        uint8_t id1, id2, flashcontent1, flashcontent2;
-       int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0;
+       int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) != 0;
 
        /* Reset to get a clean state */
        chip_writeb(flash, 0xFF, bios);
@@ -80,10 +80,10 @@
                msg_cdbg(", id2 is normal flash content");
 
        msg_cdbg("\n");
-       if (id1 != flash->manufacture_id || id2 != flash->model_id)
+       if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
                return 0;
 
-       if (flash->feature_bits & FEATURE_REGISTERMAP)
+       if (flash->chip->feature_bits & FEATURE_REGISTERMAP)
                map_flash_registers(flash);
 
        return 1;
@@ -112,7 +112,7 @@
        int i;
        //chipaddr wrprotect = flash->virtual_registers + page + 2;
 
-       for (i = 0; i < flash->total_size * 1024; i+= flash->page_size)
+       for (i = 0; i < flash->chip->total_size * 1024; i+= 
flash->chip->page_size)
                chip_writeb(flash, 0, flash->virtual_registers + i + 2);
 
        return 0;
@@ -181,7 +181,7 @@
        }
 
        /* Read block lock-bits */
-       for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) {
+       for (i = 0; i < flash->chip->total_size * 1024; i+= (64 * 1024)) {
                bcfg = chip_readb(flash, bios + i + 2); // read block lock 
config
                msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : 
"un");
                if (bcfg) {
@@ -234,7 +234,7 @@
        }
 
        /* Read block lock-bits, 8 * 8 KB + 15 * 64 KB */
-       for (i = 0; i < flash->total_size * 1024;
+       for (i = 0; i < flash->chip->total_size * 1024;
             i += (i >= (64 * 1024) ? 64 * 1024 : 8 * 1024)) {
                bcfg = chip_readb(flash, bios + i + 2); /* read block lock 
config */
                msg_cdbg("block lock at %06x is %slocked!\n", i,
Index: flashrom-flashctx_separate_struct_flashchip/dediprog.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/dediprog.c      (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/dediprog.c      (Arbeitskopie)
@@ -381,7 +381,7 @@
                              unsigned int start, unsigned int len, uint8_t 
dedi_spi_cmd)
 {
        int ret;
-       const unsigned int chunksize = flash->page_size;
+       const unsigned int chunksize = flash->chip->page_size;
        unsigned int residue = start % chunksize ? chunksize - start % 
chunksize : 0;
        unsigned int bulklen;
 
Index: flashrom-flashctx_separate_struct_flashchip/spi25.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/spi25.c (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/spi25.c (Arbeitskopie)
@@ -147,7 +147,7 @@
 
        msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
 
-       if (id1 == flash->manufacture_id && id2 == flash->model_id) {
+       if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) 
{
                /* Print the status register to tell the
                 * user about possible write protection.
                 */
@@ -157,12 +157,12 @@
        }
 
        /* Test if this is a pure vendor match. */
-       if (id1 == flash->manufacture_id &&
-           GENERIC_DEVICE_ID == flash->model_id)
+       if (id1 == flash->chip->manufacture_id &&
+           GENERIC_DEVICE_ID == flash->chip->model_id)
                return 1;
 
        /* Test if there is any vendor ID. */
-       if (GENERIC_MANUF_ID == flash->manufacture_id &&
+       if (GENERIC_MANUF_ID == flash->chip->manufacture_id &&
            id1 != 0xff)
                return 1;
 
@@ -210,7 +210,7 @@
 
        msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
 
-       if (id1 == flash->manufacture_id && id2 == flash->model_id) {
+       if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) 
{
                /* Print the status register to tell the
                 * user about possible write protection.
                 */
@@ -220,12 +220,12 @@
        }
 
        /* Test if this is a pure vendor match. */
-       if (id1 == flash->manufacture_id &&
-           GENERIC_DEVICE_ID == flash->model_id)
+       if (id1 == flash->chip->manufacture_id &&
+           GENERIC_DEVICE_ID == flash->chip->model_id)
                return 1;
 
        /* Test if there is any vendor ID. */
-       if (GENERIC_MANUF_ID == flash->manufacture_id &&
+       if (GENERIC_MANUF_ID == flash->chip->manufacture_id &&
            id1 != 0xff)
                return 1;
 
@@ -267,7 +267,7 @@
 
        msg_cdbg("%s: id 0x%x\n", __func__, id2);
 
-       if (id2 != flash->model_id)
+       if (id2 != flash->chip->model_id)
                return 0;
 
        /* Print the status register to tell the
@@ -291,7 +291,7 @@
 
        msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
 
-       if (id1 != flash->manufacture_id || id2 != flash->model_id)
+       if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
                return 0;
 
        /* Print the status register to tell the
@@ -423,18 +423,18 @@
 
        status = spi_read_status_register(flash);
        msg_cdbg("Chip status register is %02x\n", status);
-       switch (flash->manufacture_id) {
+       switch (flash->chip->manufacture_id) {
        case ST_ID:
-               if (((flash->model_id & 0xff00) == 0x2000) ||
-                   ((flash->model_id & 0xff00) == 0x2500))
+               if (((flash->chip->model_id & 0xff00) == 0x2000) ||
+                   ((flash->chip->model_id & 0xff00) == 0x2500))
                        spi_prettyprint_status_register_st_m25p(status);
                break;
        case MACRONIX_ID:
-               if ((flash->model_id & 0xff00) == 0x2000)
+               if ((flash->chip->model_id & 0xff00) == 0x2000)
                        spi_prettyprint_status_register_st_m25p(status);
                break;
        case SST_ID:
-               switch (flash->model_id) {
+               switch (flash->chip->model_id) {
                case 0x2541:
                        spi_prettyprint_status_register_sst25vf016(status);
                        break;
@@ -704,7 +704,7 @@
 int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
-       if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
+       if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;
@@ -715,7 +715,7 @@
 int spi_block_erase_c7(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
-       if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
+       if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;
@@ -820,7 +820,7 @@
 
 int spi_write_status_register(struct flashctx *flash, int status)
 {
-       int feature_bits = flash->feature_bits;
+       int feature_bits = flash->chip->feature_bits;
        int ret = 1;
 
        if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {
@@ -972,7 +972,7 @@
 {
        int rc = 0;
        unsigned int i, j, starthere, lenhere, toread;
-       unsigned int page_size = flash->page_size;
+       unsigned int page_size = flash->chip->page_size;
 
        /* Warning: This loop has a very unusual condition and body.
         * The loop needs to go through each page with at least one affected
@@ -1017,7 +1017,7 @@
         * spi_chip_write_256 have page_size set to max_writechunk_size, so
         * we're OK for now.
         */
-       unsigned int page_size = flash->page_size;
+       unsigned int page_size = flash->chip->page_size;
 
        /* Warning: This loop has a very unusual condition and body.
         * The loop needs to go through each page with at least one affected
Index: flashrom-flashctx_separate_struct_flashchip/pm49fl00x.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/pm49fl00x.c     (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/pm49fl00x.c     (Arbeitskopie)
@@ -40,14 +40,14 @@
 
 int unlock_49fl00x(struct flashctx *flash)
 {
-       write_lockbits_49fl00x(flash, flash->total_size * 1024, 0,
-                              flash->page_size);
+       write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 0,
+                              flash->chip->page_size);
        return 0;
 }
 
 int lock_49fl00x(struct flashctx *flash)
 {
-       write_lockbits_49fl00x(flash, flash->total_size * 1024, 1,
-                              flash->page_size);
+       write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 1,
+                              flash->chip->page_size);
        return 0;
 }
Index: flashrom-flashctx_separate_struct_flashchip/en29lv640b.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/en29lv640b.c    (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/en29lv640b.c    (Arbeitskopie)
@@ -81,7 +81,7 @@
 
        msg_cdbg("%s: id1 0x%04x, id2 0x%04x\n", __func__, id1, id2);
 
-       if (id1 == flash->manufacture_id && id2 == flash->model_id)
+       if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
                return 1;
 
        return 0;
@@ -130,7 +130,7 @@
 int block_erase_chip_en29lv640b(struct flashctx *flash, unsigned int address,
                                unsigned int blocklen)
 {
-       if ((address != 0) || (blocklen != flash->total_size * 1024)) {
+       if ((address != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n", __func__);
                return -1;
        }
Index: flashrom-flashctx_separate_struct_flashchip/w29ee011.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/w29ee011.c      (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/w29ee011.c      (Arbeitskopie)
@@ -29,11 +29,11 @@
        chipaddr bios = flash->virtual_memory;
        uint8_t id1, id2;
 
-       if (!chip_to_probe || strcmp(chip_to_probe, flash->name)) {
+       if (!chip_to_probe || strcmp(chip_to_probe, flash->chip->name)) {
                msg_cdbg("Old Winbond W29* probe method disabled because "
                         "the probing sequence puts the AMIC A49LF040A in "
                         "a funky state. Use 'flashrom -c %s' if you "
-                        "have a board with such a chip.\n", flash->name);
+                        "have a board with such a chip.\n", flash->chip->name);
                return 0;
        }
 
@@ -65,7 +65,7 @@
 
        msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
 
-       if (id1 == flash->manufacture_id && id2 == flash->model_id)
+       if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
                return 1;
 
        return 0;
Index: flashrom-flashctx_separate_struct_flashchip/spi.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/spi.c   (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/spi.c   (Arbeitskopie)
@@ -111,16 +111,16 @@
         * means 0xffffff, the highest unsigned 24bit number.
         */
        addrbase = spi_get_valid_read_addr(flash);
-       if (addrbase + flash->total_size * 1024 > (1 << 24)) {
+       if (addrbase + flash->chip->total_size * 1024 > (1 << 24)) {
                msg_perr("Flash chip size exceeds the allowed access window. ");
                msg_perr("Read will probably fail.\n");
                /* Try to get the best alignment subject to constraints. */
-               addrbase = (1 << 24) - flash->total_size * 1024;
+               addrbase = (1 << 24) - flash->chip->total_size * 1024;
        }
        /* Check if alignment is native (at least the largest power of two which
         * is a factor of the mapped size of the chip).
         */
-       if (ffs(flash->total_size * 1024) > (ffs(addrbase) ? : 33)) {
+       if (ffs(flash->chip->total_size * 1024) > (ffs(addrbase) ? : 33)) {
                msg_perr("Flash chip is not aligned natively in the allowed "
                         "access window.\n");
                msg_perr("Read will probably return garbage.\n");
Index: flashrom-flashctx_separate_struct_flashchip/sfdp.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/sfdp.c  (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/sfdp.c  (Arbeitskopie)
@@ -84,7 +84,7 @@
 static int sfdp_add_uniform_eraser(struct flashctx *flash, uint8_t opcode, 
uint32_t block_size)
 {
        int i;
-       uint32_t total_size = flash->total_size * 1024;
+       uint32_t total_size = flash->chip->total_size * 1024;
        erasefunc_t *erasefn = spi_get_erasefn_from_opcode(opcode);
 
        if (erasefn == NULL || total_size == 0 || block_size == 0 ||
@@ -95,7 +95,7 @@
        }
 
        for (i = 0; i < NUM_ERASEFUNCTIONS; i++) {
-               struct block_eraser *eraser = &flash->block_erasers[i];
+               struct block_eraser *eraser = &flash->chip->block_erasers[i];
                /* Check for duplicates (including (some) non-uniform ones). */
                if (eraser->eraseblocks[0].size == block_size &&
                    eraser->block_erase == erasefn) {
@@ -170,28 +170,28 @@
                msg_cdbg2("volatile and writes to the status register have to "
                          "be enabled with ");
                if (tmp32 & (1 << 4)) {
-                       flash->feature_bits = FEATURE_WRSR_WREN;
+                       flash->chip->feature_bits = FEATURE_WRSR_WREN;
                        msg_cdbg2("WREN (0x06).\n");
                } else {
-                       flash->feature_bits = FEATURE_WRSR_EWSR;
+                       flash->chip->feature_bits = FEATURE_WRSR_EWSR;
                        msg_cdbg2("EWSR (0x50).\n");
                }
        } else {
                msg_cdbg2("non-volatile and the standard does not allow "
                          "vendors to tell us whether EWSR/WREN is needed for "
                          "status register writes - assuming EWSR.\n");
-                       flash->feature_bits = FEATURE_WRSR_EWSR;
+                       flash->chip->feature_bits = FEATURE_WRSR_EWSR;
                }
 
        msg_cdbg2("  Write chunk size is ");
        if (tmp32 & (1 << 2)) {
                msg_cdbg2("at least 64 B.\n");
-               flash->page_size = 64;
-               flash->write = spi_chip_write_256;
+               flash->chip->page_size = 64;
+               flash->chip->write = spi_chip_write_256;
        } else {
                msg_cdbg2("1 B only.\n");
-               flash->page_size = 256;
-               flash->write = spi_chip_write_1;
+               flash->chip->page_size = 256;
+               flash->chip->write = spi_chip_write_1;
        }
 
        if ((tmp32 & 0x3) == 0x1) {
@@ -212,8 +212,8 @@
                return 1;
        }
        total_size = ((tmp32 & 0x7FFFFFFF) + 1) / 8;
-       flash->total_size = total_size / 1024;
-       msg_cdbg2("  Flash chip size is %d kB.\n", flash->total_size);
+       flash->chip->total_size = total_size / 1024;
+       msg_cdbg2("  Flash chip size is %d kB.\n", flash->chip->total_size);
        if (total_size > (1 << 24)) {
                msg_cdbg("Flash chip size is bigger than what 3-Byte addressing 
"
                         "can access.\n");
Index: flashrom-flashctx_separate_struct_flashchip/sst28sf040.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/sst28sf040.c    (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/sst28sf040.c    (Arbeitskopie)
@@ -119,7 +119,7 @@
 int erase_chip_28sf040(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
-       if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
+       if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;
Index: flashrom-flashctx_separate_struct_flashchip/stm50flw0x0x.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/stm50flw0x0x.c  (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/stm50flw0x0x.c  (Arbeitskopie)
@@ -54,7 +54,7 @@
        /* Check, if it's is a top/bottom-block with 4k-sectors. */
        /* TODO: What about the other types? */
        if ((offset == 0) ||
-           (offset == (flash->model_id == ST_M50FLW080A ? 0xE0000 : 0x10000))
+           (offset == (flash->chip->model_id == ST_M50FLW080A ? 0xE0000 : 
0x10000))
            || (offset == 0xF0000)) {
 
                // unlock each 4k-sector
@@ -85,7 +85,7 @@
 {
        int i;
 
-       for (i = 0; i < flash->total_size * 1024; i+= flash->page_size) {
+       for (i = 0; i < flash->chip->total_size * 1024; i+= 
flash->chip->page_size) {
                if(unlock_block_stm50flw0x0x(flash, i)) {
                        msg_cerr("UNLOCK FAILED!\n");
                        return -1;
Index: flashrom-flashctx_separate_struct_flashchip/flashrom.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/flashrom.c      (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/flashrom.c      (Arbeitskopie)
@@ -416,7 +416,7 @@
 
 void map_flash_registers(struct flashctx *flash)
 {
-       size_t size = flash->total_size * 1024;
+       size_t size = flash->chip->total_size * 1024;
        /* Flash registers live 4 MByte below the flash. */
        /* FIXME: This is incorrect for nonstandard flashbase. */
        flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash 
chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
@@ -580,7 +580,7 @@
        if (!len)
                goto out_free;
 
-       if (!flash->read) {
+       if (!flash->chip->read) {
                msg_cerr("ERROR: flashrom has no read function for this flash 
chip.\n");
                return 1;
        }
@@ -589,17 +589,17 @@
                exit(1);
        }
 
-       if (start + len > flash->total_size * 1024) {
+       if (start + len > flash->chip->total_size * 1024) {
                msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
                        " total_size 0x%x\n", __func__, start, len,
-                       flash->total_size * 1024);
+                       flash->chip->total_size * 1024);
                ret = -1;
                goto out_free;
        }
        if (!message)
                message = "VERIFY";
 
-       ret = flash->read(flash, readbuf, start, len);
+       ret = flash->chip->read(flash, readbuf, start, len);
        if (ret) {
                msg_gerr("Verification impossible because read failed "
                         "at 0x%x (len 0x%x)\n", start, len);
@@ -950,44 +950,52 @@
        return 1;
 }
 
-int probe_flash(struct registered_programmer *pgm, int startchip,
-               struct flashctx *fill_flash, int force)
+int probe_flash(struct registered_programmer *pgm, int startchip, struct 
flashctx *flash, int force)
 {
-       const struct flashchip *flash;
+       const struct flashchip *chip;
        unsigned long base = 0;
        char location[64];
        uint32_t size;
        enum chipbustype buses_common;
        char *tmp;
 
-       for (flash = flashchips + startchip; flash && flash->name; flash++) {
-               if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
+       for (chip = flashchips + startchip; chip && chip->name; chip++) {
+               if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
                        continue;
-               buses_common = pgm->buses_supported & flash->bustype;
+               buses_common = pgm->buses_supported & chip->bustype;
                if (!buses_common)
                        continue;
                msg_gdbg("Probing for %s %s, %d kB: ",
-                            flash->vendor, flash->name, flash->total_size);
-               if (!flash->probe && !force) {
+                            chip->vendor, chip->name, chip->total_size);
+               if (!chip->probe && !force) {
                        msg_gdbg("failed! flashrom has no probe function for "
                                 "this flash chip.\n");
                        continue;
                }
 
-               size = flash->total_size * 1024;
+               size = chip->total_size * 1024;
                check_max_decode(buses_common, size);
 
                /* Start filling in the dynamic data. */
-               memcpy(fill_flash, flash, sizeof(struct flashchip));
-               fill_flash->pgm = pgm;
+               flash->chip = calloc(1, sizeof(struct flashchip));
+               if (!flash->chip) {
+                       msg_gerr("Out of memory!\n");
+                       // FIXME: Is -1 the right return code?
+                       return -1;
+               }
+               memcpy(flash->chip, chip, sizeof(struct flashchip));
+               flash->pgm = pgm;
 
                base = flashbase ? flashbase : (0xffffffff - size + 1);
-               fill_flash->virtual_memory = 
(chipaddr)programmer_map_flash_region("flash chip", base, size);
+               flash->virtual_memory = 
(chipaddr)programmer_map_flash_region("flash chip", base, size);
 
+               /* We handle a forced match like a real match, we just avoid 
probing. Note that probe_flash()
+                * is only called with force=1 after normal probing failed.
+                */
                if (force)
                        break;
 
-               if (fill_flash->probe(fill_flash) != 1)
+               if (flash->chip->probe(flash) != 1)
                        goto notfound;
 
                /* If this is the first chip found, accept it.
@@ -997,11 +1005,11 @@
                 * one for this programmer interface and thus no other chip has
                 * been found on this interface.
                 */
-               if (startchip == 0 && fill_flash->model_id == SFDP_DEVICE_ID) {
+               if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
                        msg_cinfo("===\n"
                                  "SFDP has autodetected a flash chip which is "
                                  "not natively supported by flashrom yet.\n");
-                       if (count_usable_erasers(fill_flash) == 0)
+                       if (count_usable_erasers(flash) == 0)
                                msg_cinfo("The standard operations read and "
                                          "verify should work, but to support "
                                          "erase, write and all other "
@@ -1022,15 +1030,18 @@
                }
 
                if (startchip == 0 ||
-                   ((fill_flash->model_id != GENERIC_DEVICE_ID) &&
-                    (fill_flash->model_id != SFDP_DEVICE_ID)))
+                   ((flash->chip->model_id != GENERIC_DEVICE_ID) &&
+                    (flash->chip->model_id != SFDP_DEVICE_ID)))
                        break;
 
 notfound:
-               programmer_unmap_flash_region((void 
*)fill_flash->virtual_memory, size);
+               programmer_unmap_flash_region((void *)flash->virtual_memory, 
size);
+               flash->virtual_memory = (chipaddr)NULL;
+               free(flash->chip);
+               flash->chip = NULL;
        }
 
-       if (!flash || !flash->name)
+       if (!flash->chip)
                return -1;
 
 #if CONFIG_INTERNAL == 1
@@ -1040,27 +1051,26 @@
 #endif
                snprintf(location, sizeof(location), "on %s", 
programmer_table[programmer].name);
 
-       tmp = flashbuses_to_text(flash->bustype);
-       msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n",
-                 force ? "Assuming" : "Found", fill_flash->vendor,
-                 fill_flash->name, fill_flash->total_size, tmp, location);
+       tmp = flashbuses_to_text(flash->chip->bustype);
+       msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) %s.\n", force ? 
"Assuming" : "Found",
+                 flash->chip->vendor, flash->chip->name, 
flash->chip->total_size, tmp, location);
        free(tmp);
 
        /* Flash registers will not be mapped if the chip was forced. Lock info
         * may be stored in registers, so avoid lock info printing.
         */
        if (!force)
-               if (fill_flash->printlock)
-                       fill_flash->printlock(fill_flash);
+               if (flash->chip->printlock)
+                       flash->chip->printlock(flash);
 
        /* Return position of matching chip. */
-       return flash - flashchips;
+       return chip - flashchips;
 }
 
 int verify_flash(struct flashctx *flash, uint8_t *buf)
 {
        int ret;
-       unsigned int total_size = flash->total_size * 1024;
+       unsigned int total_size = flash->chip->total_size * 1024;
 
        msg_cinfo("Verifying flash... ");
 
@@ -1133,7 +1143,7 @@
 
 int read_flash_to_file(struct flashctx *flash, const char *filename)
 {
-       unsigned long size = flash->total_size * 1024;
+       unsigned long size = flash->chip->total_size * 1024;
        unsigned char *buf = calloc(size, sizeof(char));
        int ret = 0;
 
@@ -1143,12 +1153,12 @@
                msg_cinfo("FAILED.\n");
                return 1;
        }
-       if (!flash->read) {
+       if (!flash->chip->read) {
                msg_cerr("No read function available for this flash chip.\n");
                ret = 1;
                goto out_free;
        }
-       if (flash->read(flash, buf, 0, size)) {
+       if (flash->chip->read(flash, buf, 0, size)) {
                msg_cerr("Read operation failed!\n");
                ret = 1;
                goto out_free;
@@ -1165,14 +1175,14 @@
  * walk_eraseregions().
  * Even if an error is found, the function will keep going and check the rest.
  */
-static int selfcheck_eraseblocks(const struct flashchip *flash)
+static int selfcheck_eraseblocks(const struct flashchip *chip)
 {
        int i, j, k;
        int ret = 0;
 
        for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
                unsigned int done = 0;
-               struct block_eraser eraser = flash->block_erasers[k];
+               struct block_eraser eraser = chip->block_erasers[k];
 
                for (i = 0; i < NUM_ERASEREGIONS; i++) {
                        /* Blocks with zero size are bugs in flashchips.c. */
@@ -1181,7 +1191,7 @@
                                msg_gerr("ERROR: Flash chip %s erase function "
                                        "%i region %i has size 0. Please report"
                                        " a bug at [email protected]\n",
-                                       flash->name, k, i);
+                                       chip->name, k, i);
                                ret = 1;
                        }
                        /* Blocks with zero count are bugs in flashchips.c. */
@@ -1190,7 +1200,7 @@
                                msg_gerr("ERROR: Flash chip %s erase function "
                                        "%i region %i has count 0. Please 
report"
                                        " a bug at [email protected]\n",
-                                       flash->name, k, i);
+                                       chip->name, k, i);
                                ret = 1;
                        }
                        done += eraser.eraseblocks[i].count *
@@ -1202,12 +1212,12 @@
                                  "non-empty erase function. Not an error.\n");
                if (!done)
                        continue;
-               if (done != flash->total_size * 1024) {
+               if (done != chip->total_size * 1024) {
                        msg_gerr("ERROR: Flash chip %s erase function %i "
                                "region walking resulted in 0x%06x bytes total,"
                                " expected 0x%06x bytes. Please report a bug at"
-                               " [email protected]\n", flash->name, k,
-                               done, flash->total_size * 1024);
+                               " [email protected]\n", chip->name, k,
+                               done, chip->total_size * 1024);
                        ret = 1;
                }
                if (!eraser.block_erase)
@@ -1218,11 +1228,11 @@
                 */
                for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
                        if (eraser.block_erase ==
-                           flash->block_erasers[j].block_erase) {
+                           chip->block_erasers[j].block_erase) {
                                msg_gerr("ERROR: Flash chip %s erase function "
                                        "%i and %i are identical. Please report"
                                        " a bug at [email protected]\n",
-                                       flash->name, k, j);
+                                       chip->name, k, j);
                                ret = 1;
                        }
                }
@@ -1269,7 +1279,7 @@
                if (!writecount++)
                        msg_cdbg("W");
                /* Needs the partial write function signature. */
-               ret = flash->write(flash, newcontents + starthere,
+               ret = flash->chip->write(flash, newcontents + starthere,
                                   start + starthere, lenhere);
                if (ret)
                        return ret;
@@ -1296,7 +1306,7 @@
        int i, j;
        unsigned int start = 0;
        unsigned int len;
-       struct block_eraser eraser = flash->block_erasers[erasefunction];
+       struct block_eraser eraser = flash->chip->block_erasers[erasefunction];
 
        for (i = 0; i < NUM_ERASEREGIONS; i++) {
                /* count==0 for all automatically initialized array
@@ -1322,7 +1332,7 @@
 
 static int check_block_eraser(const struct flashctx *flash, int k, int log)
 {
-       struct block_eraser eraser = flash->block_erasers[k];
+       struct block_eraser eraser = flash->chip->block_erasers[k];
 
        if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
                if (log)
@@ -1341,6 +1351,7 @@
                                 "eraseblock layout is not defined. ");
                return 1;
        }
+       // TODO: Once erase functions are annotated with allowed buses, check 
that as well.
        return 0;
 }
 
@@ -1349,7 +1360,7 @@
 {
        int k, ret = 1;
        uint8_t *curcontents;
-       unsigned long size = flash->total_size * 1024;
+       unsigned long size = flash->chip->total_size * 1024;
        unsigned int usable_erasefunctions = count_usable_erasers(flash);
 
        msg_cinfo("Erasing and writing flash chip... ");
@@ -1387,7 +1398,7 @@
                 * in non-verbose mode.
                 */
                msg_cinfo("Reading current flash chip contents... ");
-               if (flash->read(flash, curcontents, 0, size)) {
+               if (flash->chip->read(flash, curcontents, 0, size)) {
                        /* Now we are truly screwed. Read failed as well. */
                        msg_cerr("Can't read anymore! Aborting.\n");
                        /* We have no idea about the flash chip contents, so
@@ -1576,7 +1587,7 @@
 int selfcheck(void)
 {
        int ret = 0;
-       const struct flashchip *flash;
+       const struct flashchip *chip;
 
        /* Safety check. Instead of aborting after the first error, check
         * if more errors exist.
@@ -1594,16 +1605,8 @@
                msg_gerr("Flashchips table miscompilation!\n");
                ret = 1;
        }
-       /* Check that virtual_memory in struct flashctx is placed directly
-        * after the members copied from struct flashchip.
-        */
-       if (sizeof(struct flashchip) !=
-           offsetof(struct flashctx, virtual_memory)) {
-               msg_gerr("struct flashctx broken!\n");
-               ret = 1;
-       }
-       for (flash = flashchips; flash && flash->name; flash++)
-               if (selfcheck_eraseblocks(flash))
+       for (chip = flashchips; chip && chip->name; chip++)
+               if (selfcheck_eraseblocks(chip))
                        ret = 1;
 
 #if CONFIG_INTERNAL == 1
@@ -1627,41 +1630,41 @@
        return ret;
 }
 
-void check_chip_supported(const struct flashctx *flash)
+void check_chip_supported(const struct flashchip *chip)
 {
-       if (flash->feature_bits & FEATURE_OTP) {
+       if (chip->feature_bits & FEATURE_OTP) {
                msg_cdbg("This chip may contain one-time programmable memory. "
                         "flashrom cannot read\nand may never be able to write "
                         "it, hence it may not be able to completely\n"
                         "clone the contents of this chip (see man page for "
                         "details).\n");
        }
-       if (TEST_OK_MASK != (flash->tested & TEST_OK_MASK)) {
+       if (TEST_OK_MASK != (chip->tested & TEST_OK_MASK)) {
                msg_cinfo("===\n");
-               if (flash->tested & TEST_BAD_MASK) {
+               if (chip->tested & TEST_BAD_MASK) {
                        msg_cinfo("This flash part has status NOT WORKING for 
operations:");
-                       if (flash->tested & TEST_BAD_PROBE)
+                       if (chip->tested & TEST_BAD_PROBE)
                                msg_cinfo(" PROBE");
-                       if (flash->tested & TEST_BAD_READ)
+                       if (chip->tested & TEST_BAD_READ)
                                msg_cinfo(" READ");
-                       if (flash->tested & TEST_BAD_ERASE)
+                       if (chip->tested & TEST_BAD_ERASE)
                                msg_cinfo(" ERASE");
-                       if (flash->tested & TEST_BAD_WRITE)
+                       if (chip->tested & TEST_BAD_WRITE)
                                msg_cinfo(" WRITE");
                        msg_cinfo("\n");
                }
-               if ((!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & 
TEST_OK_PROBE)) ||
-                   (!(flash->tested & TEST_BAD_READ) && !(flash->tested & 
TEST_OK_READ)) ||
-                   (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & 
TEST_OK_ERASE)) ||
-                   (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & 
TEST_OK_WRITE))) {
+               if ((!(chip->tested & TEST_BAD_PROBE) && !(chip->tested & 
TEST_OK_PROBE)) ||
+                   (!(chip->tested & TEST_BAD_READ) && !(chip->tested & 
TEST_OK_READ)) ||
+                   (!(chip->tested & TEST_BAD_ERASE) && !(chip->tested & 
TEST_OK_ERASE)) ||
+                   (!(chip->tested & TEST_BAD_WRITE) && !(chip->tested & 
TEST_OK_WRITE))) {
                        msg_cinfo("This flash part has status UNTESTED for 
operations:");
-                       if (!(flash->tested & TEST_BAD_PROBE) && 
!(flash->tested & TEST_OK_PROBE))
+                       if (!(chip->tested & TEST_BAD_PROBE) && !(chip->tested 
& TEST_OK_PROBE))
                                msg_cinfo(" PROBE");
-                       if (!(flash->tested & TEST_BAD_READ) && !(flash->tested 
& TEST_OK_READ))
+                       if (!(chip->tested & TEST_BAD_READ) && !(chip->tested & 
TEST_OK_READ))
                                msg_cinfo(" READ");
-                       if (!(flash->tested & TEST_BAD_ERASE) && 
!(flash->tested & TEST_OK_ERASE))
+                       if (!(chip->tested & TEST_BAD_ERASE) && !(chip->tested 
& TEST_OK_ERASE))
                                msg_cinfo(" ERASE");
-                       if (!(flash->tested & TEST_BAD_WRITE) && 
!(flash->tested & TEST_OK_WRITE))
+                       if (!(chip->tested & TEST_BAD_WRITE) && !(chip->tested 
& TEST_OK_WRITE))
                                msg_cinfo(" WRITE");
                        msg_cinfo("\n");
                }
@@ -1702,13 +1705,13 @@
 
        if (read_it || erase_it || write_it || verify_it) {
                /* Everything needs read. */
-               if (flash->tested & TEST_BAD_READ) {
+               if (flash->chip->tested & TEST_BAD_READ) {
                        msg_cerr("Read is not working on this chip. ");
                        if (!force)
                                return 1;
                        msg_cerr("Continuing anyway.\n");
                }
-               if (!flash->read) {
+               if (!flash->chip->read) {
                        msg_cerr("flashrom has no read function for this "
                                 "flash chip.\n");
                        return 1;
@@ -1716,7 +1719,7 @@
        }
        if (erase_it || write_it) {
                /* Write needs erase. */
-               if (flash->tested & TEST_BAD_ERASE) {
+               if (flash->chip->tested & TEST_BAD_ERASE) {
                        msg_cerr("Erase is not working on this chip. ");
                        if (!force)
                                return 1;
@@ -1729,13 +1732,13 @@
                }
        }
        if (write_it) {
-               if (flash->tested & TEST_BAD_WRITE) {
+               if (flash->chip->tested & TEST_BAD_WRITE) {
                        msg_cerr("Write is not working on this chip. ");
                        if (!force)
                                return 1;
                        msg_cerr("Continuing anyway.\n");
                }
-               if (!flash->write) {
+               if (!flash->chip->write) {
                        msg_cerr("flashrom has no write function for this "
                                 "flash chip.\n");
                        return 1;
@@ -1754,7 +1757,7 @@
        uint8_t *oldcontents;
        uint8_t *newcontents;
        int ret = 0;
-       unsigned long size = flash->total_size * 1024;
+       unsigned long size = flash->chip->total_size * 1024;
 
        if (chip_safety_check(flash, force, read_it, write_it, erase_it, 
verify_it)) {
                msg_cerr("Aborting.\n");
@@ -1765,8 +1768,8 @@
        /* Given the existence of read locks, we want to unlock for read,
         * erase and write.
         */
-       if (flash->unlock)
-               flash->unlock(flash);
+       if (flash->chip->unlock)
+               flash->chip->unlock(flash);
 
        if (read_it) {
                ret = read_flash_to_file(flash, filename);
@@ -1829,7 +1832,7 @@
         * takes time as well.
         */
        msg_cinfo("Reading old flash chip contents... ");
-       if (flash->read(flash, oldcontents, 0, size)) {
+       if (flash->chip->read(flash, oldcontents, 0, size)) {
                ret = 1;
                msg_cinfo("FAILED.\n");
                goto out;
@@ -1846,7 +1849,7 @@
                if (erase_and_write_flash(flash, oldcontents, newcontents)) {
                        msg_cerr("Uh oh. Erase/write failed. Checking if "
                                 "anything changed.\n");
-                       if (!flash->read(flash, newcontents, 0, size)) {
+                       if (!flash->chip->read(flash, newcontents, 0, size)) {
                                if (!memcmp(oldcontents, newcontents, size)) {
                                        msg_cinfo("Good. It seems nothing was "
                                                  "changed.\n");
Index: flashrom-flashctx_separate_struct_flashchip/programmer.h
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/programmer.h    (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/programmer.h    (Arbeitskopie)
@@ -475,7 +475,7 @@
 extern struct decode_sizes max_rom_decode;
 extern int programmer_may_write;
 extern unsigned long flashbase;
-void check_chip_supported(const struct flashctx *flash);
+void check_chip_supported(const struct flashchip *chip);
 int check_max_decode(enum chipbustype buses, uint32_t size);
 char *extract_programmer_param(const char *param_name);
 
Index: flashrom-flashctx_separate_struct_flashchip/m29f400bt.c
===================================================================
--- flashrom-flashctx_separate_struct_flashchip/m29f400bt.c     (Revision 1576)
+++ flashrom-flashctx_separate_struct_flashchip/m29f400bt.c     (Arbeitskopie)
@@ -81,7 +81,7 @@
 
        msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
 
-       if (id1 == flash->manufacture_id && id2 == flash->model_id)
+       if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
                return 1;
 
        return 0;
@@ -130,7 +130,7 @@
 int block_erase_chip_m29f400bt(struct flashctx *flash, unsigned int address,
                               unsigned int blocklen)
 {
-       if ((address != 0) || (blocklen != flash->total_size * 1024)) {
+       if ((address != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;


-- 
http://www.hailfinger.org/


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

Reply via email to