[flashrom] [PATCH] Register Parallel/LPC/FWH programmers

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Mon Nov 7 14:47:42 CET 2011


Am 09.09.2011 19:55 schrieb Carl-Daniel Hailfinger:
> Am 08.09.2011 23:36 schrieb Stefan Tauner:
>> On Thu, 08 Sep 2011 02:14:06 +0200
>> Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net> wrote:
>>   
>>> RFC/TODO:
>>> - Should register_par_programmer(...) be called before or after setting
>>>   max_rom_decode.*?
>> why is that not a field in the different programmer structs (yet?)?
> Given that the registration for parallel and SPI programmers is pretty
> different but max_rom_decode.* is used from common code, it is not
> immediately obvious to handle this sanely. Supply it as
> register_par_programmer() parameter and extend register_spi_programmer
> to accept that parameter as well?

I'm now setting max_rom_decode before calling register_par_programmer.
Given that such restrictions may exist for any programmer, I'll postpone
handling max_rom_decode to the universal programmer registration patch
where we get the infrastructure to deal with such programmer
limitations. If you have any objections, please tell me.

 
>>> - Should register_par_programmer(...) be called before or after
>>>   register_shutdown()?
>>>     
>> like register_spi_programmer (no idea when that is, but consistency is
>> the one main argument i can think of atm)
>>   
> They should be called after register_shutdown, otherwise there is a time
> when chip access functions are callable although the programmer has
> already been shut down. Will audit the code and change where appropriate.

Done.

 
>>> - Is there a better name for register_par_programmer?
>>>     
>> register_parallel_programmer ofc, and imho it is not too long, because
>> it is seldom used, but i don't care that much (due to the same reason).
>>   
> 80 column limit... I think that was one of the reasons we used a shorter
> name.
>
>>> - Should max_rom_decode.* be part of the registration?
>>>     
>> either that or declaration, see question above. if it has to be
>> modified (board enables do this it seems...), this can't be done at
>> registration (only)...
>>   
> Same trick as buses_supported. Have a local static (not part of the
> official interface) chipset_max_rom_decode variable which can be
> modified by chipset/mainboard init, and then use the end result in
> registration.

max_rom_decode is conceptually different from buses_supported although
that was not obvious when I wrote the paragraph above. It will be
handled in the universal programmer registration patch.


>>> - Should map_flash_region/unmap_flash_region be part of the registration?
>>>     
>> no idea what that does exactly :P
>>   
> It makes the flash chip accessible. This is essentially physmap for
> programmers with memory mapped flash and a no-op for everything else.

And moving it into the parallel programmer struct may not have been the
best idea. Sure, that gets it out of the way conveniently, but once the
universal programmer registration patch is in, we will not have any
dummy parallel programmer struct for such fallbacks anymore. This will
cause all sorts of design headaches which are not obvious right now.

New version.
Testing on all programmers is very appreciated.

Register Parallel/LPC/FWH programmers the same way SPI programmers are registered.

Additional fixes:
Set max_rom_decode.parallel for drkaiser.
Remove abuse of programmer_map_flash_region in it85spi.
Annotate several FIXMEs in it85spi.

Note: Programmers without parallel/LPC/FWH chip support should not call
register_par_programmer().

I did not check for 80 column limit violations, but the rest should be OK.

We need something like this patch to handle programmers with multiple
flash chips (e.g. LPC/FWH chips mapped to different regions on mainboards).

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Index: flashrom-register_par_programmer/drkaiser.c
===================================================================
--- flashrom-register_par_programmer/drkaiser.c	(Revision 1460)
+++ flashrom-register_par_programmer/drkaiser.c	(Arbeitskopie)
@@ -39,6 +39,17 @@
 
 static uint8_t *drkaiser_bar;
 
+static const struct par_programmer par_programmer_drkaiser = {
+		.chip_readb		= drkaiser_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= drkaiser_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int drkaiser_shutdown(void *data)
 {
 	physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE);
@@ -64,10 +75,12 @@
 	drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory",
 			       addr, DRKAISER_MEMMAP_SIZE);
 
-	buses_supported = BUS_PARALLEL;
-
 	if (register_shutdown(drkaiser_shutdown, NULL))
 		return 1;
+
+	max_rom_decode.parallel = 131072;
+	register_par_programmer(&par_programmer_drkaiser, BUS_PARALLEL);
+
 	return 0;
 }
 
Index: flashrom-register_par_programmer/it87spi.c
===================================================================
--- flashrom-register_par_programmer/it87spi.c	(Revision 1460)
+++ flashrom-register_par_programmer/it87spi.c	(Arbeitskopie)
@@ -192,7 +192,7 @@
 	free(portpos);
 	exit_conf_mode_ite(port);
 	it8716f_flashport = flashport;
-	if (buses_supported & BUS_SPI)
+	if (internal_buses_supported & BUS_SPI)
 		msg_pdbg("Overriding chipset SPI with IT87 SPI.\n");
 	/* FIXME: Add the SPI bus or replace the other buses with it? */
 	register_spi_programmer(&spi_programmer_it87xx);
Index: flashrom-register_par_programmer/gfxnvidia.c
===================================================================
--- flashrom-register_par_programmer/gfxnvidia.c	(Revision 1460)
+++ flashrom-register_par_programmer/gfxnvidia.c	(Arbeitskopie)
@@ -61,6 +61,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_gfxnvidia = {
+		.chip_readb		= gfxnvidia_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= gfxnvidia_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int gfxnvidia_shutdown(void *data)
 {
 	physunmap(nvidia_bar, GFXNVIDIA_MEMMAP_SIZE);
@@ -94,10 +105,9 @@
 	reg32 &= ~(1 << 0);
 	rpci_write_long(pcidev_dev, 0x50, reg32);
 
-	buses_supported = BUS_PARALLEL;
-
 	/* Write/erase doesn't work. */
 	programmer_may_write = 0;
+	register_par_programmer(&par_programmer_gfxnvidia, BUS_PARALLEL);
 
 	return 0;
 }
Index: flashrom-register_par_programmer/nicrealtek.c
===================================================================
--- flashrom-register_par_programmer/nicrealtek.c	(Revision 1460)
+++ flashrom-register_par_programmer/nicrealtek.c	(Arbeitskopie)
@@ -36,6 +36,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_nicrealtek = {
+		.chip_readb		= nicrealtek_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicrealtek_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int nicrealtek_shutdown(void *data)
 {
 	/* FIXME: We forgot to disable software access again. */
@@ -50,10 +61,11 @@
 
 	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
 
-	buses_supported = BUS_PARALLEL;
-
 	if (register_shutdown(nicrealtek_shutdown, NULL))
 		return 1;
+
+	register_par_programmer(&par_programmer_nicrealtek, BUS_PARALLEL);
+
 	return 0;
 }
 
Index: flashrom-register_par_programmer/serprog.c
===================================================================
--- flashrom-register_par_programmer/serprog.c	(Revision 1460)
+++ flashrom-register_par_programmer/serprog.c	(Arbeitskopie)
@@ -299,6 +299,11 @@
 	return 0;
 }
 
+static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr);
+static int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start,
+			    int len);
 static struct spi_programmer spi_programmer_serprog = {
 	.type		= SPI_CONTROLLER_SERPROG,
 	.max_data_read	= MAX_DATA_READ_UNLIMITED,
@@ -309,6 +314,19 @@
 	.write_256	= default_spi_write_256,
 };
 
+static const struct par_programmer par_programmer_serprog = {
+		.chip_readb		= serprog_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= serprog_chip_readn,
+		.chip_writeb		= serprog_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
+static enum chipbustype serprog_buses_supported = BUS_NONE;
+
 int serprog_init(void)
 {
 	uint16_t iface;
@@ -400,41 +418,45 @@
 
 	if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
 		msg_perr("Error: NAK to query interface version\n");
-		exit(1);
+		return 1;
 	}
 
 	if (iface != 1) {
 		msg_perr("Error: Unknown interface version: %d\n", iface);
-		exit(1);
+		return 1;
 	}
 
 	msg_pdbg(MSGHEADER "Interface version ok.\n");
 
 	if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
 		msg_perr("Error: query command map not supported\n");
-		exit(1);
+		return 1;
 	}
 
 	sp_check_avail_automatic = 1;
 
-
+	/* FIXME: This assumes that serprog device bustypes are always
+	 * identical with flashrom bustype enums and that they all fit
+	 * in a single byte.
+	 */
 	if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
 		msg_perr("Warning: NAK to query supported buses\n");
 		c = BUS_NONSPI;	/* A reasonable default for now. */
 	}
-	buses_supported = c;
+	serprog_buses_supported = c;
+
 	msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
 		 (c & BUS_PARALLEL) ? "on" : "off",
 		 (c & BUS_LPC) ? "on" : "off",
 		 (c & BUS_FWH) ? "on" : "off",
 		 (c & BUS_SPI) ? "on" : "off");
 	/* Check for the minimum operational set of commands. */
-	if (buses_supported & BUS_SPI) {
+	if (serprog_buses_supported & BUS_SPI) {
 		uint8_t bt = BUS_SPI;
 		if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
 			msg_perr("Error: SPI operation not supported while the "
 				 "bustype is SPI\n");
-			exit(1);
+			return 1;
 		}
 		/* Success of any of these commands is optional. We don't need
 		   the programmer to tell us its limits, but if it doesn't, we
@@ -461,40 +483,39 @@
 			spi_programmer_serprog.max_data_read = v;
 			msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
 		}
-		bt = buses_supported;
+		bt = serprog_buses_supported;
 		sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
-		register_spi_programmer(&spi_programmer_serprog);
 	}
 
-	if (buses_supported & BUS_NONSPI) {
+	if (serprog_buses_supported & BUS_NONSPI) {
 		if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
 			msg_perr("Error: Initialize operation buffer "
 				 "not supported\n");
-			exit(1);
+			return 1;
 		}
 
 		if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
 			msg_perr("Error: Write to opbuf: "
 				 "delay not supported\n");
-			exit(1);
+			return 1;
 		}
 
 		/* S_CMD_O_EXEC availability checked later. */
 
 		if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
 			msg_perr("Error: Single byte read not supported\n");
-			exit(1);
+			return 1;
 		}
 		/* This could be translated to single byte reads (if missing),
 		 * but now we don't support that. */
 		if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
 			msg_perr("Error: Read n bytes not supported\n");
-			exit(1);
+			return 1;
 		}
 		if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
 			msg_perr("Error: Write to opbuf: "
 				 "write byte not supported\n");
-			exit(1);
+			return 1;
 		}
 
 		if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
@@ -513,7 +534,7 @@
 			if (!sp_write_n_buf) {
 				msg_perr("Error: cannot allocate memory for "
 					 "Write-n buffer\n");
-				exit(1);
+				return 1;
 			}
 			sp_write_n_bytes = 0;
 		}
@@ -551,12 +572,12 @@
 		if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
 			msg_perr("Error: Execute operation buffer not "
 				 "supported\n");
-			exit(1);
+			return 1;
 		}
 
 		if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
 			msg_perr("Error: NAK to initialize operation buffer\n");
-			exit(1);
+			return 1;
 		}
 
 		if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
@@ -572,6 +593,11 @@
 	sp_streamed_transmit_ops = 0;
 	sp_streamed_transmit_bytes = 0;
 	sp_opbuf_usage = 0;
+	if (serprog_buses_supported & BUS_SPI)
+		register_spi_programmer(&spi_programmer_serprog);
+	if (serprog_buses_supported & BUS_NONSPI)
+		register_par_programmer(&par_programmer_serprog,
+					serprog_buses_supported & BUS_NONSPI);
 	return 0;
 }
 
@@ -766,7 +792,7 @@
 	sp_prev_was_write = 0;
 }
 
-int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 			     const unsigned char *writearr,
 			     unsigned char *readarr)
 {
@@ -796,7 +822,7 @@
  * the advantage that it is much faster for most chips, but breaks those with
  * non-contiguous address space (like AT45DB161D). When spi_read_chunked is
  * fixed this method can be removed. */
-int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
+static int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
 	int i;
 	int cur_len;
Index: flashrom-register_par_programmer/satamv.c
===================================================================
--- flashrom-register_par_programmer/satamv.c	(Revision 1460)
+++ flashrom-register_par_programmer/satamv.c	(Arbeitskopie)
@@ -41,6 +41,17 @@
 #define PCI_BAR2_CONTROL		0x00c08
 #define GPIO_PORT_CONTROL		0x104f0
 
+static const struct par_programmer par_programmer_satamv = {
+		.chip_readb		= satamv_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= satamv_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int satamv_shutdown(void *data)
 {
 	physunmap(mv_bar, 0x20000);
@@ -137,11 +148,10 @@
 	mv_iobar = tmp & 0xffff;
 	msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar);
 
-	buses_supported = BUS_PARALLEL;
-
 	/* 512 kByte with two 8-bit latches, and
 	 * 4 MByte with additional 3-bit latch. */
 	max_rom_decode.parallel = 4 * 1024 * 1024;
+	register_par_programmer(&par_programmer_satamv, BUS_PARALLEL);
 
 	return 0;
 
Index: flashrom-register_par_programmer/dummyflasher.c
===================================================================
--- flashrom-register_par_programmer/dummyflasher.c	(Revision 1460)
+++ flashrom-register_par_programmer/dummyflasher.c	(Arbeitskopie)
@@ -75,6 +75,19 @@
 	.write_256	= dummy_spi_write_256,
 };
 
+static const struct par_programmer par_programmer_dummy = {
+		.chip_readb		= dummy_chip_readb,
+		.chip_readw		= dummy_chip_readw,
+		.chip_readl		= dummy_chip_readl,
+		.chip_readn		= dummy_chip_readn,
+		.chip_writeb		= dummy_chip_writeb,
+		.chip_writew		= dummy_chip_writew,
+		.chip_writel		= dummy_chip_writel,
+		.chip_writen		= dummy_chip_writen,
+};
+
+enum chipbustype dummy_buses_supported = BUS_NONE;
+
 static int dummy_shutdown(void *data)
 {
 	msg_pspew("%s\n", __func__);
@@ -108,24 +121,24 @@
 	/* Convert the parameters to lowercase. */
 	tolower_string(bustext);
 
-	buses_supported = BUS_NONE;
+	dummy_buses_supported = BUS_NONE;
 	if (strstr(bustext, "parallel")) {
-		buses_supported |= BUS_PARALLEL;
+		dummy_buses_supported |= BUS_PARALLEL;
 		msg_pdbg("Enabling support for %s flash.\n", "parallel");
 	}
 	if (strstr(bustext, "lpc")) {
-		buses_supported |= BUS_LPC;
+		dummy_buses_supported |= BUS_LPC;
 		msg_pdbg("Enabling support for %s flash.\n", "LPC");
 	}
 	if (strstr(bustext, "fwh")) {
-		buses_supported |= BUS_FWH;
+		dummy_buses_supported |= BUS_FWH;
 		msg_pdbg("Enabling support for %s flash.\n", "FWH");
 	}
 	if (strstr(bustext, "spi")) {
-		register_spi_programmer(&spi_programmer_dummyflasher);
+		dummy_buses_supported |= BUS_SPI;
 		msg_pdbg("Enabling support for %s flash.\n", "SPI");
 	}
-	if (buses_supported == BUS_NONE)
+	if (dummy_buses_supported == BUS_NONE)
 		msg_pdbg("Support for all flash bus types disabled.\n");
 	free(bustext);
 
@@ -226,6 +239,14 @@
 		free(flashchip_contents);
 		return 1;
 	}
+	if (dummy_buses_supported & (BUS_PARALLEL | BUS_LPC | BUS_FWH))
+		register_par_programmer(&par_programmer_dummy,
+					dummy_buses_supported &
+						(BUS_PARALLEL | BUS_LPC |
+						 BUS_FWH));
+	if (dummy_buses_supported & BUS_SPI)
+		register_spi_programmer(&spi_programmer_dummyflasher);
+
 	return 0;
 }
 
Index: flashrom-register_par_programmer/cli_classic.c
===================================================================
--- flashrom-register_par_programmer/cli_classic.c	(Revision 1460)
+++ flashrom-register_par_programmer/cli_classic.c	(Arbeitskopie)
@@ -443,6 +443,10 @@
 		ret = 1;
 		goto out_shutdown;
 	}
+	tempstr = flashbuses_to_text(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);
Index: flashrom-register_par_programmer/internal.c
===================================================================
--- flashrom-register_par_programmer/internal.c	(Revision 1460)
+++ flashrom-register_par_programmer/internal.c	(Arbeitskopie)
@@ -127,6 +127,19 @@
 int is_laptop = 0;
 int laptop_ok = 0;
 
+static const struct par_programmer par_programmer_internal = {
+		.chip_readb		= internal_chip_readb,
+		.chip_readw		= internal_chip_readw,
+		.chip_readl		= internal_chip_readl,
+		.chip_readn		= internal_chip_readn,
+		.chip_writeb		= internal_chip_writeb,
+		.chip_writew		= internal_chip_writew,
+		.chip_writel		= internal_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
+enum chipbustype internal_buses_supported = BUS_NONE;
+
 static int internal_shutdown(void *data)
 {
 	release_io_perms();
@@ -191,9 +204,10 @@
 		return 1;
 
 	/* Default to Parallel/LPC/FWH flash devices. If a known host controller
-	 * is found, the init routine sets the buses_supported bitfield.
+	 * is found, the host controller init routine sets the
+	 * internal_buses_supported bitfield.
 	 */
-	buses_supported = BUS_NONSPI;
+	internal_buses_supported = BUS_NONSPI;
 
 	/* Initialize PCI access for flash enables */
 	pacc = pci_alloc();	/* Get the pci_access structure */
@@ -287,6 +301,7 @@
 	 * Besides that, we don't check the board enable return code either.
 	 */
 #if defined(__i386__) || defined(__x86_64__) || defined (__mips)
+	register_par_programmer(&par_programmer_internal, internal_buses_supported);
 	return 0;
 #else
 	msg_perr("Your platform is not supported yet for the internal "
Index: flashrom-register_par_programmer/ichspi.c
===================================================================
--- flashrom-register_par_programmer/ichspi.c	(Revision 1460)
+++ flashrom-register_par_programmer/ichspi.c	(Arbeitskopie)
@@ -1507,7 +1507,7 @@
 	ich_spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
 
 	/* Not sure if it speaks all these bus protocols. */
-	buses_supported = BUS_LPC | BUS_FWH;
+	internal_buses_supported = BUS_LPC | BUS_FWH;
 	ich_generation = CHIPSET_ICH7;
 	register_spi_programmer(&spi_programmer_via);
 
Index: flashrom-register_par_programmer/nicnatsemi.c
===================================================================
--- flashrom-register_par_programmer/nicnatsemi.c	(Revision 1460)
+++ flashrom-register_par_programmer/nicnatsemi.c	(Arbeitskopie)
@@ -35,6 +35,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_nicnatsemi = {
+		.chip_readb		= nicnatsemi_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicnatsemi_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int nicnatsemi_shutdown(void *data)
 {
 	pci_cleanup(pacc);
@@ -48,7 +59,8 @@
 
 	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
 
-	buses_supported = BUS_PARALLEL;
+	if (register_shutdown(nicnatsemi_shutdown, NULL))
+		return 1;
 
 	/* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
 	 * in another. My NIC has MA16 connected to A16 on the boot ROM socket
@@ -57,9 +69,8 @@
 	 * functions below wants to be 0x0000FFFF.
 	 */
 	max_rom_decode.parallel = 131072;
+	register_par_programmer(&par_programmer_nicnatsemi, BUS_PARALLEL);
 
-	if (register_shutdown(nicnatsemi_shutdown, NULL))
-		return 1;
 	return 0;
 }
 
Index: flashrom-register_par_programmer/it85spi.c
===================================================================
--- flashrom-register_par_programmer/it85spi.c	(Revision 1460)
+++ flashrom-register_par_programmer/it85spi.c	(Arbeitskopie)
@@ -257,8 +257,10 @@
 	INDIRECT_A3(shm_io_base, (base >> 24));
 #endif
 #ifdef LPC_MEMORY
-	base = (chipaddr)programmer_map_flash_region("it85 communication",
-						     0xFFFFF000, 0x1000);
+	/* FIXME: We should block accessing that region for anything else.
+	 * Major TODO here, and it will be a lot of work.
+	 */
+	base = (chipaddr)physmap("it85 communication", 0xFFFFF000, 0x1000);
 	msg_pdbg("%s():%d base=0x%08x\n", __func__, __LINE__,
 	         (unsigned int)base);
 	ce_high = (unsigned char *)(base + 0xE00);  /* 0xFFFFFE00 */
@@ -285,18 +287,26 @@
 {
 	int ret;
 
-	if (!(buses_supported & BUS_FWH)) {
+	if (!(internal_buses_supported & BUS_FWH)) {
 		msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__);
 		return 1;
 	}
 	ret = it85xx_spi_common_init(s);
 	msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret);
 	if (!ret) {
-		msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__,
-		          buses_supported);
-		if (buses_supported & BUS_FWH)
-			msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n");
-		/* Really leave FWH enabled? */
+		msg_pdbg("%s: internal_buses_supported=0x%x\n", __func__,
+		          internal_buses_supported);
+		/* Check for FWH because IT85 listens to FWH cycles.
+		 * FIXME: The big question is whether FWH cycles are necessary
+		 * for communication even if LPC_IO is defined.
+		 */
+		if (internal_buses_supported & BUS_FWH)
+			msg_pdbg("Registering IT85 SPI.\n");
+		/* FIXME: Really leave FWH enabled? We can't use this region
+		 * anymore since accessing it would mess up IT85 communication.
+		 * If we decide to disable FWH for this region, we should print
+		 * a debug message about it.
+		 */
 		/* Set this as SPI controller. */
 		register_spi_programmer(&spi_programmer_it85xx);
 	}
Index: flashrom-register_par_programmer/atahpt.c
===================================================================
--- flashrom-register_par_programmer/atahpt.c	(Revision 1460)
+++ flashrom-register_par_programmer/atahpt.c	(Arbeitskopie)
@@ -40,6 +40,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_atahpt = {
+		.chip_readb		= atahpt_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= atahpt_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int atahpt_shutdown(void *data)
 {
 	/* Flash access is disabled automatically by PCI restore. */
@@ -61,10 +72,11 @@
 	reg32 |= (1 << 24);
 	rpci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
 
-	buses_supported = BUS_PARALLEL;
-
 	if (register_shutdown(atahpt_shutdown, NULL))
 		return 1;
+
+	register_par_programmer(&par_programmer_atahpt, BUS_PARALLEL);
+
 	return 0;
 }
 
Index: flashrom-register_par_programmer/nic3com.c
===================================================================
--- flashrom-register_par_programmer/nic3com.c	(Revision 1460)
+++ flashrom-register_par_programmer/nic3com.c	(Arbeitskopie)
@@ -55,6 +55,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_nic3com = {
+		.chip_readb		= nic3com_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nic3com_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int nic3com_shutdown(void *data)
 {
 	/* 3COM 3C90xB cards need a special fixup. */
@@ -96,11 +107,12 @@
 	 */
 	OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
 
-	buses_supported = BUS_PARALLEL;
+	if (register_shutdown(nic3com_shutdown, NULL))
+		return 1;
+
 	max_rom_decode.parallel = 128 * 1024;
+	register_par_programmer(&par_programmer_nic3com, BUS_PARALLEL);
 
-	if (register_shutdown(nic3com_shutdown, NULL))
-		return 1;
 	return 0;
 }
 
Index: flashrom-register_par_programmer/satasii.c
===================================================================
--- flashrom-register_par_programmer/satasii.c	(Revision 1460)
+++ flashrom-register_par_programmer/satasii.c	(Arbeitskopie)
@@ -42,6 +42,17 @@
 	{},
 };
 
+static const struct par_programmer par_programmer_satasii = {
+		.chip_readb		= satasii_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= satasii_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int satasii_shutdown(void *data)
 {
 	physunmap(sii_bar, SATASII_MEMMAP_SIZE);
@@ -76,10 +87,11 @@
 	if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26))))
 		msg_pinfo("Warning: Flash seems unconnected.\n");
 
-	buses_supported = BUS_PARALLEL;
-
 	if (register_shutdown(satasii_shutdown, NULL))
 		return 1;
+
+	register_par_programmer(&par_programmer_satasii, BUS_PARALLEL);
+
 	return 0;
 }
 
Index: flashrom-register_par_programmer/wbsio_spi.c
===================================================================
--- flashrom-register_par_programmer/wbsio_spi.c	(Revision 1460)
+++ flashrom-register_par_programmer/wbsio_spi.c	(Arbeitskopie)
@@ -82,10 +82,10 @@
 
 	msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase);
 
-	register_spi_programmer(&spi_programmer_wbsio);
 	msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is "
 		 "1024 kB!\n", __func__);
 	max_rom_decode.spi = 1024 * 1024;
+	register_spi_programmer(&spi_programmer_wbsio);
 
 	return 0;
 }
Index: flashrom-register_par_programmer/nicintel.c
===================================================================
--- flashrom-register_par_programmer/nicintel.c	(Revision 1460)
+++ flashrom-register_par_programmer/nicintel.c	(Arbeitskopie)
@@ -43,6 +43,17 @@
 
 #define CSR_FCR 0x0c
 
+static const struct par_programmer par_programmer_nicintel = {
+		.chip_readb		= nicintel_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicintel_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
 static int nicintel_shutdown(void *data)
 {
 	physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE);
@@ -93,9 +104,8 @@
 	 */
 	pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
 
-	buses_supported = BUS_PARALLEL;
-
 	max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE;
+	register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL);
 
 	return 0;
 
Index: flashrom-register_par_programmer/chipset_enable.c
===================================================================
--- flashrom-register_par_programmer/chipset_enable.c	(Revision 1460)
+++ flashrom-register_par_programmer/chipset_enable.c	(Arbeitskopie)
@@ -213,7 +213,7 @@
 	uint16_t old, new;
 	uint16_t xbcs = 0x4e;	/* X-Bus Chip Select register. */
 
-	buses_supported = BUS_PARALLEL;
+	internal_buses_supported = BUS_PARALLEL;
 
 	old = pci_read_word(dev, xbcs);
 
@@ -303,7 +303,7 @@
 	 * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and
 	 * FB_DEC_EN2.
 	 */
-	buses_supported = BUS_FWH;
+	internal_buses_supported = BUS_FWH;
 	return enable_flash_ich(dev, name, 0x4e);
 }
 
@@ -412,9 +412,9 @@
 	msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
 
 	/* If we're called by enable_flash_ich_dc_spi, it will override
-	 * buses_supported anyway.
+	 * internal_buses_supported anyway.
 	 */
-	buses_supported = BUS_FWH;
+	internal_buses_supported = BUS_FWH;
 	return enable_flash_ich(dev, name, 0xdc);
 }
 
@@ -434,7 +434,7 @@
 	if (new != old)
 		rpci_write_byte(dev, 0xd9, new);
 
-	buses_supported = BUS_FWH;
+	internal_buses_supported = BUS_FWH;
 	return 0;
 }
 
@@ -468,12 +468,11 @@
 	bnt = mmio_readl(rcrb + 0x3410);
 	if (bnt & 0x02) {
 		/* If strapped to LPC, no SPI initialization is required */
-		buses_supported = BUS_FWH;
+		internal_buses_supported = BUS_FWH;
 		return 0;
 	}
 
 	/* This adds BUS_SPI */
-	buses_supported = BUS_SPI;
 	if (ich_init_spi(dev, tmp, rcrb, 7) != 0) {
 		if (!ret)
 			ret = ERROR_NONFATAL;
@@ -556,7 +555,7 @@
 	 * time. At least not with our current code. So we prevent searching
 	 * on ICH7 when the southbridge is strapped to LPC
 	 */
-	buses_supported = BUS_FWH;
+	internal_buses_supported = BUS_FWH;
 	if (ich_generation == CHIPSET_ICH7) {
 		if (bbs == 0x03) {
 			/* If strapped to LPC, no further SPI initialization is
@@ -564,7 +563,7 @@
 			return ret;
 		} else {
 			/* Disable LPC/FWH if strapped to PCI or SPI */
-			buses_supported = 0;
+			internal_buses_supported = BUS_NONE;
 		}
 	}
 
@@ -667,7 +666,7 @@
 #define CS5530_ENABLE_SA2320		(1 << 2)
 #define CS5530_ENABLE_SA20		(1 << 6)
 
-	buses_supported = BUS_PARALLEL;
+	internal_buses_supported = BUS_PARALLEL;
 	/* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and
 	 * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB.
 	 * FIXME: Should we really touch the low mapping below 1 MB? Flashrom
@@ -820,7 +819,7 @@
 				 (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff));
 	}
 
-	buses_supported = BUS_LPC | BUS_FWH;
+	internal_buses_supported = BUS_LPC | BUS_FWH;
 
 	ret = sb600_probe_spi(dev);
 
@@ -914,7 +913,7 @@
 {
 	uint8_t tmp;
 
-	buses_supported = BUS_PARALLEL;
+	internal_buses_supported = BUS_PARALLEL;
 
 	tmp = INB(0xc06);
 	tmp |= 0x1;
@@ -1014,7 +1013,7 @@
 	switch ((val >> 5) & 0x3) {
 	case 0x0:
 		ret = enable_flash_mcp55(dev, name);
-		buses_supported = BUS_LPC;
+		internal_buses_supported = BUS_LPC;
 		msg_pdbg("Flash bus type is LPC\n");
 		break;
 	case 0x2:
@@ -1022,7 +1021,7 @@
 		/* SPI is added in mcp6x_spi_init if it works.
 		 * Do we really want to disable LPC in this case?
 		 */
-		buses_supported = BUS_NONE;
+		internal_buses_supported = BUS_NONE;
 		msg_pdbg("Flash bus type is SPI\n");
 		msg_pinfo("SPI on this chipset is WIP. Please report any "
 			  "success or failure by mailing us the verbose "
@@ -1030,7 +1029,7 @@
 		break;
 	default:
 		/* Should not happen. */
-		buses_supported = BUS_NONE;
+		internal_buses_supported = BUS_NONE;
 		msg_pdbg("Flash bus type is unknown (none)\n");
 		msg_pinfo("Something went wrong with bus type detection.\n");
 		goto out_msg;
@@ -1323,7 +1322,6 @@
 	struct pci_dev *dev = NULL;
 	int ret = -2;		/* Nothing! */
 	int i;
-	char *s;
 
 	/* Now let's try to find the chipset we have... */
 	for (i = 0; chipset_enables[i].vendor_name != NULL; i++) {
@@ -1375,9 +1373,5 @@
 		}
 	}
 
-	s = flashbuses_to_text(buses_supported);
-	msg_pinfo("This chipset supports the following protocols: %s.\n", s);
-	free(s);
-
 	return ret;
 }
Index: flashrom-register_par_programmer/programmer.c
===================================================================
--- flashrom-register_par_programmer/programmer.c	(Revision 1460)
+++ flashrom-register_par_programmer/programmer.c	(Arbeitskopie)
@@ -19,7 +19,21 @@
  */
 
 #include "flash.h"
+#include "programmer.h"
 
+static const struct par_programmer par_programmer_none = {
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+};
+
+const struct par_programmer *par_programmer = &par_programmer_none;
+
 /* No-op shutdown() for programmers which don't need special handling */
 int noop_shutdown(void)
 {
@@ -96,3 +110,9 @@
 		buf[i] = chip_readb(addr + i);
 	return;
 }
+
+void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses)
+{
+	par_programmer = pgm;
+	buses_supported |= buses;
+}
Index: flashrom-register_par_programmer/flashrom.c
===================================================================
--- flashrom-register_par_programmer/flashrom.c	(Revision 1460)
+++ flashrom-register_par_programmer/flashrom.c	(Arbeitskopie)
@@ -68,14 +68,6 @@
 		.init			= internal_init,
 		.map_flash_region	= physmap,
 		.unmap_flash_region	= physunmap,
-		.chip_readb		= internal_chip_readb,
-		.chip_readw		= internal_chip_readw,
-		.chip_readl		= internal_chip_readl,
-		.chip_readn		= internal_chip_readn,
-		.chip_writeb		= internal_chip_writeb,
-		.chip_writew		= internal_chip_writew,
-		.chip_writel		= internal_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -86,14 +78,6 @@
 		.init			= dummy_init,
 		.map_flash_region	= dummy_map,
 		.unmap_flash_region	= dummy_unmap,
-		.chip_readb		= dummy_chip_readb,
-		.chip_readw		= dummy_chip_readw,
-		.chip_readl		= dummy_chip_readl,
-		.chip_readn		= dummy_chip_readn,
-		.chip_writeb		= dummy_chip_writeb,
-		.chip_writew		= dummy_chip_writew,
-		.chip_writel		= dummy_chip_writel,
-		.chip_writen		= dummy_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -104,14 +88,6 @@
 		.init			= nic3com_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nic3com_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nic3com_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -124,14 +100,6 @@
 		.init			= nicrealtek_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicrealtek_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicrealtek_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -142,14 +110,6 @@
 		.init			= nicnatsemi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicnatsemi_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicnatsemi_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -160,14 +120,6 @@
 		.init			= gfxnvidia_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= gfxnvidia_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= gfxnvidia_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -178,14 +130,6 @@
 		.init			= drkaiser_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= drkaiser_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= drkaiser_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -196,14 +140,6 @@
 		.init			= satasii_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= satasii_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= satasii_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -214,14 +150,6 @@
 		.init			= atahpt_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= atahpt_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= atahpt_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -232,14 +160,6 @@
 		.init			= ft2232_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -250,14 +170,6 @@
 		.init			= serprog_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= serprog_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= serprog_chip_readn,
-		.chip_writeb		= serprog_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= serprog_delay,
 	},
 #endif
@@ -268,14 +180,6 @@
 		.init			= buspirate_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -286,14 +190,6 @@
 		.init			= dediprog_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -304,14 +200,6 @@
 		.init			= rayer_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -322,14 +210,6 @@
 		.init			= nicintel_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicintel_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicintel_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -340,14 +220,6 @@
 		.init			= nicintel_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -358,14 +230,6 @@
 		.init			= ogp_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -376,14 +240,6 @@
 		.init			= satamv_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= satamv_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= satamv_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -394,14 +250,6 @@
 		.init			= linux_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
 		.delay			= internal_delay,
 	},
 #endif
@@ -513,42 +361,42 @@
 
 void chip_writeb(uint8_t val, chipaddr addr)
 {
-	programmer_table[programmer].chip_writeb(val, addr);
+	par_programmer->chip_writeb(val, addr);
 }
 
 void chip_writew(uint16_t val, chipaddr addr)
 {
-	programmer_table[programmer].chip_writew(val, addr);
+	par_programmer->chip_writew(val, addr);
 }
 
 void chip_writel(uint32_t val, chipaddr addr)
 {
-	programmer_table[programmer].chip_writel(val, addr);
+	par_programmer->chip_writel(val, addr);
 }
 
 void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
 {
-	programmer_table[programmer].chip_writen(buf, addr, len);
+	par_programmer->chip_writen(buf, addr, len);
 }
 
 uint8_t chip_readb(const chipaddr addr)
 {
-	return programmer_table[programmer].chip_readb(addr);
+	return par_programmer->chip_readb(addr);
 }
 
 uint16_t chip_readw(const chipaddr addr)
 {
-	return programmer_table[programmer].chip_readw(addr);
+	return par_programmer->chip_readw(addr);
 }
 
 uint32_t chip_readl(const chipaddr addr)
 {
-	return programmer_table[programmer].chip_readl(addr);
+	return par_programmer->chip_readl(addr);
 }
 
 void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
 {
-	programmer_table[programmer].chip_readn(buf, addr, len);
+	par_programmer->chip_readn(buf, addr, len);
 }
 
 void programmer_delay(int usecs)
Index: flashrom-register_par_programmer/programmer.h
===================================================================
--- flashrom-register_par_programmer/programmer.h	(Revision 1460)
+++ flashrom-register_par_programmer/programmer.h	(Arbeitskopie)
@@ -97,14 +97,6 @@
 				    size_t len);
 	void (*unmap_flash_region) (void *virt_addr, size_t len);
 
-	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);
 	void (*delay) (int usecs);
 };
 
@@ -306,6 +298,7 @@
 extern int force_boardmismatch;
 void probe_superio(void);
 int register_superio(struct superio s);
+extern enum chipbustype internal_buses_supported;
 int internal_init(void);
 void internal_chip_writeb(uint8_t val, chipaddr addr);
 void internal_chip_writew(uint16_t val, chipaddr addr);
@@ -360,6 +353,18 @@
 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
@@ -634,10 +639,6 @@
 uint8_t serprog_chip_readb(const chipaddr addr);
 void serprog_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
 void serprog_delay(int usecs);
-int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			     const unsigned char *writearr,
-			     unsigned char *readarr);
-int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 #endif
 
 /* serial.c */
Index: flashrom-register_par_programmer/board_enable.c
===================================================================
--- flashrom-register_par_programmer/board_enable.c	(Revision 1460)
+++ flashrom-register_par_programmer/board_enable.c	(Arbeitskopie)
@@ -425,7 +425,7 @@
 	/* Check if at least one flash segment is enabled. */
 	if (tmp & 0xf0) {
 		/* The IT8705F will respond to LPC cycles and translate them. */
-		buses_supported = BUS_PARALLEL;
+		internal_buses_supported = BUS_PARALLEL;
 		/* Flash ROM I/F Writes Enable */
 		tmp |= 0x04;
 		msg_pdbg("Enabling IT8705F flash ROM interface write.\n");


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





More information about the flashrom mailing list