Please note that this patch breaks every programmer except hwseq because
we're not passing struct flashchip around yet. To get this working, the
following changes have to be made:
- Pass struct flashchip * everywhere (or struct flashctx *), see my
other patch for that
- Change parallel-style and SPI programmers to use flash->pgm... instead
of par_programmer->... and spi_programmer->...

This compiles and should help you review it, but it is not for merge
until the "struct flashchip * everywhere" patch is in.
Some code has been removed with #if 0 because I wanted to discuss
removing it. The final patch will have no #if 0 at all.

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

Index: flashrom-register_all_programmers_register_generic/flash.h
===================================================================
--- flashrom-register_all_programmers_register_generic/flash.h  (Revision 1463)
+++ flashrom-register_all_programmers_register_generic/flash.h  (Arbeitskopie)
@@ -153,6 +153,7 @@
        /* Some flash devices have an additional register space. */
        chipaddr virtual_memory;
        chipaddr virtual_registers;
+       struct registered_programmer *pgm;
 };
 
 #define TEST_UNTESTED  0
@@ -197,14 +198,13 @@
        write_gran_1byte,
        write_gran_256bytes,
 };
-extern enum chipbustype buses_supported;
 extern int verbose;
 extern const char flashrom_version[];
 extern char *chip_to_probe;
 void map_flash_registers(struct flashchip *flash);
 int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len);
 int erase_flash(struct flashchip *flash);
-int probe_flash(int startchip, struct flashchip *fill_flash, int force);
+int probe_flash(struct registered_programmer *pgm, int startchip, struct 
flashchip *fill_flash, int force);
 int read_flash_to_file(struct flashchip *flash, const char *filename);
 int min(int a, int b);
 int max(int a, int b);
@@ -271,4 +271,5 @@
 int spi_send_multicommand(struct spi_command *cmds);
 uint32_t spi_get_valid_read_addr(void);
 
+enum chipbustype get_buses_supported(void);
 #endif                         /* !__FLASH_H__ */
Index: flashrom-register_all_programmers_register_generic/cli_classic.c
===================================================================
--- flashrom-register_all_programmers_register_generic/cli_classic.c    
(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/cli_classic.c    
(Arbeitskopie)
@@ -172,7 +172,7 @@
        struct flashchip flashes[3];
        struct flashchip *fill_flash;
        const char *name;
-       int namelen, opt, i;
+       int namelen, opt, i, j;
        int startchip = 0, chipcount = 0, option_index = 0, force = 0;
 #if CONFIG_PRINT_WIKI == 1
        int list_supported_wiki = 0;
@@ -443,17 +443,21 @@
                ret = 1;
                goto out_shutdown;
        }
-       tempstr = flashbuses_to_text(buses_supported);
+       tempstr = flashbuses_to_text(get_buses_supported());
        msg_pdbg("This programmer supports the following protocols: %s.\n",
                 tempstr);
        free(tempstr);
 
-       for (i = 0; i < ARRAY_SIZE(flashes); i++) {
-               startchip = probe_flash(startchip, &flashes[i], 0);
-               if (startchip == -1)
-                       break;
-               chipcount++;
-               startchip++;
+       for (j = 0; j < registered_programmer_count; j++) {
+               startchip = 0;
+               for (i = 0; i < ARRAY_SIZE(flashes); i++) {
+                       startchip = probe_flash(&registered_programmers[j],
+                                               startchip, &flashes[i], 0);
+                       if (startchip == -1)
+                               break;
+                       chipcount++;
+                       startchip++;
+               }
        }
 
        if (chipcount > 1) {
@@ -471,6 +475,7 @@
                        printf("Note: flashrom can never write if the flash "
                               "chip isn't found automatically.\n");
                }
+#if 0 // FIXME: What happens for a forced chip read if multiple compatible 
programmers are registered?
                if (force && read_it && chip_to_probe) {
                        printf("Force read (-f -r -c) requested, pretending "
                               "the chip is there:\n");
@@ -485,6 +490,7 @@
                               "contain garbage.\n");
                        return read_flash_to_file(&flashes[0], filename);
                }
+#endif
                ret = 1;
                goto out_shutdown;
        } else if (!chip_to_probe) {
@@ -501,7 +507,7 @@
        check_chip_supported(fill_flash);
 
        size = fill_flash->total_size * 1024;
-       if (check_max_decode((buses_supported & fill_flash->bustype), size) &&
+       if (check_max_decode((get_buses_supported() & fill_flash->bustype), 
size) &&
            (!force)) {
                fprintf(stderr, "Chip is too big for this programmer "
                        "(-V gives details). Use --force to override.\n");
Index: flashrom-register_all_programmers_register_generic/ichspi.c
===================================================================
--- flashrom-register_all_programmers_register_generic/ichspi.c (Revision 1463)
+++ flashrom-register_all_programmers_register_generic/ichspi.c (Arbeitskopie)
@@ -1295,7 +1295,7 @@
        REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS));
 
        while (len > 0) {
-               block_len = min(len, opaque_programmer->max_data_read);
+               block_len = min(len, flash->pgm->opaque.max_data_read);
                ich_hwseq_set_addr(addr);
                hsfc = REGREAD16(ICH9_REG_HSFC);
                hsfc &= ~HSFC_FCYCLE; /* set read operation */
@@ -1333,7 +1333,7 @@
 
        while (len > 0) {
                ich_hwseq_set_addr(addr);
-               block_len = min(len, opaque_programmer->max_data_write);
+               block_len = min(len, flash->pgm->opaque.max_data_write);
                ich_fill_data(buf, block_len, ICH9_REG_FDATA0);
                hsfc = REGREAD16(ICH9_REG_HSFC);
                hsfc &= ~HSFC_FCYCLE; /* clear operation */
Index: flashrom-register_all_programmers_register_generic/opaque.c
===================================================================
--- flashrom-register_all_programmers_register_generic/opaque.c (Revision 1463)
+++ flashrom-register_all_programmers_register_generic/opaque.c (Arbeitskopie)
@@ -30,70 +30,62 @@
 #include "chipdrivers.h"
 #include "programmer.h"
 
-const struct opaque_programmer opaque_programmer_none = {
-       .max_data_read = MAX_DATA_UNSPECIFIED,
-       .max_data_write = MAX_DATA_UNSPECIFIED,
-       .probe = NULL,
-       .read = NULL,
-       .write = NULL,
-       .erase = NULL,
-};
-
-const struct opaque_programmer *opaque_programmer = &opaque_programmer_none;
-
 int probe_opaque(struct flashchip *flash)
 {
-       if (!opaque_programmer->probe) {
+       if (!flash->pgm->opaque.probe) {
                msg_perr("%s called before register_opaque_programmer. "
                         "Please report a bug at [email protected]\n",
                         __func__);
                return 0;
        }
 
-       return opaque_programmer->probe(flash);
+       return flash->pgm->opaque.probe(flash);
 }
 
 int read_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-       if (!opaque_programmer->read) {
+       if (!flash->pgm->opaque.read) {
                msg_perr("%s called before register_opaque_programmer. "
                         "Please report a bug at [email protected]\n",
                         __func__);
                return 1;
        }
-       return opaque_programmer->read(flash, buf, start, len);
+       return flash->pgm->opaque.read(flash, buf, start, len);
 }
 
 int write_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-       if (!opaque_programmer->write) {
+       if (!flash->pgm->opaque.write) {
                msg_perr("%s called before register_opaque_programmer. "
                         "Please report a bug at [email protected]\n",
                         __func__);
                return 1;
        }
-       return opaque_programmer->write(flash, buf, start, len);
+       return flash->pgm->opaque.write(flash, buf, start, len);
 }
 
 int erase_opaque(struct flashchip *flash, unsigned int blockaddr, unsigned int 
blocklen)
 {
-       if (!opaque_programmer->erase) {
+       if (!flash->pgm->opaque.erase) {
                msg_perr("%s called before register_opaque_programmer. "
                         "Please report a bug at [email protected]\n",
                         __func__);
                return 1;
        }
-       return opaque_programmer->erase(flash, blockaddr, blocklen);
+       return flash->pgm->opaque.erase(flash, blockaddr, blocklen);
 }
 
 void register_opaque_programmer(const struct opaque_programmer *pgm)
 {
+       struct registered_programmer rpgm;
+
        if (!pgm->probe || !pgm->read || !pgm->write || !pgm->erase) {
                msg_perr("%s called with one of probe/read/write/erase being "
                         "NULL. Please report a bug at [email protected]\n",
                         __func__);
                return;
        }
-       opaque_programmer = pgm;
-       buses_supported |= BUS_PROG;
+       rpgm.buses_supported = BUS_PROG;
+       rpgm.opaque = *pgm;
+       register_programmer(&rpgm);
 }
Index: flashrom-register_all_programmers_register_generic/spi.c
===================================================================
--- flashrom-register_all_programmers_register_generic/spi.c    (Revision 1463)
+++ flashrom-register_all_programmers_register_generic/spi.c    (Arbeitskopie)
@@ -194,6 +194,9 @@
 
 void register_spi_programmer(const struct spi_programmer *pgm)
 {
-       spi_programmer = pgm;
-       buses_supported |= BUS_SPI;
+       struct registered_programmer rpgm;
+
+       rpgm.buses_supported = BUS_SPI;
+       rpgm.spi = *pgm;
+       register_programmer(&rpgm);
 }
Index: flashrom-register_all_programmers_register_generic/programmer.c
===================================================================
--- flashrom-register_all_programmers_register_generic/programmer.c     
(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/programmer.c     
(Arbeitskopie)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the flashrom project.
  *
- * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2009,2010,2011 Carl-Daniel Hailfinger
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,6 +113,38 @@
 
 void register_par_programmer(const struct par_programmer *pgm, const enum 
chipbustype buses)
 {
-       par_programmer = pgm;
-       buses_supported |= buses;
+       struct registered_programmer rpgm;
+
+       rpgm.buses_supported = buses;
+       rpgm.par = *pgm;
+       register_programmer(&rpgm);
 }
+
+/* The limit of 4 is totally arbitrary. */
+#define PROGRAMMERS_MAX 4
+struct registered_programmer registered_programmers[PROGRAMMERS_MAX];
+int registered_programmer_count = 0;
+
+int register_programmer(struct registered_programmer *pgm)
+{
+       if (registered_programmer_count >= PROGRAMMERS_MAX) {
+               msg_perr("Tried to register more than %i programmer "
+                        "interfaces.\n", PROGRAMMERS_MAX);
+               return 1;
+       }
+       registered_programmers[registered_programmer_count] = *pgm;
+       registered_programmer_count++;
+
+       return 0;
+}
+
+enum chipbustype get_buses_supported(void)
+{
+       int i;
+       enum chipbustype ret = BUS_NONE;
+
+       for (i = 0; i < registered_programmer_count; i++)
+               ret |= registered_programmers[i].buses_supported;
+
+       return ret;
+}
Index: flashrom-register_all_programmers_register_generic/flashrom.c
===================================================================
--- flashrom-register_all_programmers_register_generic/flashrom.c       
(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/flashrom.c       
(Arbeitskopie)
@@ -46,9 +46,6 @@
 
 static char *programmer_param = NULL;
 
-/* Supported buses for the current programmer. */
-enum chipbustype buses_supported;
-
 /*
  * Programmers supporting multiple buses can have differing size limits on
  * each bus. Store the limits for each bus in a common struct.
@@ -314,7 +311,6 @@
                .fwh            = 0xffffffff,
                .spi            = 0xffffffff,
        };
-       buses_supported = BUS_NONE;
        /* Default to top aligned flash at 4 GB. */
        flashbase = 0;
        /* Registering shutdown functions is now allowed. */
@@ -936,7 +932,8 @@
        return 1;
 }
 
-int probe_flash(int startchip, struct flashchip *fill_flash, int force)
+int probe_flash(struct registered_programmer *pgm, int startchip,
+               struct flashchip *fill_flash, int force)
 {
        const struct flashchip *flash;
        unsigned long base = 0;
@@ -948,11 +945,12 @@
        for (flash = flashchips + startchip; flash && flash->name; flash++) {
                if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
                        continue;
-               buses_common = buses_supported & flash->bustype;
+               buses_common = pgm->buses_supported & flash->bustype;
                if (!buses_common) {
+#if 0 // Does not really make sense anymore if we use a programmer-centric 
walk.
                        msg_gspew("Probing for %s %s, %d kB: skipped. ",
                                 flash->vendor, flash->name, flash->total_size);
-                       tmp = flashbuses_to_text(buses_supported);
+                       tmp = flashbuses_to_text(get_buses_supported());
                        msg_gspew("Host bus type %s ", tmp);
                        free(tmp);
                        tmp = flashbuses_to_text(flash->bustype);
@@ -960,6 +958,7 @@
                                  tmp);
                        free(tmp);
                        msg_gspew("\n");
+#endif
                        continue;
                }
                msg_gdbg("Probing for %s %s, %d kB: ",
@@ -975,6 +974,7 @@
 
                /* Start filling in the dynamic data. */
                *fill_flash = *flash;
+               fill_flash->pgm = pgm;
 
                base = flashbase ? flashbase : (0xffffffff - size + 1);
                fill_flash->virtual_memory = 
(chipaddr)programmer_map_flash_region("flash chip", base, size);
Index: flashrom-register_all_programmers_register_generic/programmer.h
===================================================================
--- flashrom-register_all_programmers_register_generic/programmer.h     
(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/programmer.h     
(Arbeitskopie)
@@ -93,8 +93,8 @@
 
        int (*init) (void);
 
-       void * (*map_flash_region) (const char *descr, unsigned long phys_addr,
-                                   size_t len);
+       void *(*map_flash_region) (const char *descr, unsigned long phys_addr,
+                                  size_t len);
        void (*unmap_flash_region) (void *virt_addr, size_t len);
 
        void (*delay) (int usecs);
@@ -341,31 +341,6 @@
 void rmmio_valw(void *addr);
 void rmmio_vall(void *addr);
 
-/* programmer.c */
-int noop_shutdown(void);
-void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
-void fallback_unmap(void *virt_addr, size_t len);
-uint8_t noop_chip_readb(const chipaddr addr);
-void noop_chip_writeb(uint8_t val, chipaddr addr);
-void fallback_chip_writew(uint16_t val, chipaddr addr);
-void fallback_chip_writel(uint32_t val, chipaddr addr);
-void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
-uint16_t fallback_chip_readw(const chipaddr addr);
-uint32_t fallback_chip_readl(const chipaddr addr);
-void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
-struct par_programmer {
-       void (*chip_writeb) (uint8_t val, chipaddr addr);
-       void (*chip_writew) (uint16_t val, chipaddr addr);
-       void (*chip_writel) (uint32_t val, chipaddr addr);
-       void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len);
-       uint8_t (*chip_readb) (const chipaddr addr);
-       uint16_t (*chip_readw) (const chipaddr addr);
-       uint32_t (*chip_readl) (const chipaddr addr);
-       void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
-};
-extern const struct par_programmer *par_programmer;
-void register_par_programmer(const struct par_programmer *pgm, const enum 
chipbustype buses);
-
 /* dummyflasher.c */
 #if CONFIG_DUMMY == 1
 int dummy_init(void);
@@ -632,6 +607,42 @@
 extern const struct opaque_programmer *opaque_programmer;
 void register_opaque_programmer(const struct opaque_programmer *pgm);
 
+/* programmer.c */
+int noop_shutdown(void);
+void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
+void fallback_unmap(void *virt_addr, size_t len);
+uint8_t noop_chip_readb(const chipaddr addr);
+void noop_chip_writeb(uint8_t val, chipaddr addr);
+void fallback_chip_writew(uint16_t val, chipaddr addr);
+void fallback_chip_writel(uint32_t val, chipaddr addr);
+void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
+uint16_t fallback_chip_readw(const chipaddr addr);
+uint32_t fallback_chip_readl(const chipaddr addr);
+void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
+struct par_programmer {
+       void (*chip_writeb) (uint8_t val, chipaddr addr);
+       void (*chip_writew) (uint16_t val, chipaddr addr);
+       void (*chip_writel) (uint32_t val, chipaddr addr);
+       void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len);
+       uint8_t (*chip_readb) (const chipaddr addr);
+       uint16_t (*chip_readw) (const chipaddr addr);
+       uint32_t (*chip_readl) (const chipaddr addr);
+       void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
+};
+extern const struct par_programmer *par_programmer;
+void register_par_programmer(const struct par_programmer *pgm, const enum 
chipbustype buses);
+struct registered_programmer {
+       enum chipbustype buses_supported;
+       union {
+               struct par_programmer par;
+               struct spi_programmer spi;
+               struct opaque_programmer opaque;
+       };
+};
+extern struct registered_programmer registered_programmers[];
+extern int registered_programmer_count;
+int register_programmer(struct registered_programmer *pgm);
+
 /* serprog.c */
 #if CONFIG_SERPROG == 1
 int serprog_init(void);


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


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

Reply via email to