[flashrom] [RFC] Add struct flashchip * everywhere

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Thu Nov 3 23:07:05 CET 2011


Am 02.11.2011 13:41 schrieb Stefan Tauner:
> On Wed, 02 Nov 2011 04:53:22 +0100
> Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net> wrote:
>
>> We need a way to identify which registered programmer should be used for
>> a given access. Especially for cases where multiple programmers for the
>> same bus type are registered (e.g. IT87+MCP79 SPI or Dual BIOS
>> solutions), probing has to happen on each programmer. Somehow we have to
>> tell the dispatcher (spi_send_command etc.) this information, and the
>> only way to get the info to the dispatcher is either an ugly global
>> variable which makes dealing with multiple flash chips and multiple bus
>> probing really messy, or we store the info inside struct flashchip.
>> Given that struct flashchip is passed around almost everywhere already,
>> it is the natural location for such information and only very few
>> function prototypes have to be changed to handle this.
>>
>> I have a prototype patch in the queue, but it's only half ready. If
>> there is any interest, I can send the patch as is to give you an option
>> to shoot it down while it is still unfinished.
> changing prototypes should be no concern in such decisions imho. it is
> a one-time change that may break some patches in the queue (which is no
> problem, because there should be only a short queue, right? ;) but this
> should not play a major role in the design.

Heh, OK.

 
> the reason i bring this argument up explicitly is that i think
> the name "flashchip" may get a bit abused and changing it might be
> better. that's not necessarily the case, i just wanted to criticize
> something, because else it sounds good at this level of detail ;)

struct everything?
And yes, that proposal is halfway serious.

 
> another layer of redirection is - as always - also a
> possibility: introducing a new struct with pointers to the actual chip
> and the programmer to be used (and other information related to the
> actual situation/probing... e.g. access right ranges). but that's
> probably not needed (yet) and the splitting could be done later anyway
> if need be. OTOH if it is clear that there will be more information
> stuffed into struct flashchip, that is not really static and does not
> need to/should not reside in flashchips.c/struct flashchip, we may
> better discuss a separation now(?).

We have a big problem: There is almost no information in struct
flashchip which is constant in all cases.
The name, size and erase structures could be filled in automatically for
SFDP stuff. That alone kills the separation idea IMHO.
Here comes my current patch for struct flashchip * everyhwere.
Uwe: I know that 80 columns are a limit, and I violated it badly in many
places. I just wanted to get something testable out, and I will change
the formatting if the patch has a chance for merging.

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

Index: flashrom-struct_flashchip_everywhere/flash.h
===================================================================
--- flashrom-struct_flashchip_everywhere/flash.h	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/flash.h	(Arbeitskopie)
@@ -44,14 +44,6 @@
 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
 				  size_t len);
 void programmer_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 programmer_delay(int usecs);
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
@@ -186,6 +178,15 @@
 
 extern const struct flashchip flashchips[];
 
+void chip_writeb(const struct flashchip *flash, uint8_t val, chipaddr addr);
+void chip_writew(const struct flashchip *flash, uint16_t val, chipaddr addr);
+void chip_writel(const struct flashchip *flash, uint32_t val, chipaddr addr);
+void chip_writen(const struct flashchip *flash, uint8_t *buf, chipaddr addr, size_t len);
+uint8_t chip_readb(const struct flashchip *flash, const chipaddr addr);
+uint16_t chip_readw(const struct flashchip *flash, const chipaddr addr);
+uint32_t chip_readl(const struct flashchip *flash, const chipaddr addr);
+void chip_readn(const struct flashchip *flash, uint8_t *buf, const chipaddr addr, size_t len);
+
 /* print.c */
 char *flashbuses_to_text(enum chipbustype bustype);
 void print_supported(void);
@@ -266,9 +267,9 @@
 	const unsigned char *writearr;
 	unsigned char *readarr;
 };
-int spi_send_command(unsigned int writecnt, unsigned int readcnt,
+int spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr);
-int spi_send_multicommand(struct spi_command *cmds);
-uint32_t spi_get_valid_read_addr(void);
+int spi_send_multicommand(struct flashchip *flash, struct spi_command *cmds);
+uint32_t spi_get_valid_read_addr(struct flashchip *flash);
 
 #endif				/* !__FLASH_H__ */
Index: flashrom-struct_flashchip_everywhere/it87spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/it87spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/it87spi.c	(Arbeitskopie)
@@ -103,7 +103,7 @@
 	return;
 }
 
-static int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int it8716f_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *writearr, unsigned char *readarr);
 static int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf,
 				 int start, int len);
@@ -247,7 +247,7 @@
  * commands with the address in inverse wire order. That's why the register
  * ordering in case 4 and 5 may seem strange.
  */
-static int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int it8716f_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *writearr, unsigned char *readarr)
 {
 	uint8_t busy, writeenc;
@@ -318,19 +318,19 @@
 	int i, result;
 	chipaddr bios = flash->virtual_memory;
 
-	result = spi_write_enable();
+	result = spi_write_enable(flash);
 	if (result)
 		return result;
 	/* 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++)
-		chip_writeb(buf[i], bios + start + i);
+		chip_writeb(flash, buf[i], bios + start + i);
 	OUTB(0, it8716f_flashport);
 	/* Wait until the Write-In-Progress bit is cleared.
 	 * This usually takes 1-10 ms, so wait in 1 ms steps.
 	 */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(1000);
 	return 0;
 }
Index: flashrom-struct_flashchip_everywhere/jedec.c
===================================================================
--- flashrom-struct_flashchip_everywhere/jedec.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/jedec.c	(Arbeitskopie)
@@ -37,17 +37,17 @@
 	return (val ^ (val >> 1)) & 0x1;
 }
 
-static void toggle_ready_jedec_common(chipaddr dst, int delay)
+static void toggle_ready_jedec_common(const struct flashchip *flash, chipaddr dst, int delay)
 {
 	unsigned int i = 0;
 	uint8_t tmp1, tmp2;
 
-	tmp1 = chip_readb(dst) & 0x40;
+	tmp1 = chip_readb(flash, dst) & 0x40;
 
 	while (i++ < 0xFFFFFFF) {
 		if (delay)
 			programmer_delay(delay);
-		tmp2 = chip_readb(dst) & 0x40;
+		tmp2 = chip_readb(flash, dst) & 0x40;
 		if (tmp1 == tmp2) {
 			break;
 		}
@@ -57,9 +57,9 @@
 		msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
 }
 
-void toggle_ready_jedec(chipaddr dst)
+void toggle_ready_jedec(const struct flashchip *flash, chipaddr dst)
 {
-	toggle_ready_jedec_common(dst, 0);
+	toggle_ready_jedec_common(flash, dst, 0);
 }
 
 /* Some chips require a minimum delay between toggle bit reads.
@@ -69,12 +69,12 @@
  * Given that erase is slow on all chips, it is recommended to use 
  * toggle_ready_jedec_slow in erase functions.
  */
-static void toggle_ready_jedec_slow(chipaddr dst)
+static void toggle_ready_jedec_slow(const struct flashchip *flash, chipaddr dst)
 {
-	toggle_ready_jedec_common(dst, 8 * 1000);
+	toggle_ready_jedec_common(flash, dst, 8 * 1000);
 }
 
-void data_polling_jedec(chipaddr dst, uint8_t data)
+void data_polling_jedec(const struct flashchip *flash, chipaddr dst, uint8_t data)
 {
 	unsigned int i = 0;
 	uint8_t tmp;
@@ -82,7 +82,7 @@
 	data &= 0x80;
 
 	while (i++ < 0xFFFFFFF) {
-		tmp = chip_readb(dst) & 0x80;
+		tmp = chip_readb(flash, dst) & 0x80;
 		if (tmp == data) {
 			break;
 		}
@@ -113,9 +113,9 @@
 static void start_program_jedec_common(struct flashchip *flash, unsigned int mask)
 {
 	chipaddr bios = flash->virtual_memory;
-	chip_writeb(0xAA, bios + (0x5555 & mask));
-	chip_writeb(0x55, bios + (0x2AAA & mask));
-	chip_writeb(0xA0, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0xA0, bios + (0x5555 & mask));
 }
 
 static int probe_jedec_common(struct flashchip *flash, unsigned int mask)
@@ -150,57 +150,57 @@
 	/* Reset chip to a clean slate */
 	if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
 	{
-		chip_writeb(0xAA, bios + (0x5555 & mask));
+		chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
-		chip_writeb(0x55, bios + (0x2AAA & mask));
+		chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
 	}
-	chip_writeb(0xF0, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
 	if (probe_timing_exit)
 		programmer_delay(probe_timing_exit);
 
 	/* Issue JEDEC Product ID Entry command */
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	if (probe_timing_enter)
 		programmer_delay(10);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	if (probe_timing_enter)
 		programmer_delay(10);
-	chip_writeb(0x90, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x90, bios + (0x5555 & mask));
 	if (probe_timing_enter)
 		programmer_delay(probe_timing_enter);
 
 	/* Read product ID */
-	id1 = chip_readb(bios);
-	id2 = chip_readb(bios + 0x01);
+	id1 = chip_readb(flash, bios);
+	id2 = chip_readb(flash, bios + 0x01);
 	largeid1 = id1;
 	largeid2 = id2;
 
 	/* Check if it is a continuation ID, this should be a while loop. */
 	if (id1 == 0x7F) {
 		largeid1 <<= 8;
-		id1 = chip_readb(bios + 0x100);
+		id1 = chip_readb(flash, bios + 0x100);
 		largeid1 |= id1;
 	}
 	if (id2 == 0x7F) {
 		largeid2 <<= 8;
-		id2 = chip_readb(bios + 0x101);
+		id2 = chip_readb(flash, bios + 0x101);
 		largeid2 |= id2;
 	}
 
 	/* Issue JEDEC Product ID Exit command */
 	if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
 	{
-		chip_writeb(0xAA, bios + (0x5555 & mask));
+		chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
-		chip_writeb(0x55, bios + (0x2AAA & mask));
+		chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
 	}
-	chip_writeb(0xF0, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
 	if (probe_timing_exit)
 		programmer_delay(probe_timing_exit);
 
@@ -209,17 +209,17 @@
 		msg_cdbg(", id1 parity violation");
 
 	/* Read the product ID location again. We should now see normal flash contents. */
-	flashcontent1 = chip_readb(bios);
-	flashcontent2 = chip_readb(bios + 0x01);
+	flashcontent1 = chip_readb(flash, bios);
+	flashcontent2 = chip_readb(flash, bios + 0x01);
 
 	/* Check if it is a continuation ID, this should be a while loop. */
 	if (flashcontent1 == 0x7F) {
 		flashcontent1 <<= 8;
-		flashcontent1 |= chip_readb(bios + 0x100);
+		flashcontent1 |= chip_readb(flash, bios + 0x100);
 	}
 	if (flashcontent2 == 0x7F) {
 		flashcontent2 <<= 8;
-		flashcontent2 |= chip_readb(bios + 0x101);
+		flashcontent2 |= chip_readb(flash, bios + 0x101);
 	}
 
 	if (largeid1 == flashcontent1)
@@ -246,22 +246,22 @@
 	        delay_us = 10;
 
 	/*  Issue the Sector Erase command   */
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x80, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x80, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
 
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x30, bios + page);
+	chip_writeb(flash, 0x30, bios + page);
 	programmer_delay(delay_us);
 
 	/* wait for Toggle bit ready         */
-	toggle_ready_jedec_slow(bios);
+	toggle_ready_jedec_slow(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -276,22 +276,22 @@
 	        delay_us = 10;
 
 	/*  Issue the Sector Erase command   */
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x80, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x80, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
 
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x50, bios + block);
+	chip_writeb(flash, 0x50, bios + block);
 	programmer_delay(delay_us);
 
 	/* wait for Toggle bit ready         */
-	toggle_ready_jedec_slow(bios);
+	toggle_ready_jedec_slow(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -305,21 +305,21 @@
 	        delay_us = 10;
 
 	/*  Issue the JEDEC Chip Erase command   */
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x80, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x80, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
 
-	chip_writeb(0xAA, bios + (0x5555 & mask));
+	chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x55, bios + (0x2AAA & mask));
+	chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
 	programmer_delay(delay_us);
-	chip_writeb(0x10, bios + (0x5555 & mask));
+	chip_writeb(flash, 0x10, bios + (0x5555 & mask));
 	programmer_delay(delay_us);
 
-	toggle_ready_jedec_slow(bios);
+	toggle_ready_jedec_slow(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -341,10 +341,10 @@
 	start_program_jedec_common(flash, mask);
 
 	/* transfer data from source to destination */
-	chip_writeb(*src, dst);
-	toggle_ready_jedec(bios);
+	chip_writeb(flash, *src, dst);
+	toggle_ready_jedec(flash, bios);
 
-	if (chip_readb(dst) != *src && tried++ < MAX_REFLASH_TRIES) {
+	if (chip_readb(flash, dst) != *src && tried++ < MAX_REFLASH_TRIES) {
 		goto retry;
 	}
 
@@ -395,12 +395,12 @@
 	for (i = 0; i < page_size; i++) {
 		/* If the data is 0xFF, don't program it */
 		if (*src != 0xFF)
-			chip_writeb(*src, dst);
+			chip_writeb(flash, *src, dst);
 		dst++;
 		src++;
 	}
 
-	toggle_ready_jedec(dst - 1);
+	toggle_ready_jedec(flash, dst - 1);
 
 	dst = d;
 	src = s;
Index: flashrom-struct_flashchip_everywhere/bitbang_spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/bitbang_spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/bitbang_spi.c	(Arbeitskopie)
@@ -63,7 +63,7 @@
 		bitbang_spi_master->release_bus();
 }
 
-static int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int bitbang_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_bitbang = {
@@ -141,7 +141,7 @@
 	return ret;
 }
 
-static int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int bitbang_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
 	int i;
Index: flashrom-struct_flashchip_everywhere/serprog.c
===================================================================
--- flashrom-struct_flashchip_everywhere/serprog.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/serprog.c	(Arbeitskopie)
@@ -299,6 +299,12 @@
 	return 0;
 }
 
+static int serprog_spi_send_command(struct flashchip *flash,
+				    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,
@@ -766,7 +772,7 @@
 	sp_prev_was_write = 0;
 }
 
-int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int serprog_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			     const unsigned char *writearr,
 			     unsigned char *readarr)
 {
@@ -796,7 +802,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;
@@ -804,7 +810,7 @@
 	for (i = 0; i < len; i += cur_len) {
 		int ret;
 		cur_len = min(max_read, (len - i));
-		ret = spi_nbyte_read(start + i, buf + i, cur_len);
+		ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
 		if (ret)
 			return ret;
 	}
Index: flashrom-struct_flashchip_everywhere/w39.c
===================================================================
--- flashrom-struct_flashchip_everywhere/w39.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/w39.c	(Arbeitskopie)
@@ -26,7 +26,7 @@
 	chipaddr wrprotect = flash->virtual_registers + offset + 2;
 	uint8_t locking;
 
-	locking = chip_readb(wrprotect);
+	locking = chip_readb(flash, wrprotect);
 	msg_cdbg("Lock status of block at 0x%08x is ", offset);
 	switch (locking & 0x7) {
 	case 0:
@@ -64,7 +64,7 @@
 	chipaddr wrprotect = flash->virtual_registers + offset + 2;
 	uint8_t locking;
 
-	locking = chip_readb(wrprotect);
+	locking = chip_readb(flash, wrprotect);
 	/* Read or write lock present? */
 	if (locking & ((1 << 2) | (1 << 0))) {
 		/* Lockdown active? */
@@ -73,7 +73,7 @@
 			return -1;
 		} else {
 			msg_cdbg("Unlocking block at 0x%08x\n", offset);
-			chip_writeb(0, wrprotect);
+			chip_writeb(flash, 0, wrprotect);
 		}
 	}
 
@@ -86,18 +86,18 @@
 	uint8_t val;
 
 	/* Product Identification Entry */
-	chip_writeb(0xAA, bios + 0x5555);
-	chip_writeb(0x55, bios + 0x2AAA);
-	chip_writeb(0x90, bios + 0x5555);
+	chip_writeb(flash, 0xAA, bios + 0x5555);
+	chip_writeb(flash, 0x55, bios + 0x2AAA);
+	chip_writeb(flash, 0x90, bios + 0x5555);
 	programmer_delay(10);
 
 	/* Read something, maybe hardware lock bits */
-	val = chip_readb(bios + offset);
+	val = chip_readb(flash, bios + offset);
 
 	/* Product Identification Exit */
-	chip_writeb(0xAA, bios + 0x5555);
-	chip_writeb(0x55, bios + 0x2AAA);
-	chip_writeb(0xF0, bios + 0x5555);
+	chip_writeb(flash, 0xAA, bios + 0x5555);
+	chip_writeb(flash, 0x55, bios + 0x2AAA);
+	chip_writeb(flash, 0xF0, bios + 0x5555);
 	programmer_delay(10);
 
 	return val;
Index: flashrom-struct_flashchip_everywhere/sst49lfxxxc.c
===================================================================
--- flashrom-struct_flashchip_everywhere/sst49lfxxxc.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/sst49lfxxxc.c	(Arbeitskopie)
@@ -26,8 +26,8 @@
 static int write_lockbits_block_49lfxxxc(struct flashchip *flash, unsigned long address, unsigned char bits)
 {
 	unsigned long lock = flash->virtual_registers + address + 2;
-	msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", lock, chip_readb(lock));
-	chip_writeb(bits, lock);
+	msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", lock, chip_readb(flash, lock));
+	chip_writeb(flash, bits, lock);
 
 	return 0;
 }
@@ -64,8 +64,8 @@
 	uint8_t status;
 	chipaddr bios = flash->virtual_memory;
 
-	chip_writeb(0x30, bios);
-	chip_writeb(0xD0, bios + address);
+	chip_writeb(flash, 0x30, bios);
+	chip_writeb(flash, 0xD0, bios + address);
 
 	status = wait_82802ab(flash);
 	print_status_82802ab(status);
Index: flashrom-struct_flashchip_everywhere/sharplhf00l04.c
===================================================================
--- flashrom-struct_flashchip_everywhere/sharplhf00l04.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/sharplhf00l04.c	(Arbeitskopie)
@@ -33,18 +33,18 @@
 	uint8_t status;
 
 	// clear status register
-	chip_writeb(0x50, bios);
+	chip_writeb(flash, 0x50, bios);
 	status = wait_82802ab(flash);
 	print_status_82802ab(status);
 	// clear write protect
 	msg_cspew("write protect is at 0x%lx\n", (wrprotect));
-	msg_cspew("write protect is 0x%x\n", chip_readb(wrprotect));
-	chip_writeb(0, wrprotect);
-	msg_cspew("write protect is 0x%x\n", chip_readb(wrprotect));
+	msg_cspew("write protect is 0x%x\n", chip_readb(flash, wrprotect));
+	chip_writeb(flash, 0, wrprotect);
+	msg_cspew("write protect is 0x%x\n", chip_readb(flash, wrprotect));
 
 	// now start it
-	chip_writeb(0x20, bios);
-	chip_writeb(0xd0, bios);
+	chip_writeb(flash, 0x20, bios);
+	chip_writeb(flash, 0xd0, bios);
 	programmer_delay(10);
 	// now let's see what the register is
 	status = wait_82802ab(flash);
Index: flashrom-struct_flashchip_everywhere/a25.c
===================================================================
--- flashrom-struct_flashchip_everywhere/a25.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/a25.c	(Arbeitskopie)
@@ -33,7 +33,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_amic_a25_srwd(status);
@@ -49,7 +49,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_amic_a25_srwd(status);
@@ -64,7 +64,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_amic_a25_srwd(status);
@@ -82,7 +82,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_amic_a25_srwd(status);
Index: flashrom-struct_flashchip_everywhere/dummyflasher.c
===================================================================
--- flashrom-struct_flashchip_everywhere/dummyflasher.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/dummyflasher.c	(Arbeitskopie)
@@ -60,7 +60,7 @@
 
 static int spi_write_256_chunksize = 256;
 
-static int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int dummy_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		      const unsigned char *writearr, unsigned char *readarr);
 static int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf,
 			       int start, int len);
@@ -492,7 +492,7 @@
 }
 #endif
 
-static int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int dummy_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		      const unsigned char *writearr, unsigned char *readarr)
 {
 	int i;
Index: flashrom-struct_flashchip_everywhere/sst_fwhub.c
===================================================================
--- flashrom-struct_flashchip_everywhere/sst_fwhub.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/sst_fwhub.c	(Arbeitskopie)
@@ -29,7 +29,7 @@
 	chipaddr registers = flash->virtual_registers;
 	uint8_t blockstatus;
 
-	blockstatus = chip_readb(registers + offset + 2);
+	blockstatus = chip_readb(flash, registers + offset + 2);
 	msg_cdbg("Lock status for 0x%06x (size 0x%06x) is %02x, ",
 		     offset, flash->page_size, blockstatus);
 	switch (blockstatus & 0x3) {
@@ -59,7 +59,7 @@
 
 	if (blockstatus) {
 		msg_cdbg("Trying to clear lock for 0x%06x... ", offset);
-		chip_writeb(0, registers + offset + 2);
+		chip_writeb(flash, 0, registers + offset + 2);
 
 		blockstatus = check_sst_fwhub_block_lock(flash, offset);
 		msg_cdbg("%s\n", (blockstatus) ? "failed" : "OK");
Index: flashrom-struct_flashchip_everywhere/at25.c
===================================================================
--- flashrom-struct_flashchip_everywhere/at25.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/at25.c	(Arbeitskopie)
@@ -61,7 +61,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_atmel_at25_srpl(status);
@@ -84,7 +84,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_atmel_at25_srpl(status);
@@ -103,7 +103,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	msg_cdbg("Chip status register: Status Register Write Protect (WPEN) "
@@ -127,7 +127,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	msg_cdbg("Chip status register: Status Register Write Protect (WPEN) "
@@ -151,7 +151,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 
 	spi_prettyprint_status_register_atmel_at25_srpl(status);
@@ -168,7 +168,7 @@
 	uint8_t status;
 	int result;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	/* If block protection is disabled, stop here. */
 	if ((status & (3 << 2)) == 0)
 		return 0;
@@ -195,7 +195,7 @@
 		msg_cerr("spi_write_status_register failed\n");
 		return result;
 	}
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	if ((status & (3 << 2)) != 0) {
 		msg_cerr("Block protection could not be disabled!\n");
 		return 1;
@@ -223,7 +223,7 @@
 	uint8_t status;
 	int result;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	/* If block protection is disabled, stop here. */
 	if ((status & 0x6c) == 0)
 		return 0;
@@ -244,7 +244,7 @@
 		msg_cerr("spi_write_status_register failed\n");
 		return result;
 	}
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	if ((status & 0x6c) != 0) {
 		msg_cerr("Block protection could not be disabled!\n");
 		return 1;
@@ -257,7 +257,7 @@
 	uint8_t status;
 	int result;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	/* If block protection is disabled, stop here. */
 	if ((status & 0x7c) == 0)
 		return 0;
@@ -278,7 +278,7 @@
 		msg_cerr("spi_write_status_register failed\n");
 		return result;
 	}
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	if ((status & 0x7c) != 0) {
 		msg_cerr("Block protection could not be disabled!\n");
 		return 1;
Index: flashrom-struct_flashchip_everywhere/ichspi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/ichspi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/ichspi.c	(Arbeitskopie)
@@ -955,7 +955,7 @@
 	}
 }
 
-static int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int ich_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		    const unsigned char *writearr, unsigned char *readarr)
 {
 	int result;
@@ -1152,7 +1152,7 @@
 }
 #endif
 
-static int ich_spi_send_multicommand(struct spi_command *cmds)
+static int ich_spi_send_multicommand(struct flashchip *flash, struct spi_command *cmds)
 {
 	int ret = 0;
 	int i;
@@ -1202,7 +1202,7 @@
 			 * preoppos matched, this is a normal opcode.
 			 */
 		}
-		ret = ich_spi_send_command(cmds->writecnt, cmds->readcnt,
+		ret = ich_spi_send_command(flash, cmds->writecnt, cmds->readcnt,
 					   cmds->writearr, cmds->readarr);
 		/* Reset the type of all opcodes to non-atomic. */
 		for (i = 0; i < 8; i++)
Index: flashrom-struct_flashchip_everywhere/82802ab.c
===================================================================
--- flashrom-struct_flashchip_everywhere/82802ab.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/82802ab.c	(Arbeitskopie)
@@ -47,18 +47,18 @@
 	int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0;
 
 	/* Reset to get a clean state */
-	chip_writeb(0xFF, bios);
+	chip_writeb(flash, 0xFF, bios);
 	programmer_delay(10);
 
 	/* Enter ID mode */
-	chip_writeb(0x90, bios);
+	chip_writeb(flash, 0x90, bios);
 	programmer_delay(10);
 
-	id1 = chip_readb(bios + (0x00 << shifted));
-	id2 = chip_readb(bios + (0x01 << shifted));
+	id1 = chip_readb(flash, bios + (0x00 << shifted));
+	id2 = chip_readb(flash, bios + (0x01 << shifted));
 
 	/* Leave ID mode */
-	chip_writeb(0xFF, bios);
+	chip_writeb(flash, 0xFF, bios);
 
 	programmer_delay(10);
 
@@ -71,8 +71,8 @@
 	 * Read the product ID location again. We should now see normal
 	 * flash contents.
 	 */
-	flashcontent1 = chip_readb(bios + (0x00 << shifted));
-	flashcontent2 = chip_readb(bios + (0x01 << shifted));
+	flashcontent1 = chip_readb(flash, bios + (0x00 << shifted));
+	flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
 
 	if (id1 == flashcontent1)
 		msg_cdbg(", id1 is normal flash content");
@@ -94,15 +94,15 @@
 	uint8_t status;
 	chipaddr bios = flash->virtual_memory;
 
-	chip_writeb(0x70, bios);
-	if ((chip_readb(bios) & 0x80) == 0) {	// it's busy
-		while ((chip_readb(bios) & 0x80) == 0) ;
+	chip_writeb(flash, 0x70, bios);
+	if ((chip_readb(flash, bios) & 0x80) == 0) {	// it's busy
+		while ((chip_readb(flash, bios) & 0x80) == 0) ;
 	}
 
-	status = chip_readb(bios);
+	status = chip_readb(flash, bios);
 
 	/* Reset to get a clean state */
-	chip_writeb(0xFF, bios);
+	chip_writeb(flash, 0xFF, bios);
 
 	return status;
 }
@@ -113,7 +113,7 @@
 	//chipaddr wrprotect = flash->virtual_registers + page + 2;
 
 	for (i = 0; i < flash->total_size * 1024; i+= flash->page_size)
-		chip_writeb(0, flash->virtual_registers + i + 2);
+		chip_writeb(flash, 0, flash->virtual_registers + i + 2);
 
 	return 0;
 }
@@ -125,11 +125,11 @@
 	uint8_t status;
 
 	// clear status register
-	chip_writeb(0x50, bios + page);
+	chip_writeb(flash, 0x50, bios + page);
 
 	// now start it
-	chip_writeb(0x20, bios + page);
-	chip_writeb(0xd0, bios + page);
+	chip_writeb(flash, 0x20, bios + page);
+	chip_writeb(flash, 0xd0, bios + page);
 	programmer_delay(10);
 
 	// now let's see what the register is
@@ -148,8 +148,8 @@
 
 	for (i = 0; i < len; i++) {
 		/* transfer data from source to destination */
-		chip_writeb(0x40, dst);
-		chip_writeb(*src++, dst++);
+		chip_writeb(flash, 0x40, dst);
+		chip_writeb(flash, *src++, dst++);
 		wait_82802ab(flash);
 	}
 
@@ -164,13 +164,13 @@
 	int i;
 
 	/* Clear status register */
-	chip_writeb(0x50, bios);
+	chip_writeb(flash, 0x50, bios);
 
 	/* Read identifier codes */
-	chip_writeb(0x90, bios);
+	chip_writeb(flash, 0x90, bios);
 
 	/* Read master lock-bit */
-	mcfg = chip_readb(bios + 0x3);
+	mcfg = chip_readb(flash, bios + 0x3);
 	msg_cdbg("master lock is ");
 	if (mcfg) {
 		msg_cdbg("locked!\n");
@@ -181,7 +181,7 @@
 
 	/* Read block lock-bits */
 	for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) {
-		bcfg = chip_readb(bios + i + 2); // read block lock config
+		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) {
 			need_unlock = 1;
@@ -189,14 +189,14 @@
 	}
 
 	/* Reset chip */
-	chip_writeb(0xFF, bios);
+	chip_writeb(flash, 0xFF, bios);
 
 	/* Unlock: clear block lock-bits, if needed */
 	if (can_unlock && need_unlock) {
 		msg_cdbg("Unlock: ");
-		chip_writeb(0x60, bios);
-		chip_writeb(0xD0, bios);
-		chip_writeb(0xFF, bios);
+		chip_writeb(flash, 0x60, bios);
+		chip_writeb(flash, 0xD0, bios);
+		chip_writeb(flash, 0xFF, bios);
 		msg_cdbg("Done!\n");
 	}
 
@@ -220,10 +220,10 @@
 	wait_82802ab(flash);
 
 	/* Read identifier codes */
-	chip_writeb(0x90, bios);
+	chip_writeb(flash, 0x90, bios);
 
 	/* Read master lock-bit */
-	mcfg = chip_readb(bios + 0x3);
+	mcfg = chip_readb(flash, bios + 0x3);
 	msg_cdbg("master lock is ");
 	if (mcfg) {
 		msg_cdbg("locked!\n");
@@ -235,7 +235,7 @@
 	/* Read block lock-bits, 8 * 8 KB + 15 * 64 KB */
 	for (i = 0; i < flash->total_size * 1024;
 	     i += (i >= (64 * 1024) ? 64 * 1024 : 8 * 1024)) {
-		bcfg = chip_readb(bios + i + 2); /* read block lock config */
+		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)
@@ -243,14 +243,14 @@
 	}
 
 	/* Reset chip */
-	chip_writeb(0xFF, bios);
+	chip_writeb(flash, 0xFF, bios);
 
 	/* Unlock: clear block lock-bits, if needed */
 	if (can_unlock && need_unlock) {
 		msg_cdbg("Unlock: ");
-		chip_writeb(0x60, bios);
-		chip_writeb(0xD0, bios);
-		chip_writeb(0xFF, bios);
+		chip_writeb(flash, 0x60, bios);
+		chip_writeb(flash, 0xD0, bios);
+		chip_writeb(flash, 0xFF, bios);
 		wait_82802ab(flash);
 		msg_cdbg("Done!\n");
 	}
Index: flashrom-struct_flashchip_everywhere/dediprog.c
===================================================================
--- flashrom-struct_flashchip_everywhere/dediprog.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/dediprog.c	(Arbeitskopie)
@@ -317,7 +317,7 @@
 	return ret;
 }
 
-static int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int dediprog_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *writearr, unsigned char *readarr)
 {
 	int ret;
Index: flashrom-struct_flashchip_everywhere/spi25.c
===================================================================
--- flashrom-struct_flashchip_everywhere/spi25.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/spi25.c	(Arbeitskopie)
@@ -29,13 +29,13 @@
 #include "programmer.h"
 #include "spi.h"
 
-static int spi_rdid(unsigned char *readarr, int bytes)
+static int spi_rdid(struct flashchip *flash, unsigned char *readarr, int bytes)
 {
 	static const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
 	int ret;
 	int i;
 
-	ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr);
+	ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
 	if (ret)
 		return ret;
 	msg_cspew("RDID returned");
@@ -45,20 +45,20 @@
 	return 0;
 }
 
-static int spi_rems(unsigned char *readarr)
+static int spi_rems(struct flashchip *flash, unsigned char *readarr)
 {
 	unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
 	uint32_t readaddr;
 	int ret;
 
-	ret = spi_send_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+	ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
 	if (ret == SPI_INVALID_ADDRESS) {
 		/* Find the lowest even address allowed for reads. */
-		readaddr = (spi_get_valid_read_addr() + 1) & ~1;
+		readaddr = (spi_get_valid_read_addr(flash) + 1) & ~1;
 		cmd[1] = (readaddr >> 16) & 0xff,
 		cmd[2] = (readaddr >> 8) & 0xff,
 		cmd[3] = (readaddr >> 0) & 0xff,
-		ret = spi_send_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+		ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
 	}
 	if (ret)
 		return ret;
@@ -66,21 +66,21 @@
 	return 0;
 }
 
-static int spi_res(unsigned char *readarr, int bytes)
+static int spi_res(struct flashchip *flash, unsigned char *readarr, int bytes)
 {
 	unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
 	uint32_t readaddr;
 	int ret;
 	int i;
 
-	ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr);
+	ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
 	if (ret == SPI_INVALID_ADDRESS) {
 		/* Find the lowest even address allowed for reads. */
-		readaddr = (spi_get_valid_read_addr() + 1) & ~1;
+		readaddr = (spi_get_valid_read_addr(flash) + 1) & ~1;
 		cmd[1] = (readaddr >> 16) & 0xff,
 		cmd[2] = (readaddr >> 8) & 0xff,
 		cmd[3] = (readaddr >> 0) & 0xff,
-		ret = spi_send_command(sizeof(cmd), bytes, cmd, readarr);
+		ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
 	}
 	if (ret)
 		return ret;
@@ -91,13 +91,13 @@
 	return 0;
 }
 
-int spi_write_enable(void)
+int spi_write_enable(struct flashchip *flash)
 {
 	static const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
 	int result;
 
 	/* Send WREN (Write Enable) */
-	result = spi_send_command(sizeof(cmd), 0, cmd, NULL);
+	result = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
 
 	if (result)
 		msg_cerr("%s failed\n", __func__);
@@ -105,12 +105,12 @@
 	return result;
 }
 
-int spi_write_disable(void)
+int spi_write_disable(struct flashchip *flash)
 {
 	static const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
 
 	/* Send WRDI (Write Disable) */
-	return spi_send_command(sizeof(cmd), 0, cmd, NULL);
+	return spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
 }
 
 static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
@@ -119,7 +119,7 @@
 	uint32_t id1;
 	uint32_t id2;
 
-	if (spi_rdid(readarr, bytes)) {
+	if (spi_rdid(flash, readarr, bytes)) {
 		return 0;
 	}
 
@@ -199,7 +199,7 @@
 	unsigned char readarr[JEDEC_REMS_INSIZE];
 	uint32_t id1, id2;
 
-	if (spi_rems(readarr)) {
+	if (spi_rems(flash, readarr)) {
 		return 0;
 	}
 
@@ -242,7 +242,7 @@
 	/* Check if RDID is usable and does not return 0xff 0xff 0xff or
 	 * 0x00 0x00 0x00. In that case, RES is pointless.
 	 */
-	if (!spi_rdid(readarr, 3) && memcmp(readarr, allff, 3) &&
+	if (!spi_rdid(flash, readarr, 3) && memcmp(readarr, allff, 3) &&
 	    memcmp(readarr, all00, 3)) {
 		msg_cdbg("Ignoring RES in favour of RDID.\n");
 		return 0;
@@ -250,13 +250,13 @@
 	/* Check if REMS is usable and does not return 0xff 0xff or
 	 * 0x00 0x00. In that case, RES is pointless.
 	 */
-	if (!spi_rems(readarr) && memcmp(readarr, allff, JEDEC_REMS_INSIZE) &&
+	if (!spi_rems(flash, readarr) && memcmp(readarr, allff, JEDEC_REMS_INSIZE) &&
 	    memcmp(readarr, all00, JEDEC_REMS_INSIZE)) {
 		msg_cdbg("Ignoring RES in favour of REMS.\n");
 		return 0;
 	}
 
-	if (spi_res(readarr, 1)) {
+	if (spi_res(flash, readarr, 1)) {
 		return 0;
 	}
 
@@ -279,7 +279,7 @@
 	unsigned char readarr[2];
 	uint32_t id1, id2;
 
-	if (spi_res(readarr, 2)) {
+	if (spi_res(flash, readarr, 2)) {
 		return 0;
 	}
 
@@ -298,7 +298,7 @@
 	return 1;
 }
 
-uint8_t spi_read_status_register(void)
+uint8_t spi_read_status_register(struct flashchip *flash)
 {
 	static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
 	/* FIXME: No workarounds for driver/hardware bugs in generic code. */
@@ -306,7 +306,7 @@
 	int ret;
 
 	/* Read Status Register */
-	ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
+	ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr);
 	if (ret)
 		msg_cerr("RDSR failed!\n");
 
@@ -414,7 +414,7 @@
 {
 	uint8_t status;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	msg_cdbg("Chip status register is %02x\n", status);
 	switch (flash->manufacture_id) {
 	case ST_ID:
@@ -465,7 +465,7 @@
 		.readarr	= NULL,
 	}};
 	
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution\n",
 			__func__);
@@ -475,7 +475,7 @@
 	 * This usually takes 1-85 s, so wait in 1 s steps.
 	 */
 	/* FIXME: We assume spi_read_status_register will never fail. */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(1000 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -502,7 +502,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution\n", __func__);
 		return result;
@@ -511,7 +511,7 @@
 	 * This usually takes 1-85 s, so wait in 1 s steps.
 	 */
 	/* FIXME: We assume spi_read_status_register will never fail. */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(1000 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -543,7 +543,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -552,7 +552,7 @@
 	/* Wait until the Write-In-Progress bit is cleared.
 	 * This usually takes 100-4000 ms, so wait in 100 ms steps.
 	 */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(100 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -589,7 +589,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -598,7 +598,7 @@
 	/* Wait until the Write-In-Progress bit is cleared.
 	 * This usually takes 100-4000 ms, so wait in 100 ms steps.
 	 */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(100 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -633,7 +633,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -642,7 +642,7 @@
 	/* Wait until the Write-In-Progress bit is cleared.
 	 * This usually takes 100-4000 ms, so wait in 100 ms steps.
 	 */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(100 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -675,7 +675,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -684,7 +684,7 @@
 	/* Wait until the Write-In-Progress bit is cleared.
 	 * This usually takes 15-800 ms, so wait in 10 ms steps.
 	 */
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(10 * 1000);
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -710,13 +710,13 @@
 	return spi_chip_erase_c7(flash);
 }
 
-int spi_write_status_enable(void)
+int spi_write_status_enable(struct flashchip *flash)
 {
 	static const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
 	int result;
 
 	/* Send EWSR (Enable Write Status Register). */
-	result = spi_send_command(sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
+	result = spi_send_command(flash, sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
 
 	if (result)
 		msg_cerr("%s failed\n", __func__);
@@ -751,7 +751,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution\n",
 			__func__);
@@ -766,7 +766,7 @@
 	 * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
 	 */
 	programmer_delay(100 * 1000);
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP) {
 		if (++i > 490) {
 			msg_cerr("Error: WIP bit after WRSR never cleared\n");
 			return TIMEOUT_ERROR;
@@ -799,7 +799,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution\n",
 			__func__);
@@ -814,7 +814,7 @@
 	 * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
 	 */
 	programmer_delay(100 * 1000);
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP) {
 		if (++i > 490) {
 			msg_cerr("Error: WIP bit after WRSR never cleared\n");
 			return TIMEOUT_ERROR;
@@ -840,7 +840,7 @@
 	return ret;
 }
 
-int spi_byte_program(int addr, uint8_t databyte)
+int spi_byte_program(struct flashchip *flash, int addr, uint8_t databyte)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -867,7 +867,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -875,7 +875,7 @@
 	return result;
 }
 
-int spi_nbyte_program(int addr, uint8_t *bytes, int len)
+int spi_nbyte_program(struct flashchip *flash, int addr, uint8_t *bytes, int len)
 {
 	int result;
 	/* FIXME: Switch to malloc based on len unless that kills speed. */
@@ -914,7 +914,7 @@
 
 	memcpy(&cmd[4], bytes, len);
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
 			__func__, addr);
@@ -931,7 +931,7 @@
 	uint8_t status;
 	int result;
 
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	/* If block protection is disabled, stop here. */
 	if ((status & 0x3c) == 0)
 		return 0;
@@ -942,7 +942,7 @@
 		msg_cerr("spi_write_status_register failed\n");
 		return result;
 	}
-	status = spi_read_status_register();
+	status = spi_read_status_register(flash);
 	if ((status & 0x3c) != 0) {
 		msg_cerr("Block protection could not be disabled!\n");
 		return 1;
@@ -950,7 +950,7 @@
 	return 0;
 }
 
-int spi_nbyte_read(int address, uint8_t *bytes, int len)
+int spi_nbyte_read(struct flashchip *flash, int address, uint8_t *bytes, int len)
 {
 	const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
 		JEDEC_READ,
@@ -960,7 +960,7 @@
 	};
 
 	/* Send Read */
-	return spi_send_command(sizeof(cmd), len, cmd, bytes);
+	return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
 }
 
 /*
@@ -992,7 +992,7 @@
 		lenhere = min(start + len, (i + 1) * page_size) - starthere;
 		for (j = 0; j < lenhere; j += chunksize) {
 			toread = min(chunksize, lenhere - j);
-			rc = spi_nbyte_read(starthere + j, buf + starthere - start + j, toread);
+			rc = spi_nbyte_read(flash, starthere + j, buf + starthere - start + j, toread);
 			if (rc)
 				break;
 		}
@@ -1037,10 +1037,10 @@
 		lenhere = min(start + len, (i + 1) * page_size) - starthere;
 		for (j = 0; j < lenhere; j += chunksize) {
 			towrite = min(chunksize, lenhere - j);
-			rc = spi_nbyte_program(starthere + j, buf + starthere - start + j, towrite);
+			rc = spi_nbyte_program(flash, starthere + j, buf + starthere - start + j, towrite);
 			if (rc)
 				break;
-			while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+			while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 				programmer_delay(10);
 		}
 		if (rc)
@@ -1062,10 +1062,10 @@
 	int i, result = 0;
 
 	for (i = start; i < start + len; i++) {
-		result = spi_byte_program(i, buf[i - start]);
+		result = spi_byte_program(flash, i, buf[i - start]);
 		if (result)
 			return 1;
-		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+		while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 			programmer_delay(10);
 	}
 
@@ -1150,7 +1150,7 @@
 	}
 
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during start command execution\n",
 			 __func__);
@@ -1159,7 +1159,7 @@
 		 */
 		return result;
 	}
-	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 		programmer_delay(10);
 
 	/* We already wrote 2 bytes in the multicommand step. */
@@ -1169,15 +1169,15 @@
 	while (pos < start + len - 1) {
 		cmd[1] = buf[pos++ - start];
 		cmd[2] = buf[pos++ - start];
-		spi_send_command(JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL);
-		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+		spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL);
+		while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP)
 			programmer_delay(10);
 	}
 
 	/* Use WRDI to exit AAI mode. This needs to be done before issuing any
 	 * other non-AAI command.
 	 */
-	spi_write_disable();
+	spi_write_disable(flash);
 
 	/* Write remaining byte (if any). */
 	if (pos < start + len) {
Index: flashrom-struct_flashchip_everywhere/pm49fl00x.c
===================================================================
--- flashrom-struct_flashchip_everywhere/pm49fl00x.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/pm49fl00x.c	(Arbeitskopie)
@@ -22,7 +22,7 @@
 
 #include "flash.h"
 
-static void write_lockbits_49fl00x(chipaddr bios, int size,
+static void write_lockbits_49fl00x(const struct flashchip *flash, chipaddr bios, int size,
 			    unsigned char bits, int block_size)
 {
 	int i, left = size;
@@ -32,18 +32,18 @@
 		if (block_size == 16384 && i % 2)
 			continue;
 
-		chip_writeb(bits, bios + (i * block_size) + 2);
+		chip_writeb(flash, bits, bios + (i * block_size) + 2);
 	}
 }
 
 int unlock_49fl00x(struct flashchip *flash)
 {
-	write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size);
+	write_lockbits_49fl00x(flash, flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size);
 	return 0;
 }
 
 int lock_49fl00x(struct flashchip *flash)
 {
-	write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 1, flash->page_size);
+	write_lockbits_49fl00x(flash, flash->virtual_registers, flash->total_size * 1024, 1, flash->page_size);
 	return 0;
 }
Index: flashrom-struct_flashchip_everywhere/it85spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/it85spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/it85spi.c	(Arbeitskopie)
@@ -268,7 +268,7 @@
 	return 0;
 }
 
-static int it85xx_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int it85xx_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *writearr, unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_it85xx = {
@@ -310,7 +310,7 @@
  *   3. read date from LPC/FWH address 0xffff_fdxxh (drive CE# low and get
  *      data from MISO)
  */
-static int it85xx_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int it85xx_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *writearr, unsigned char *readarr)
 {
 	int i;
Index: flashrom-struct_flashchip_everywhere/buspirate_spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/buspirate_spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/buspirate_spi.c	(Arbeitskopie)
@@ -86,7 +86,7 @@
 	return 0;
 }
 
-static int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int buspirate_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_buspirate = {
@@ -291,7 +291,7 @@
 	return 0;
 }
 
-static int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int buspirate_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
 	static unsigned char *buf = NULL;
Index: flashrom-struct_flashchip_everywhere/linux_spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/linux_spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/linux_spi.c	(Arbeitskopie)
@@ -34,7 +34,7 @@
 static int fd = -1;
 
 static int linux_spi_shutdown(void *data);
-static int linux_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int linux_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *txbuf, unsigned char *rxbuf);
 static int linux_spi_read(struct flashchip *flash, uint8_t *buf, int start,
 			  int len);
@@ -107,7 +107,7 @@
 	return 0;
 }
 
-static int linux_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int linux_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			const unsigned char *txbuf, unsigned char *rxbuf)
 {
 	struct spi_ioc_transfer msg[2] = {
Index: flashrom-struct_flashchip_everywhere/w29ee011.c
===================================================================
--- flashrom-struct_flashchip_everywhere/w29ee011.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/w29ee011.c	(Arbeitskopie)
@@ -38,29 +38,29 @@
 	}
 
 	/* Issue JEDEC Product ID Entry command */
-	chip_writeb(0xAA, bios + 0x5555);
+	chip_writeb(flash, 0xAA, bios + 0x5555);
 	programmer_delay(10);
-	chip_writeb(0x55, bios + 0x2AAA);
+	chip_writeb(flash, 0x55, bios + 0x2AAA);
 	programmer_delay(10);
-	chip_writeb(0x80, bios + 0x5555);
+	chip_writeb(flash, 0x80, bios + 0x5555);
 	programmer_delay(10);
-	chip_writeb(0xAA, bios + 0x5555);
+	chip_writeb(flash, 0xAA, bios + 0x5555);
 	programmer_delay(10);
-	chip_writeb(0x55, bios + 0x2AAA);
+	chip_writeb(flash, 0x55, bios + 0x2AAA);
 	programmer_delay(10);
-	chip_writeb(0x60, bios + 0x5555);
+	chip_writeb(flash, 0x60, bios + 0x5555);
 	programmer_delay(10);
 
 	/* Read product ID */
-	id1 = chip_readb(bios);
-	id2 = chip_readb(bios + 0x01);
+	id1 = chip_readb(flash, bios);
+	id2 = chip_readb(flash, bios + 0x01);
 
 	/* Issue JEDEC Product ID Exit command */
-	chip_writeb(0xAA, bios + 0x5555);
+	chip_writeb(flash, 0xAA, bios + 0x5555);
 	programmer_delay(10);
-	chip_writeb(0x55, bios + 0x2AAA);
+	chip_writeb(flash, 0x55, bios + 0x2AAA);
 	programmer_delay(10);
-	chip_writeb(0xF0, bios + 0x5555);
+	chip_writeb(flash, 0xF0, bios + 0x5555);
 	programmer_delay(10);
 
 	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
Index: flashrom-struct_flashchip_everywhere/spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/spi.c	(Arbeitskopie)
@@ -42,7 +42,7 @@
 
 const struct spi_programmer *spi_programmer = &spi_programmer_none;
 
-int spi_send_command(unsigned int writecnt, unsigned int readcnt,
+int spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
 	if (!spi_programmer->command) {
@@ -52,11 +52,11 @@
 		return 1;
 	}
 
-	return spi_programmer->command(writecnt, readcnt,
+	return spi_programmer->command(flash, writecnt, readcnt,
 						      writearr, readarr);
 }
 
-int spi_send_multicommand(struct spi_command *cmds)
+int spi_send_multicommand(struct flashchip *flash, struct spi_command *cmds)
 {
 	if (!spi_programmer->multicommand) {
 		msg_perr("%s called, but SPI is unsupported on this "
@@ -65,10 +65,10 @@
 		return 1;
 	}
 
-	return spi_programmer->multicommand(cmds);
+	return spi_programmer->multicommand(flash, cmds);
 }
 
-int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+int default_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			     const unsigned char *writearr, unsigned char *readarr)
 {
 	struct spi_command cmd[] = {
@@ -84,14 +84,14 @@
 		.readarr = NULL,
 	}};
 
-	return spi_send_multicommand(cmd);
+	return spi_send_multicommand(flash, cmd);
 }
 
-int default_spi_send_multicommand(struct spi_command *cmds)
+int default_spi_send_multicommand(struct flashchip *flash, struct spi_command *cmds)
 {
 	int result = 0;
 	for (; (cmds->writecnt || cmds->readcnt) && !result; cmds++) {
-		result = spi_send_command(cmds->writecnt, cmds->readcnt,
+		result = spi_send_command(flash, cmds->writecnt, cmds->readcnt,
 					  cmds->writearr, cmds->readarr);
 	}
 	return result;
@@ -135,7 +135,7 @@
 	 * address. Highest possible address with the current SPI implementation
 	 * means 0xffffff, the highest unsigned 24bit number.
 	 */
-	addrbase = spi_get_valid_read_addr();
+	addrbase = spi_get_valid_read_addr(flash);
 	if (addrbase + flash->total_size * 1024 > (1 << 24)) {
 		msg_perr("Flash chip size exceeds the allowed access window. ");
 		msg_perr("Read will probably fail.\n");
@@ -177,7 +177,7 @@
  * be the lowest allowed address for all commands which take an address.
  * This is a programmer limitation.
  */
-uint32_t spi_get_valid_read_addr(void)
+uint32_t spi_get_valid_read_addr(struct flashchip *flash)
 {
 	switch (spi_programmer->type) {
 #if CONFIG_INTERNAL == 1
Index: flashrom-struct_flashchip_everywhere/ft2232_spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/ft2232_spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/ft2232_spi.c	(Arbeitskopie)
@@ -144,7 +144,7 @@
 	return 0;
 }
 
-static int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int ft2232_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_ft2232 = {
@@ -342,7 +342,7 @@
 }
 
 /* Returns 0 upon success, a negative number upon errors. */
-static int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int ft2232_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
 	struct ftdi_context *ftdic = &ftdic_context;
Index: flashrom-struct_flashchip_everywhere/wbsio_spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/wbsio_spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/wbsio_spi.c	(Arbeitskopie)
@@ -60,7 +60,7 @@
 	return flashport;
 }
 
-static int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int wbsio_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		      const unsigned char *writearr, unsigned char *readarr);
 static int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 
@@ -110,7 +110,7 @@
  * Would one more byte of RAM in the chip (to get all 24 bits) really make
  * such a big difference?
  */
-static int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int wbsio_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		      const unsigned char *writearr, unsigned char *readarr)
 {
 	int i;
Index: flashrom-struct_flashchip_everywhere/sst28sf040.c
===================================================================
--- flashrom-struct_flashchip_everywhere/sst28sf040.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/sst28sf040.c	(Arbeitskopie)
@@ -34,13 +34,13 @@
 {
 	chipaddr bios = flash->virtual_memory;
 
-	chip_readb(bios + 0x1823);
-	chip_readb(bios + 0x1820);
-	chip_readb(bios + 0x1822);
-	chip_readb(bios + 0x0418);
-	chip_readb(bios + 0x041B);
-	chip_readb(bios + 0x0419);
-	chip_readb(bios + 0x040A);
+	chip_readb(flash, bios + 0x1823);
+	chip_readb(flash, bios + 0x1820);
+	chip_readb(flash, bios + 0x1822);
+	chip_readb(flash, bios + 0x0418);
+	chip_readb(flash, bios + 0x041B);
+	chip_readb(flash, bios + 0x0419);
+	chip_readb(flash, bios + 0x040A);
 
 	return 0;
 }
@@ -49,13 +49,13 @@
 {
 	chipaddr bios = flash->virtual_memory;
 
-	chip_readb(bios + 0x1823);
-	chip_readb(bios + 0x1820);
-	chip_readb(bios + 0x1822);
-	chip_readb(bios + 0x0418);
-	chip_readb(bios + 0x041B);
-	chip_readb(bios + 0x0419);
-	chip_readb(bios + 0x041A);
+	chip_readb(flash, bios + 0x1823);
+	chip_readb(flash, bios + 0x1820);
+	chip_readb(flash, bios + 0x1822);
+	chip_readb(flash, bios + 0x0418);
+	chip_readb(flash, bios + 0x041B);
+	chip_readb(flash, bios + 0x0419);
+	chip_readb(flash, bios + 0x041A);
 
 	return 0;
 }
@@ -65,11 +65,11 @@
 	chipaddr bios = flash->virtual_memory;
 
 	/* This command sequence is very similar to erase_block_82802ab. */
-	chip_writeb(AUTO_PG_ERASE1, bios);
-	chip_writeb(AUTO_PG_ERASE2, bios + address);
+	chip_writeb(flash, AUTO_PG_ERASE1, bios);
+	chip_writeb(flash, AUTO_PG_ERASE2, bios + address);
 
 	/* wait for Toggle bit ready */
-	toggle_ready_jedec(bios);
+	toggle_ready_jedec(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -90,11 +90,11 @@
 			continue;
 		}
 		/*issue AUTO PROGRAM command */
-		chip_writeb(AUTO_PGRM, dst);
-		chip_writeb(*src++, dst++);
+		chip_writeb(flash, AUTO_PGRM, dst);
+		chip_writeb(flash, *src++, dst++);
 
 		/* wait for Toggle bit ready */
-		toggle_ready_jedec(bios);
+		toggle_ready_jedec(flash, bios);
 	}
 
 	return 0;
@@ -104,11 +104,11 @@
 {
 	chipaddr bios = flash->virtual_memory;
 
-	chip_writeb(CHIP_ERASE, bios);
-	chip_writeb(CHIP_ERASE, bios);
+	chip_writeb(flash, CHIP_ERASE, bios);
+	chip_writeb(flash, CHIP_ERASE, bios);
 
 	programmer_delay(10);
-	toggle_ready_jedec(bios);
+	toggle_ready_jedec(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
Index: flashrom-struct_flashchip_everywhere/stm50flw0x0x.c
===================================================================
--- flashrom-struct_flashchip_everywhere/stm50flw0x0x.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/stm50flw0x0x.c	(Arbeitskopie)
@@ -60,8 +60,8 @@
 		// unlock each 4k-sector
 		for (j = 0; j < 0x10000; j += 0x1000) {
 			msg_cdbg("unlocking at 0x%x\n", offset + j);
-			chip_writeb(unlock_sector, wrprotect + offset + j);
-			if (chip_readb(wrprotect + offset + j) != unlock_sector) {
+			chip_writeb(flash, unlock_sector, wrprotect + offset + j);
+			if (chip_readb(flash, wrprotect + offset + j) != unlock_sector) {
 				msg_cerr("Cannot unlock sector @ 0x%x\n",
 				       offset + j);
 				return -1;
@@ -69,8 +69,8 @@
 		}
 	} else {
 		msg_cdbg("unlocking at 0x%x\n", offset);
-		chip_writeb(unlock_sector, wrprotect + offset);
-		if (chip_readb(wrprotect + offset) != unlock_sector) {
+		chip_writeb(flash, unlock_sector, wrprotect + offset);
+		if (chip_readb(flash, wrprotect + offset) != unlock_sector) {
 			msg_cerr("Cannot unlock sector @ 0x%x\n", offset);
 			return -1;
 		}
@@ -99,10 +99,10 @@
 	chipaddr bios = flash->virtual_memory + sector;
 
 	// clear status register
-	chip_writeb(0x50, bios);
+	chip_writeb(flash, 0x50, bios);
 	// now start it
-	chip_writeb(0x32, bios);
-	chip_writeb(0xd0, bios);
+	chip_writeb(flash, 0x32, bios);
+	chip_writeb(flash, 0xd0, bios);
 	programmer_delay(10);
 
 	wait_82802ab(flash);
Index: flashrom-struct_flashchip_everywhere/sb600spi.c
===================================================================
--- flashrom-struct_flashchip_everywhere/sb600spi.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/sb600spi.c	(Arbeitskopie)
@@ -88,7 +88,7 @@
 		;
 }
 
-static int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int sb600_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		      const unsigned char *writearr, unsigned char *readarr)
 {
 	int count;
Index: flashrom-struct_flashchip_everywhere/programmer.c
===================================================================
--- flashrom-struct_flashchip_everywhere/programmer.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/programmer.c	(Arbeitskopie)
@@ -39,60 +39,60 @@
 }
 
 /* No-op chip_writeb() for drivers not supporting addr/data pair accesses */
-uint8_t noop_chip_readb(const chipaddr addr)
+uint8_t noop_chip_readb(struct flashchip *flash, const chipaddr addr)
 {
 	return 0xff;
 }
 
 /* No-op chip_writeb() for drivers not supporting addr/data pair accesses */
-void noop_chip_writeb(uint8_t val, chipaddr addr)
+void noop_chip_writeb(struct flashchip *flash, uint8_t val, chipaddr addr)
 {
 }
 
 /* Little-endian fallback for drivers not supporting 16 bit accesses */
-void fallback_chip_writew(uint16_t val, chipaddr addr)
+void fallback_chip_writew(const struct flashchip *flash, uint16_t val, chipaddr addr)
 {
-	chip_writeb(val & 0xff, addr);
-	chip_writeb((val >> 8) & 0xff, addr + 1);
+	chip_writeb(flash, val & 0xff, addr);
+	chip_writeb(flash, (val >> 8) & 0xff, addr + 1);
 }
 
 /* Little-endian fallback for drivers not supporting 16 bit accesses */
-uint16_t fallback_chip_readw(const chipaddr addr)
+uint16_t fallback_chip_readw(struct flashchip *flash, const chipaddr addr)
 {
 	uint16_t val;
-	val = chip_readb(addr);
-	val |= chip_readb(addr + 1) << 8;
+	val = chip_readb(flash, addr);
+	val |= chip_readb(flash, addr + 1) << 8;
 	return val;
 }
 
 /* Little-endian fallback for drivers not supporting 32 bit accesses */
-void fallback_chip_writel(uint32_t val, chipaddr addr)
+void fallback_chip_writel(const struct flashchip *flash, uint32_t val, chipaddr addr)
 {
-	chip_writew(val & 0xffff, addr);
-	chip_writew((val >> 16) & 0xffff, addr + 2);
+	chip_writew(flash, val & 0xffff, addr);
+	chip_writew(flash, (val >> 16) & 0xffff, addr + 2);
 }
 
 /* Little-endian fallback for drivers not supporting 32 bit accesses */
-uint32_t fallback_chip_readl(const chipaddr addr)
+uint32_t fallback_chip_readl(struct flashchip *flash, const chipaddr addr)
 {
 	uint32_t val;
-	val = chip_readw(addr);
-	val |= chip_readw(addr + 2) << 16;
+	val = chip_readw(flash, addr);
+	val |= chip_readw(flash, addr + 2) << 16;
 	return val;
 }
 
-void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len)
+void fallback_chip_writen(const struct flashchip *flash, uint8_t *buf, chipaddr addr, size_t len)
 {
 	size_t i;
 	for (i = 0; i < len; i++)
-		chip_writeb(buf[i], addr + i);
+		chip_writeb(flash, buf[i], addr + i);
 	return;
 }
 
-void fallback_chip_readn(uint8_t *buf, chipaddr addr, size_t len)
+void fallback_chip_readn(struct flashchip *flash, uint8_t *buf, chipaddr addr, size_t len)
 {
 	size_t i;
 	for (i = 0; i < len; i++)
-		buf[i] = chip_readb(addr + i);
+		buf[i] = chip_readb(flash, addr + i);
 	return;
 }
Index: flashrom-struct_flashchip_everywhere/flashrom.c
===================================================================
--- flashrom-struct_flashchip_everywhere/flashrom.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/flashrom.c	(Arbeitskopie)
@@ -511,43 +511,47 @@
 	programmer_table[programmer].unmap_flash_region(virt_addr, len);
 }
 
-void chip_writeb(uint8_t val, chipaddr addr)
+void chip_writeb(const struct flashchip *flash, uint8_t val, chipaddr addr)
 {
 	programmer_table[programmer].chip_writeb(val, addr);
 }
 
-void chip_writew(uint16_t val, chipaddr addr)
+void chip_writew(const struct flashchip *flash, uint16_t val, chipaddr addr)
 {
 	programmer_table[programmer].chip_writew(val, addr);
 }
 
-void chip_writel(uint32_t val, chipaddr addr)
+void chip_writel(const struct flashchip *flash, uint32_t val, chipaddr addr)
 {
 	programmer_table[programmer].chip_writel(val, addr);
 }
 
-void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
+void chip_writen(const struct flashchip *flash, uint8_t *buf, chipaddr addr, size_t len)
 {
 	programmer_table[programmer].chip_writen(buf, addr, len);
 }
 
-uint8_t chip_readb(const chipaddr addr)
+uint8_t chip_readb(const struct flashchip *flash, const chipaddr addr)
 {
+	// FIXME: Pass on flash to the programmer
 	return programmer_table[programmer].chip_readb(addr);
 }
 
-uint16_t chip_readw(const chipaddr addr)
+uint16_t chip_readw(const struct flashchip *flash, const chipaddr addr)
 {
+	// FIXME: Pass on flash to the programmer
 	return programmer_table[programmer].chip_readw(addr);
 }
 
-uint32_t chip_readl(const chipaddr addr)
+uint32_t chip_readl(const struct flashchip *flash, const chipaddr addr)
 {
+	// FIXME: Pass on flash to the programmer
 	return programmer_table[programmer].chip_readl(addr);
 }
 
-void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
+void chip_readn(const struct flashchip *flash, uint8_t *buf, chipaddr addr, size_t len)
 {
+	// FIXME: Pass on flash to the programmer
 	programmer_table[programmer].chip_readn(buf, addr, len);
 }
 
@@ -566,7 +570,7 @@
 
 int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-	chip_readn(buf, flash->virtual_memory + start, len);
+	chip_readn(flash, buf, flash->virtual_memory + start, len);
 
 	return 0;
 }
Index: flashrom-struct_flashchip_everywhere/programmer.h
===================================================================
--- flashrom-struct_flashchip_everywhere/programmer.h	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/programmer.h	(Arbeitskopie)
@@ -558,9 +558,9 @@
 	enum spi_controller type;
 	int max_data_read;
 	int max_data_write;
-	int (*command)(unsigned int writecnt, unsigned int readcnt,
+	int (*command)(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 		   const unsigned char *writearr, unsigned char *readarr);
-	int (*multicommand)(struct spi_command *cmds);
+	int (*multicommand)(struct flashchip *flash, struct spi_command *cmds);
 
 	/* Optimized functions for this programmer */
 	int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
@@ -568,9 +568,9 @@
 };
 
 extern const struct spi_programmer *spi_programmer;
-int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+int default_spi_send_command(struct flashchip *flash, unsigned int writecnt, unsigned int readcnt,
 			     const unsigned char *writearr, unsigned char *readarr);
-int default_spi_send_multicommand(struct spi_command *cmds);
+int default_spi_send_multicommand(struct flashchip *flash, struct spi_command *cmds);
 int default_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 int default_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
 void register_spi_programmer(const struct spi_programmer *programmer);
@@ -608,10 +608,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-struct_flashchip_everywhere/chipdrivers.h
===================================================================
--- flashrom-struct_flashchip_everywhere/chipdrivers.h	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/chipdrivers.h	(Arbeitskopie)
@@ -33,8 +33,8 @@
 int probe_spi_rems(struct flashchip *flash);
 int probe_spi_res1(struct flashchip *flash);
 int probe_spi_res2(struct flashchip *flash);
-int spi_write_enable(void);
-int spi_write_disable(void);
+int spi_write_enable(struct flashchip *flash);
+int spi_write_disable(struct flashchip *flash);
 int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
@@ -44,16 +44,16 @@
 int spi_chip_write_1(struct flashchip *flash, uint8_t *buf, int start, int len);
 int spi_chip_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
 int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
-uint8_t spi_read_status_register(void);
+uint8_t spi_read_status_register(struct flashchip *flash);
 int spi_write_status_register(struct flashchip *flash, int status);
 void spi_prettyprint_status_register_bit(uint8_t status, int bit);
 void spi_prettyprint_status_register_bp3210(uint8_t status, int bp);
 void spi_prettyprint_status_register_welwip(uint8_t status);
 int spi_prettyprint_status_register(struct flashchip *flash);
 int spi_disable_blockprotect(struct flashchip *flash);
-int spi_byte_program(int addr, uint8_t databyte);
-int spi_nbyte_program(int addr, uint8_t *bytes, int len);
-int spi_nbyte_read(int addr, uint8_t *bytes, int len);
+int spi_byte_program(struct flashchip *flash, int addr, uint8_t databyte);
+int spi_nbyte_program(struct flashchip *flash, int addr, uint8_t *bytes, int len);
+int spi_nbyte_read(struct flashchip *flash, int addr, uint8_t *bytes, int len);
 int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
 int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
 int spi_aai_write(struct flashchip *flash, uint8_t *buf, int start, int len);
@@ -89,9 +89,9 @@
 
 /* jedec.c */
 uint8_t oddparity(uint8_t val);
-void toggle_ready_jedec(chipaddr dst);
-void data_polling_jedec(chipaddr dst, uint8_t data);
-int write_byte_program_jedec(chipaddr bios, uint8_t *src,
+void toggle_ready_jedec(struct flashchip *flash, chipaddr dst);
+void data_polling_jedec(struct flashchip *flash, chipaddr dst, uint8_t data);
+int write_byte_program_jedec(struct flashchip *flash, chipaddr bios, uint8_t *src,
 			     chipaddr dst);
 int probe_jedec(struct flashchip *flash);
 int write_jedec(struct flashchip *flash, uint8_t *buf, int start, int len);
@@ -105,7 +105,7 @@
 int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len);
 int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len);
 int write_m29f400bt(struct flashchip *flash, uint8_t *buf, int start, int len);
-void protect_m29f400bt(chipaddr bios);
+void protect_m29f400bt(struct flashchip *flash, chipaddr bios);
 
 /* pm49fl00x.c */
 int unlock_49fl00x(struct flashchip *flash);
Index: flashrom-struct_flashchip_everywhere/m29f400bt.c
===================================================================
--- flashrom-struct_flashchip_everywhere/m29f400bt.c	(Revision 1458)
+++ flashrom-struct_flashchip_everywhere/m29f400bt.c	(Arbeitskopie)
@@ -35,17 +35,17 @@
 	chipaddr dst = flash->virtual_memory + start;
 
 	for (i = 0; i < len; i++) {
-		chip_writeb(0xAA, bios + 0xAAA);
-		chip_writeb(0x55, bios + 0x555);
-		chip_writeb(0xA0, bios + 0xAAA);
+		chip_writeb(flash, 0xAA, bios + 0xAAA);
+		chip_writeb(flash, 0x55, bios + 0x555);
+		chip_writeb(flash, 0xA0, bios + 0xAAA);
 
 		/* transfer data from source to destination */
-		chip_writeb(*src, dst);
-		toggle_ready_jedec(dst);
+		chip_writeb(flash, *src, dst);
+		toggle_ready_jedec(flash, dst);
 #if 0
 		/* We only want to print something in the error case. */
 		msg_cerr("Value in the flash at address 0x%lx = %#x, want %#x\n",
-		     (dst - bios), chip_readb(dst), *src);
+		     (dst - bios), chip_readb(flash, dst), *src);
 #endif
 		dst++;
 		src++;
@@ -60,21 +60,21 @@
 	chipaddr bios = flash->virtual_memory;
 	uint8_t id1, id2;
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0x90, bios + 0xAAA);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0x90, bios + 0xAAA);
 
 	programmer_delay(10);
 
-	id1 = chip_readb(bios);
+	id1 = chip_readb(flash, bios);
 	/* The data sheet says id2 is at (bios + 0x01) and id2 listed in
 	 * flash.h does not match. It should be possible to use JEDEC probe.
 	 */
-	id2 = chip_readb(bios + 0x02);
+	id2 = chip_readb(flash, bios + 0x02);
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0xF0, bios + 0xAAA);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0xF0, bios + 0xAAA);
 
 	programmer_delay(10);
 
@@ -90,16 +90,16 @@
 {
 	chipaddr bios = flash->virtual_memory;
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0x80, bios + 0xAAA);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0x80, bios + 0xAAA);
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0x10, bios + 0xAAA);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0x10, bios + 0xAAA);
 
 	programmer_delay(10);
-	toggle_ready_jedec(bios);
+	toggle_ready_jedec(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;
@@ -110,16 +110,16 @@
 	chipaddr bios = flash->virtual_memory;
 	chipaddr dst = bios + start;
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0x80, bios + 0xAAA);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0x80, bios + 0xAAA);
 
-	chip_writeb(0xAA, bios + 0xAAA);
-	chip_writeb(0x55, bios + 0x555);
-	chip_writeb(0x30, dst);
+	chip_writeb(flash, 0xAA, bios + 0xAAA);
+	chip_writeb(flash, 0x55, bios + 0x555);
+	chip_writeb(flash, 0x30, dst);
 
 	programmer_delay(10);
-	toggle_ready_jedec(bios);
+	toggle_ready_jedec(flash, bios);
 
 	/* FIXME: Check the status register for errors. */
 	return 0;


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





More information about the flashrom mailing list