diff --git a/82802ab.c b/82802ab.c
index 228d071f222ffbb1099584df3521395f33ca4c36..79e157a41c0b5f4984a682cc5f1ee644035a164a 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -47,18 +47,18 @@ int probe_82802ab(struct flashctx *flash)
 	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 @@ int probe_82802ab(struct flashctx *flash)
 	 * 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 wait_82802ab(struct flashctx *flash)
 	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 @@ int unlock_82802ab(struct flashctx *flash)
 	//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 @@ int erase_block_82802ab(struct flashctx *flash, unsigned int page,
 	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
@@ -141,15 +141,16 @@ int erase_block_82802ab(struct flashctx *flash, unsigned int page,
 }
 
 /* chunksize is 1 */
-int write_82802ab(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
+int write_82802ab(struct flashctx *flash, uint8_t *src, unsigned int start,
+		  unsigned int len)
 {
 	int i;
 	chipaddr dst = flash->virtual_memory + start;
 
 	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 +165,13 @@ int unlock_28f004s5(struct flashctx *flash)
 	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 +182,7 @@ int unlock_28f004s5(struct flashctx *flash)
 
 	/* 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 +190,14 @@ int unlock_28f004s5(struct flashctx *flash)
 	}
 
 	/* 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 +221,10 @@ int unlock_lh28f008bjt(struct flashctx *flash)
 	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 +236,7 @@ int unlock_lh28f008bjt(struct flashctx *flash)
 	/* 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 +244,14 @@ int unlock_lh28f008bjt(struct flashctx *flash)
 	}
 
 	/* 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");
 	}
diff --git a/a25.c b/a25.c
index f7641cb8012a716e1d26a4a4c997680b08fb979a..b0c6b906493585277a5676109466d3da863b208b 100644
--- a/a25.c
+++ b/a25.c
@@ -33,7 +33,7 @@ int spi_prettyprint_status_register_amic_a25l05p(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_amic_a25l40p(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_amic_a25l032(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_amic_a25lq032(struct flashctx *flash)
 {
 	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);
diff --git a/at25.c b/at25.c
index eccf4c899721d81e65eb2997f47a82fbdd90a7cd..ec9b4b69c01b84ec60980c4a7630c81732756947 100644
--- a/at25.c
+++ b/at25.c
@@ -61,7 +61,7 @@ int spi_prettyprint_status_register_at25df(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_at25f(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_at25fs010(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_at25fs040(struct flashctx *flash)
 {
 	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 @@ int spi_prettyprint_status_register_atmel_at26df081a(struct flashctx *flash)
 {
 	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 @@ int spi_disable_blockprotect_at25df(struct flashctx *flash)
 	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 @@ int spi_disable_blockprotect_at25df(struct flashctx *flash)
 		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 @@ int spi_disable_blockprotect_at25fs010(struct flashctx *flash)
 	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 @@ int spi_disable_blockprotect_at25fs010(struct flashctx *flash)
 		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 @@ int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
 	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 @@ int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
 		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;
diff --git a/atahpt.c b/atahpt.c
index 6252865a03d9f2908e2756c1cf14df0558f096ae..4234f6d3f475acc7706990f84dface9a96ed1b94 100644
--- a/atahpt.c
+++ b/atahpt.c
@@ -40,6 +40,10 @@ const struct pcidev_status ata_hpt[] = {
 	{},
 };
 
+static void atahpt_chip_writeb(const struct flashctx *flash, uint8_t val,
+			       chipaddr addr);
+static uint8_t atahpt_chip_readb(const struct flashctx *flash,
+				 const chipaddr addr);
 static const struct par_programmer par_programmer_atahpt = {
 		.chip_readb		= atahpt_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -80,13 +84,15 @@ int atahpt_init(void)
 	return 0;
 }
 
-void atahpt_chip_writeb(uint8_t val, chipaddr addr)
+static void atahpt_chip_writeb(const struct flashctx *flash, uint8_t val,
+			       chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
 	OUTB(val, io_base_addr + BIOS_ROM_DATA);
 }
 
-uint8_t atahpt_chip_readb(const chipaddr addr)
+static uint8_t atahpt_chip_readb(const struct flashctx *flash,
+				 const chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
 	return INB(io_base_addr + BIOS_ROM_DATA);
diff --git a/bitbang_spi.c b/bitbang_spi.c
index 391fd324662788b3d1475d1e717d04e3a8be90db..5ee52f54242e672e20c85ba73c3deebb8ecdade7 100644
--- a/bitbang_spi.c
+++ b/bitbang_spi.c
@@ -63,8 +63,10 @@ static void bitbang_spi_release_bus(void)
 		bitbang_spi_master->release_bus();
 }
 
-static int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr);
+static int bitbang_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_bitbang = {
 	.type		= SPI_CONTROLLER_BITBANG,
@@ -141,8 +143,10 @@ static uint8_t bitbang_spi_readwrite_byte(uint8_t val)
 	return ret;
 }
 
-static int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr)
+static int bitbang_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr)
 {
 	int i;
 
diff --git a/buspirate_spi.c b/buspirate_spi.c
index fd06b5984aa8ceaf790c55cc018fe3af19070918..f816afdf7473cd68b98d2f6db9ade18186163569 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -86,8 +86,11 @@ static int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt,
 	return 0;
 }
 
-static int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr);
+static int buspirate_spi_send_command(struct flashctx *flash,
+				      unsigned int writecnt,
+				      unsigned int readcnt,
+				      const unsigned char *writearr,
+				      unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_buspirate = {
 	.type		= SPI_CONTROLLER_BUSPIRATE,
@@ -291,8 +294,11 @@ int buspirate_spi_init(void)
 	return 0;
 }
 
-static int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr)
+static int buspirate_spi_send_command(struct flashctx *flash,
+				      unsigned int writecnt,
+				      unsigned int readcnt,
+				      const unsigned char *writearr,
+				      unsigned char *readarr)
 {
 	static unsigned char *buf = NULL;
 	unsigned int i = 0;
diff --git a/chipdrivers.h b/chipdrivers.h
index ce0f9acd68a1811b88d60d3ac85195f5f247cde7..a1d0cd9c829155438f21c7f0c79b576e9fe94d5b 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -33,8 +33,8 @@ int probe_spi_rdid4(struct flashctx *flash);
 int probe_spi_rems(struct flashctx *flash);
 int probe_spi_res1(struct flashctx *flash);
 int probe_spi_res2(struct flashctx *flash);
-int spi_write_enable(void);
-int spi_write_disable(void);
+int spi_write_enable(struct flashctx *flash);
+int spi_write_disable(struct flashctx *flash);
 int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
@@ -44,16 +44,16 @@ int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int b
 int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len);
-uint8_t spi_read_status_register(void);
+uint8_t spi_read_status_register(struct flashctx *flash);
 int spi_write_status_register(struct flashctx *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 flashctx *flash);
 int spi_disable_blockprotect(struct flashctx *flash);
-int spi_byte_program(unsigned int addr, uint8_t databyte);
-int spi_nbyte_program(unsigned int addr, uint8_t *bytes, unsigned int len);
-int spi_nbyte_read(unsigned int addr, uint8_t *bytes, unsigned int len);
+int spi_byte_program(struct flashctx *flash, unsigned int addr, uint8_t databyte);
+int spi_nbyte_program(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len);
+int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len);
 int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
 int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
 int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
@@ -95,9 +95,9 @@ int unlock_lh28f008bjt(struct flashctx *flash);
 
 /* 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 flashctx *flash, chipaddr dst);
+void data_polling_jedec(struct flashctx *flash, chipaddr dst, uint8_t data);
+int write_byte_program_jedec(struct flashctx *flash, chipaddr bios, uint8_t *src,
 			     chipaddr dst);
 int probe_jedec(struct flashctx *flash);
 int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
@@ -111,7 +111,7 @@ int probe_m29f400bt(struct flashctx *flash);
 int block_erase_m29f400bt(struct flashctx *flash, unsigned int start, unsigned int len);
 int block_erase_chip_m29f400bt(struct flashctx *flash, unsigned int start, unsigned int len);
 int write_m29f400bt(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
-void protect_m29f400bt(chipaddr bios);
+void protect_m29f400bt(struct flashctx *flash, chipaddr bios);
 
 /* pm49fl00x.c */
 int unlock_49fl00x(struct flashctx *flash);
diff --git a/dediprog.c b/dediprog.c
index 4161f62f36657def461b97afa1c4671809fb7071..db29c13efdecd81d62361363a225d63604ef2bf7 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -317,8 +317,11 @@ static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf,
 	return ret;
 }
 
-static int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			const unsigned char *writearr, unsigned char *readarr)
+static int dediprog_spi_send_command(struct flashctx *flash,
+				     unsigned int writecnt,
+				     unsigned int readcnt,
+				     const unsigned char *writearr,
+				     unsigned char *readarr)
 {
 	int ret;
 
diff --git a/drkaiser.c b/drkaiser.c
index 9f2202e18048c94f62c90a693737bbfafefafa00..362db57996bcd11b03cf820226bdbdc9e8869113 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -39,6 +39,10 @@ const struct pcidev_status drkaiser_pcidev[] = {
 
 static uint8_t *drkaiser_bar;
 
+static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr);
+static uint8_t drkaiser_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr);
 static const struct par_programmer par_programmer_drkaiser = {
 		.chip_readb		= drkaiser_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -84,12 +88,14 @@ int drkaiser_init(void)
 	return 0;
 }
 
-void drkaiser_chip_writeb(uint8_t val, chipaddr addr)
+static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr)
 {
 	pci_mmio_writeb(val, drkaiser_bar + (addr & DRKAISER_MEMMAP_MASK));
 }
 
-uint8_t drkaiser_chip_readb(const chipaddr addr)
+static uint8_t drkaiser_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr)
 {
 	return pci_mmio_readb(drkaiser_bar + (addr & DRKAISER_MEMMAP_MASK));
 }
diff --git a/dummyflasher.c b/dummyflasher.c
index cb975b46e9a1325f6bd6cde8329275f9cbc1e1d2..99f81f5f74052e4e8759da2ba139a8c4af4870f4 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -60,10 +60,28 @@ static unsigned int emu_jedec_ce_c7_size = 0;
 
 static unsigned int spi_write_256_chunksize = 256;
 
-static int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		      const unsigned char *writearr, unsigned char *readarr);
+static int dummy_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *writearr,
+				  unsigned char *readarr);
 static int dummy_spi_write_256(struct flashctx *flash, uint8_t *buf,
 			       unsigned int start, unsigned int len);
+static void dummy_chip_writeb(const struct flashctx *flash, uint8_t val,
+			      chipaddr addr);
+static void dummy_chip_writew(const struct flashctx *flash, uint16_t val,
+			      chipaddr addr);
+static void dummy_chip_writel(const struct flashctx *flash, uint32_t val,
+			      chipaddr addr);
+static void dummy_chip_writen(const struct flashctx *flash, uint8_t *buf,
+			      chipaddr addr, size_t len);
+static uint8_t dummy_chip_readb(const struct flashctx *flash,
+				const chipaddr addr);
+static uint16_t dummy_chip_readw(const struct flashctx *flash,
+				 const chipaddr addr);
+static uint32_t dummy_chip_readl(const struct flashctx *flash,
+				 const chipaddr addr);
+static void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf,
+			     const chipaddr addr, size_t len);
 
 static const struct spi_programmer spi_programmer_dummyflasher = {
 	.type		= SPI_CONTROLLER_DUMMY,
@@ -263,22 +281,26 @@ void dummy_unmap(void *virt_addr, size_t len)
 		  __func__, (unsigned long)len, virt_addr);
 }
 
-void dummy_chip_writeb(uint8_t val, chipaddr addr)
+static void dummy_chip_writeb(const struct flashctx *flash, uint8_t val,
+			      chipaddr addr)
 {
 	msg_pspew("%s: addr=0x%lx, val=0x%02x\n", __func__, addr, val);
 }
 
-void dummy_chip_writew(uint16_t val, chipaddr addr)
+static void dummy_chip_writew(const struct flashctx *flash, uint16_t val,
+			      chipaddr addr)
 {
 	msg_pspew("%s: addr=0x%lx, val=0x%04x\n", __func__, addr, val);
 }
 
-void dummy_chip_writel(uint32_t val, chipaddr addr)
+static void dummy_chip_writel(const struct flashctx *flash, uint32_t val,
+			      chipaddr addr)
 {
 	msg_pspew("%s: addr=0x%lx, val=0x%08x\n", __func__, addr, val);
 }
 
-void dummy_chip_writen(uint8_t *buf, chipaddr addr, size_t len)
+static void dummy_chip_writen(const struct flashctx *flash, uint8_t *buf,
+			      chipaddr addr, size_t len)
 {
 	size_t i;
 	msg_pspew("%s: addr=0x%lx, len=0x%08lx, writing data (hex):",
@@ -290,25 +312,29 @@ void dummy_chip_writen(uint8_t *buf, chipaddr addr, size_t len)
 	}
 }
 
-uint8_t dummy_chip_readb(const chipaddr addr)
+static uint8_t dummy_chip_readb(const struct flashctx *flash,
+				const chipaddr addr)
 {
 	msg_pspew("%s:  addr=0x%lx, returning 0xff\n", __func__, addr);
 	return 0xff;
 }
 
-uint16_t dummy_chip_readw(const chipaddr addr)
+static uint16_t dummy_chip_readw(const struct flashctx *flash,
+				 const chipaddr addr)
 {
 	msg_pspew("%s:  addr=0x%lx, returning 0xffff\n", __func__, addr);
 	return 0xffff;
 }
 
-uint32_t dummy_chip_readl(const chipaddr addr)
+static uint32_t dummy_chip_readl(const struct flashctx *flash,
+				 const chipaddr addr)
 {
 	msg_pspew("%s:  addr=0x%lx, returning 0xffffffff\n", __func__, addr);
 	return 0xffffffff;
 }
 
-void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len)
+static void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf,
+			     const chipaddr addr, size_t len)
 {
 	msg_pspew("%s:  addr=0x%lx, len=0x%lx, returning array of 0xff\n",
 		  __func__, addr, (unsigned long)len);
@@ -317,8 +343,10 @@ void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len)
 }
 
 #if EMULATE_SPI_CHIP
-static int emulate_spi_chip_response(unsigned int writecnt, unsigned int readcnt,
-		      const unsigned char *writearr, unsigned char *readarr)
+static int emulate_spi_chip_response(unsigned int writecnt,
+				     unsigned int readcnt,
+				     const unsigned char *writearr,
+				     unsigned char *readarr)
 {
 	unsigned int offs;
 	static int unsigned aai_offs;
@@ -513,8 +541,10 @@ static int emulate_spi_chip_response(unsigned int writecnt, unsigned int readcnt
 }
 #endif
 
-static int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		      const unsigned char *writearr, unsigned char *readarr)
+static int dummy_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *writearr,
+				  unsigned char *readarr)
 {
 	int i;
 
diff --git a/flash.h b/flash.h
index b1cd280792c58a1ef78c11512d5a924593514825..29ba1932e78dccf99b41353c0fc91d6fe6788f56 100644
--- a/flash.h
+++ b/flash.h
@@ -44,14 +44,6 @@ int register_shutdown(int (*function) (void *data), void *data);
 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]))
@@ -212,6 +204,15 @@ struct flashctx {
 
 extern const struct flashchip flashchips[];
 
+void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr);
+void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr);
+void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr);
+void chip_writen(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len);
+uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr);
+uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr);
+uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr);
+void chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len);
+
 /* print.c */
 char *flashbuses_to_text(enum chipbustype bustype);
 void print_supported(void);
@@ -292,9 +293,8 @@ struct spi_command {
 	const unsigned char *writearr;
 	unsigned char *readarr;
 };
-int spi_send_command(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_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
+int spi_send_multicommand(struct flashctx *flash, struct spi_command *cmds);
+uint32_t spi_get_valid_read_addr(struct flashctx *flash);
 
 #endif				/* !__FLASH_H__ */
diff --git a/flashrom.c b/flashrom.c
index 6cba06c5d80b72d3c0662d1fcb079496c670fe64..f7a17d1398aa921cb0d52f419a1bccc01e32ca68 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -359,44 +359,46 @@ void programmer_unmap_flash_region(void *virt_addr, size_t len)
 	programmer_table[programmer].unmap_flash_region(virt_addr, len);
 }
 
-void chip_writeb(uint8_t val, chipaddr addr)
+void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
 {
-	par_programmer->chip_writeb(val, addr);
+	par_programmer->chip_writeb(flash, val, addr);
 }
 
-void chip_writew(uint16_t val, chipaddr addr)
+void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
 {
-	par_programmer->chip_writew(val, addr);
+	par_programmer->chip_writew(flash, val, addr);
 }
 
-void chip_writel(uint32_t val, chipaddr addr)
+void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
 {
-	par_programmer->chip_writel(val, addr);
+	par_programmer->chip_writel(flash, val, addr);
 }
 
-void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
+void chip_writen(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
+		 size_t len)
 {
-	par_programmer->chip_writen(buf, addr, len);
+	par_programmer->chip_writen(flash, buf, addr, len);
 }
 
-uint8_t chip_readb(const chipaddr addr)
+uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
 {
-	return par_programmer->chip_readb(addr);
+	return par_programmer->chip_readb(flash, addr);
 }
 
-uint16_t chip_readw(const chipaddr addr)
+uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
 {
-	return par_programmer->chip_readw(addr);
+	return par_programmer->chip_readw(flash, addr);
 }
 
-uint32_t chip_readl(const chipaddr addr)
+uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
 {
-	return par_programmer->chip_readl(addr);
+	return par_programmer->chip_readl(flash, addr);
 }
 
-void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
+void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
+		size_t len)
 {
-	par_programmer->chip_readn(buf, addr, len);
+	par_programmer->chip_readn(flash, buf, addr, len);
 }
 
 void programmer_delay(int usecs)
@@ -412,9 +414,10 @@ void map_flash_registers(struct flashctx *flash)
 	flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
 }
 
-int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
+int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		   int unsigned len)
 {
-	chip_readn(buf, flash->virtual_memory + start, len);
+	chip_readn(flash, buf, flash->virtual_memory + start, len);
 
 	return 0;
 }
@@ -535,7 +538,8 @@ static unsigned int count_usable_erasers(const struct flashctx *flash)
 }
 
 /* start is an offset to the base address of the flash chip */
-int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
+int check_erased_range(struct flashctx *flash, unsigned int start,
+		       unsigned int len)
 {
 	int ret;
 	uint8_t *cmpbuf = malloc(len);
@@ -558,8 +562,8 @@ int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int
  * @message	string to print in the "FAILED" message
  * @return	0 for success, -1 for failure
  */
-int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start, unsigned int len,
-		 const char *message)
+int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start,
+		 unsigned int len, const char *message)
 {
 	unsigned int i;
 	uint8_t *readbuf = malloc(len);
@@ -1537,7 +1541,8 @@ int selfcheck(void)
 	/* Check that virtual_memory in struct flashctx is placed directly
 	 * after the members copied from struct flashchip.
 	 */
-	if (sizeof(struct flashchip) != offsetof(struct flashctx, virtual_memory)) {
+	if (sizeof(struct flashchip) !=
+	    offsetof(struct flashctx, virtual_memory)) {
 		msg_gerr("struct flashctx broken!\n");
 		ret = 1;
 	}
@@ -1618,7 +1623,8 @@ void check_chip_supported(const struct flashctx *flash)
 /* FIXME: This function signature needs to be improved once doit() has a better
  * function signature.
  */
-int chip_safety_check(struct flashctx *flash, int force, int read_it, int write_it, int erase_it, int verify_it)
+int chip_safety_check(struct flashctx *flash, int force, int read_it,
+		      int write_it, int erase_it, int verify_it)
 {
 	if (!programmer_may_write && (write_it || erase_it)) {
 		msg_perr("Write/erase is not working yet on your programmer in "
@@ -1679,7 +1685,8 @@ int chip_safety_check(struct flashctx *flash, int force, int read_it, int write_
  * but right now it allows us to split off the CLI code.
  * Besides that, the function itself is a textbook example of abysmal code flow.
  */
-int doit(struct flashctx *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it)
+int doit(struct flashctx *flash, int force, const char *filename, int read_it,
+	 int write_it, int erase_it, int verify_it)
 {
 	uint8_t *oldcontents;
 	uint8_t *newcontents;
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 8d89ea10d7e121ee320ac9b9d5a2699d45023a96..ce7d8998459ba29f350be4c4bab32917400074fb 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -144,8 +144,10 @@ static int get_buf(struct ftdi_context *ftdic, const unsigned char *buf,
 	return 0;
 }
 
-static int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr);
+static int ft2232_spi_send_command(struct flashctx *flash,
+				   unsigned int writecnt, unsigned int readcnt,
+				   const unsigned char *writearr,
+				   unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_ft2232 = {
 	.type		= SPI_CONTROLLER_FT2232,
@@ -342,8 +344,10 @@ ftdi_err:
 }
 
 /* Returns 0 upon success, a negative number upon errors. */
-static int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr)
+static int ft2232_spi_send_command(struct flashctx *flash,
+				   unsigned int writecnt, unsigned int readcnt,
+				   const unsigned char *writearr,
+				   unsigned char *readarr)
 {
 	struct ftdi_context *ftdic = &ftdic_context;
 	static unsigned char *buf = NULL;
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 2601e9a0c270a1e2aa444607bd089ee5df6e2bd9..b8750b306e11d758e75ec0b37278a302dceac097 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -61,6 +61,10 @@ const struct pcidev_status gfx_nvidia[] = {
 	{},
 };
 
+static void gfxnvidia_chip_writeb(const struct flashctx *flash, uint8_t val,
+				  chipaddr addr);
+static uint8_t gfxnvidia_chip_readb(const struct flashctx *flash,
+				    const chipaddr addr);
 static const struct par_programmer par_programmer_gfxnvidia = {
 		.chip_readb		= gfxnvidia_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -112,12 +116,14 @@ int gfxnvidia_init(void)
 	return 0;
 }
 
-void gfxnvidia_chip_writeb(uint8_t val, chipaddr addr)
+static void gfxnvidia_chip_writeb(const struct flashctx *flash, uint8_t val,
+				  chipaddr addr)
 {
 	pci_mmio_writeb(val, nvidia_bar + (addr & GFXNVIDIA_MEMMAP_MASK));
 }
 
-uint8_t gfxnvidia_chip_readb(const chipaddr addr)
+static uint8_t gfxnvidia_chip_readb(const struct flashctx *flash,
+				    const chipaddr addr)
 {
 	return pci_mmio_readb(nvidia_bar + (addr & GFXNVIDIA_MEMMAP_MASK));
 }
diff --git a/ichspi.c b/ichspi.c
index 1c66986728bac2607cd7e084aebd2026f3ccc32d..6bcea45eb9b57b913b0bd1a04882753aa733c327 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -228,7 +228,7 @@ static int find_opcode(OPCODES *op, uint8_t opcode);
 static int find_preop(OPCODES *op, uint8_t preop);
 static int generate_opcodes(OPCODES * op);
 static int program_opcodes(OPCODES *op, int enable_undo);
-static int run_opcode(OPCODE op, uint32_t offset,
+static int run_opcode(const struct flashctx *flash, OPCODE op, uint32_t offset,
 		      uint8_t datalength, uint8_t * data);
 
 /* for pairing opcodes with their required preop */
@@ -638,7 +638,7 @@ static void ich_set_bbar(uint32_t min_addr)
  * Note that using len > spi_programmer->max_data_read will return garbage or
  * may even crash.
  */
- static void ich_read_data(uint8_t *data, int len, int reg0_off)
+static void ich_read_data(uint8_t *data, int len, int reg0_off)
  {
 	int i;
 	uint32_t temp32 = 0;
@@ -956,7 +956,7 @@ static int ich9_run_opcode(OPCODE op, uint32_t offset,
 	return 0;
 }
 
-static int run_opcode(OPCODE op, uint32_t offset,
+static int run_opcode(const struct flashctx *flash, OPCODE op, uint32_t offset,
 		      uint8_t datalength, uint8_t * data)
 {
 	/* max_data_read == max_data_write for all Intel/VIA SPI masters */
@@ -983,8 +983,10 @@ static int run_opcode(OPCODE op, uint32_t offset,
 	}
 }
 
-static int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		    const unsigned char *writearr, unsigned char *readarr)
+static int ich_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				unsigned int readcnt,
+				const unsigned char *writearr,
+				unsigned char *readarr)
 {
 	int result;
 	int opcode_index = -1;
@@ -1076,7 +1078,7 @@ static int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		count = readcnt;
 	}
 
-	result = run_opcode(*opcode, addr, count, data);
+	result = run_opcode(flash, *opcode, addr, count, data);
 	if (result) {
 		msg_pdbg("Running OPCODE 0x%02x failed ", opcode->opcode);
 		if ((opcode->spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) ||
@@ -1175,7 +1177,7 @@ static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout,
 	return 0;
 }
 
-int ich_hwseq_probe(struct flashctx *flash)
+static int ich_hwseq_probe(struct flashctx *flash)
 {
 	uint32_t total_size, boundary;
 	uint32_t erase_size_low, size_low, erase_size_high, size_high;
@@ -1228,9 +1230,8 @@ int ich_hwseq_probe(struct flashctx *flash)
 	return 1;
 }
 
-int ich_hwseq_block_erase(struct flashctx *flash,
-			  unsigned int addr,
-			  unsigned int len)
+static int ich_hwseq_block_erase(struct flashctx *flash, unsigned int addr,
+				 unsigned int len)
 {
 	uint32_t erase_block;
 	uint16_t hsfc;
@@ -1278,8 +1279,8 @@ int ich_hwseq_block_erase(struct flashctx *flash,
 	return 0;
 }
 
-int ich_hwseq_read(struct flashctx *flash, uint8_t *buf, unsigned int addr,
-		   unsigned int len)
+static int ich_hwseq_read(struct flashctx *flash, uint8_t *buf,
+			  unsigned int addr, unsigned int len)
 {
 	uint16_t hsfc;
 	uint16_t timeout = 100 * 60;
@@ -1316,8 +1317,8 @@ int ich_hwseq_read(struct flashctx *flash, uint8_t *buf, unsigned int addr,
 	return 0;
 }
 
-int ich_hwseq_write(struct flashctx *flash, uint8_t *buf, unsigned int addr,
-		    unsigned int len)
+static int ich_hwseq_write(struct flashctx *flash, uint8_t *buf,
+			   unsigned int addr, unsigned int len)
 {
 	uint16_t hsfc;
 	uint16_t timeout = 100 * 60;
@@ -1355,7 +1356,8 @@ int ich_hwseq_write(struct flashctx *flash, uint8_t *buf, unsigned int addr,
 	return 0;
 }
 
-static int ich_spi_send_multicommand(struct spi_command *cmds)
+static int ich_spi_send_multicommand(struct flashctx *flash,
+				     struct spi_command *cmds)
 {
 	int ret = 0;
 	int i;
@@ -1405,7 +1407,7 @@ static int ich_spi_send_multicommand(struct spi_command *cmds)
 			 * 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++)
diff --git a/internal.c b/internal.c
index 215ce6f36458934bd43c688abb2a5eaa1226f0e3..386b842847beb583908c9f77a45e32c786315151 100644
--- a/internal.c
+++ b/internal.c
@@ -127,6 +127,20 @@ int register_superio(struct superio s)
 int is_laptop = 0;
 int laptop_ok = 0;
 
+static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr);
+static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
+				 chipaddr addr);
+static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
+				 chipaddr addr);
+static uint8_t internal_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr);
+static uint16_t internal_chip_readw(const struct flashctx *flash,
+				    const chipaddr addr);
+static uint32_t internal_chip_readl(const struct flashctx *flash,
+				    const chipaddr addr);
+static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
+				const chipaddr addr, size_t len);
 static const struct par_programmer par_programmer_internal = {
 		.chip_readb		= internal_chip_readb,
 		.chip_readw		= internal_chip_readw,
@@ -324,37 +338,44 @@ int internal_init(void)
 }
 #endif
 
-void internal_chip_writeb(uint8_t val, chipaddr addr)
+static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr)
 {
 	mmio_writeb(val, (void *) addr);
 }
 
-void internal_chip_writew(uint16_t val, chipaddr addr)
+static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
+				 chipaddr addr)
 {
 	mmio_writew(val, (void *) addr);
 }
 
-void internal_chip_writel(uint32_t val, chipaddr addr)
+static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
+				 chipaddr addr)
 {
 	mmio_writel(val, (void *) addr);
 }
 
-uint8_t internal_chip_readb(const chipaddr addr)
+static uint8_t internal_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr)
 {
 	return mmio_readb((void *) addr);
 }
 
-uint16_t internal_chip_readw(const chipaddr addr)
+static uint16_t internal_chip_readw(const struct flashctx *flash,
+				    const chipaddr addr)
 {
 	return mmio_readw((void *) addr);
 }
 
-uint32_t internal_chip_readl(const chipaddr addr)
+static uint32_t internal_chip_readl(const struct flashctx *flash,
+				    const chipaddr addr)
 {
 	return mmio_readl((void *) addr);
 }
 
-void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len)
+static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
+				const chipaddr addr, size_t len)
 {
 	memcpy(buf, (void *)addr, len);
 	return;
diff --git a/it85spi.c b/it85spi.c
index d25f5ac60562302179121fbe0e9c3022d285e3d5..01cb08651057cb9c23f6c544bd1e59e9c8efb35e 100644
--- a/it85spi.c
+++ b/it85spi.c
@@ -270,8 +270,10 @@ static int it85xx_spi_common_init(struct superio s)
 	return 0;
 }
 
-static int it85xx_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			const unsigned char *writearr, unsigned char *readarr);
+static int it85xx_spi_send_command(struct flashctx *flash,
+				   unsigned int writecnt, unsigned int readcnt,
+				   const unsigned char *writearr,
+				   unsigned char *readarr);
 
 static const struct spi_programmer spi_programmer_it85xx = {
 	.type		= SPI_CONTROLLER_IT85XX,
@@ -320,8 +322,10 @@ int it85xx_spi_init(struct superio s)
  *   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,
-			const unsigned char *writearr, unsigned char *readarr)
+static int it85xx_spi_send_command(struct flashctx *flash,
+				   unsigned int writecnt, unsigned int readcnt,
+				   const unsigned char *writearr,
+				   unsigned char *readarr)
 {
 	int i;
 
diff --git a/it87spi.c b/it87spi.c
index 5a7e6ecaca030cf883389b1b75ab8fb9440e5464..f089d78d337f222b4798a369ed11f521a032e543 100644
--- a/it87spi.c
+++ b/it87spi.c
@@ -103,8 +103,10 @@ void probe_superio_ite(void)
 	return;
 }
 
-static int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			const unsigned char *writearr, unsigned char *readarr);
+static int it8716f_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr);
 static int it8716f_spi_chip_read(struct flashctx *flash, uint8_t *buf,
 				 unsigned int start, unsigned int len);
 static int it8716f_spi_chip_write_256(struct flashctx *flash, uint8_t *buf,
@@ -247,8 +249,10 @@ int init_superio_ite(void)
  * 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,
-			const unsigned char *writearr, unsigned char *readarr)
+static int it8716f_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr)
 {
 	uint8_t busy, writeenc;
 	int i;
@@ -319,19 +323,19 @@ static int it8716f_spi_page_program(struct flashctx *flash, uint8_t *buf,
 	int 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;
 }
diff --git a/jedec.c b/jedec.c
index 97621d9a9cfc1affc489862b939ff255b50d0e5e..69c0c0c23aab1b972baae707dcbe514b38c302dd 100644
--- a/jedec.c
+++ b/jedec.c
@@ -37,17 +37,18 @@ uint8_t oddparity(uint8_t val)
 	return (val ^ (val >> 1)) & 0x1;
 }
 
-static void toggle_ready_jedec_common(chipaddr dst, int delay)
+static void toggle_ready_jedec_common(const struct flashctx *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 +58,9 @@ static void toggle_ready_jedec_common(chipaddr dst, int delay)
 		msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
 }
 
-void toggle_ready_jedec(chipaddr dst)
+void toggle_ready_jedec(const struct flashctx *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 +70,13 @@ void toggle_ready_jedec(chipaddr dst)
  * 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 flashctx *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 flashctx *flash, chipaddr dst,
+			uint8_t data)
 {
 	unsigned int i = 0;
 	uint8_t tmp;
@@ -82,7 +84,7 @@ void data_polling_jedec(chipaddr dst, uint8_t data)
 	data &= 0x80;
 
 	while (i++ < 0xFFFFFFF) {
-		tmp = chip_readb(dst) & 0x80;
+		tmp = chip_readb(flash, dst) & 0x80;
 		if (tmp == data) {
 			break;
 		}
@@ -110,12 +112,13 @@ static unsigned int getaddrmask(struct flashctx *flash)
 	}
 }
 
-static void start_program_jedec_common(struct flashctx *flash, unsigned int mask)
+static void start_program_jedec_common(struct flashctx *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 flashctx *flash, unsigned int mask)
@@ -150,57 +153,57 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
 	/* 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 +212,17 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
 		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)
@@ -238,7 +241,7 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
 }
 
 static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page,
-			      unsigned int pagesize, unsigned int mask)
+				     unsigned int pagesize, unsigned int mask)
 {
 	chipaddr bios = flash->virtual_memory;
 	int delay_us = 0;
@@ -246,29 +249,29 @@ static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page,
 	        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;
 }
 
 static int erase_block_jedec_common(struct flashctx *flash, unsigned int block,
-			     unsigned int blocksize, unsigned int mask)
+				    unsigned int blocksize, unsigned int mask)
 {
 	chipaddr bios = flash->virtual_memory;
 	int delay_us = 0;
@@ -276,22 +279,22 @@ static int erase_block_jedec_common(struct flashctx *flash, unsigned int block,
 	        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,28 +308,28 @@ static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask)
 	        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;
 }
 
 static int write_byte_program_jedec_common(struct flashctx *flash, uint8_t *src,
-			     chipaddr dst, unsigned int mask)
+					   chipaddr dst, unsigned int mask)
 {
 	int tried = 0, failed = 0;
 	chipaddr bios = flash->virtual_memory;
@@ -341,10 +344,10 @@ retry:
 	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;
 	}
 
@@ -355,7 +358,8 @@ retry:
 }
 
 /* chunksize is 1 */
-int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
+int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start,
+		  unsigned int len)
 {
 	int i, failed = 0;
 	chipaddr dst = flash->virtual_memory + start;
@@ -376,7 +380,8 @@ int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start, unsi
 	return failed;
 }
 
-int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int page_size)
+int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src,
+				  unsigned int start, unsigned int page_size)
 {
 	int i, tried = 0, failed;
 	uint8_t *s = src;
@@ -395,12 +400,12 @@ retry:
 	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;
@@ -424,7 +429,8 @@ retry:
  * This function is a slightly modified copy of spi_write_chunked.
  * Each page is written separately in chunks with a maximum size of chunksize.
  */
-int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
+int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		int unsigned len)
 {
 	unsigned int i, starthere, lenhere;
 	/* FIXME: page_size is the wrong variable. We need max_writechunk_size
@@ -480,7 +486,8 @@ int probe_jedec(struct flashctx *flash)
 	return probe_jedec_common(flash, mask);
 }
 
-int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int size)
+int erase_sector_jedec(struct flashctx *flash, unsigned int page,
+		       unsigned int size)
 {
 	unsigned int mask;
 
@@ -488,7 +495,8 @@ int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int s
 	return erase_sector_jedec_common(flash, page, size, mask);
 }
 
-int erase_block_jedec(struct flashctx *flash, unsigned int page, unsigned int size)
+int erase_block_jedec(struct flashctx *flash, unsigned int page,
+		      unsigned int size)
 {
 	unsigned int mask;
 
diff --git a/linux_spi.c b/linux_spi.c
index 372082300bfe2bf4f473ca0941d6d0edf943d147..d99438988269687b66779fc0e49554eff36ce296 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -34,8 +34,10 @@
 static int fd = -1;
 
 static int linux_spi_shutdown(void *data);
-static int linux_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			const unsigned char *txbuf, unsigned char *rxbuf);
+static int linux_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *txbuf,
+				  unsigned char *rxbuf);
 static int linux_spi_read(struct flashctx *flash, uint8_t *buf,
 			  unsigned int start, unsigned int len);
 static int linux_spi_write_256(struct flashctx *flash, uint8_t *buf,
@@ -107,8 +109,10 @@ static int linux_spi_shutdown(void *data)
 	return 0;
 }
 
-static int linux_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			const unsigned char *txbuf, unsigned char *rxbuf)
+static int linux_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *txbuf,
+				  unsigned char *rxbuf)
 {
 	struct spi_ioc_transfer msg[2] = {
 		{
@@ -134,11 +138,13 @@ static int linux_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 static int linux_spi_read(struct flashctx *flash, uint8_t *buf,
 			  unsigned int start, unsigned int len)
 {
-	return spi_read_chunked(flash, buf, start, len, (unsigned)getpagesize());
+	return spi_read_chunked(flash, buf, start, len,
+				(unsigned int)getpagesize());
 }
 
 static int linux_spi_write_256(struct flashctx *flash, uint8_t *buf,
 			       unsigned int start, unsigned int len)
 {
-	return spi_write_chunked(flash, buf, start, len, ((unsigned)getpagesize()) - 4);
+	return spi_write_chunked(flash, buf, start, len,
+				((unsigned int)getpagesize()) - 4);
 }
diff --git a/m29f400bt.c b/m29f400bt.c
index f664b476c944b1e55568a78d82568e1cd9c24ca4..c9d8a40ebd13fa96e662434800cf655ea07851d2 100644
--- a/m29f400bt.c
+++ b/m29f400bt.c
@@ -28,24 +28,25 @@
    functions. */
 
 /* chunksize is 1 */
-int write_m29f400bt(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
+int write_m29f400bt(struct flashctx *flash, uint8_t *src, unsigned int start,
+		    unsigned int len)
 {
 	int i;
 	chipaddr bios = flash->virtual_memory;
 	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 +61,21 @@ int probe_m29f400bt(struct flashctx *flash)
 	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,42 +91,44 @@ int erase_m29f400bt(struct flashctx *flash)
 {
 	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;
 }
 
-int block_erase_m29f400bt(struct flashctx *flash, unsigned int start, unsigned int len)
+int block_erase_m29f400bt(struct flashctx *flash, unsigned int start,
+			  unsigned int len)
 {
 	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;
 }
 
-int block_erase_chip_m29f400bt(struct flashctx *flash, unsigned int address, unsigned int blocklen)
+int block_erase_chip_m29f400bt(struct flashctx *flash, unsigned int address,
+			       unsigned int blocklen)
 {
 	if ((address != 0) || (blocklen != flash->total_size * 1024)) {
 		msg_cerr("%s called with incorrect arguments\n",
diff --git a/nic3com.c b/nic3com.c
index 0c279579102397848e79c1d6d9573e9cd7785c11..473c7b11215d373336ff6981502d1c8c9c0cf234 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -55,6 +55,10 @@ const struct pcidev_status nics_3com[] = {
 	{},
 };
 
+static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr);
+static uint8_t nic3com_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr);
 static const struct par_programmer par_programmer_nic3com = {
 		.chip_readb		= nic3com_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -116,13 +120,15 @@ int nic3com_init(void)
 	return 0;
 }
 
-void nic3com_chip_writeb(uint8_t val, chipaddr addr)
+static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
 	OUTB(val, io_base_addr + BIOS_ROM_DATA);
 }
 
-uint8_t nic3com_chip_readb(const chipaddr addr)
+static uint8_t nic3com_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
 	return INB(io_base_addr + BIOS_ROM_DATA);
diff --git a/nicintel.c b/nicintel.c
index b20f85637c26edd6cf95f8f9f0b2eb62848d349e..0415f46b80d870c5161feb5b80a695f40ad2debf 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -43,6 +43,10 @@ const struct pcidev_status nics_intel[] = {
 
 #define CSR_FCR 0x0c
 
+static void nicintel_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr);
+static uint8_t nicintel_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr);
 static const struct par_programmer par_programmer_nicintel = {
 		.chip_readb		= nicintel_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -117,12 +121,14 @@ error_out:
 	return 1;
 }
 
-void nicintel_chip_writeb(uint8_t val, chipaddr addr)
+static void nicintel_chip_writeb(const struct flashctx *flash, uint8_t val,
+				 chipaddr addr)
 {
 	pci_mmio_writeb(val, nicintel_bar + (addr & NICINTEL_MEMMAP_MASK));
 }
 
-uint8_t nicintel_chip_readb(const chipaddr addr)
+static uint8_t nicintel_chip_readb(const struct flashctx *flash,
+				   const chipaddr addr)
 {
 	return pci_mmio_readb(nicintel_bar + (addr & NICINTEL_MEMMAP_MASK));
 }
diff --git a/nicnatsemi.c b/nicnatsemi.c
index f9825fdf2f9538e2bf072c75d70bf67322242fe3..eb2a7f882a99555ed85cd3d39d3faf591c61217b 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -35,6 +35,10 @@ const struct pcidev_status nics_natsemi[] = {
 	{},
 };
 
+static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
+				   chipaddr addr);
+static uint8_t nicnatsemi_chip_readb(const struct flashctx *flash,
+				     const chipaddr addr);
 static const struct par_programmer par_programmer_nicnatsemi = {
 		.chip_readb		= nicnatsemi_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -74,7 +78,8 @@ int nicnatsemi_init(void)
 	return 0;
 }
 
-void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr)
+static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
+				   chipaddr addr)
 {
 	OUTL((uint32_t)addr & 0x0001FFFF, io_base_addr + BOOT_ROM_ADDR);
 	/*
@@ -88,7 +93,8 @@ void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr)
 	OUTB(val, io_base_addr + BOOT_ROM_DATA);
 }
 
-uint8_t nicnatsemi_chip_readb(const chipaddr addr)
+static uint8_t nicnatsemi_chip_readb(const struct flashctx *flash,
+				     const chipaddr addr)
 {
 	OUTL(((uint32_t)addr & 0x0001FFFF), io_base_addr + BOOT_ROM_ADDR);
 	/*
diff --git a/nicrealtek.c b/nicrealtek.c
index 9f9265fa8f7e20f55534fbee6a7204527e5830cf..32aa43498f9dfdaa39e3c4988eca987989e3190d 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -36,6 +36,10 @@ const struct pcidev_status nics_realtek[] = {
 	{},
 };
 
+static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val,
+				   chipaddr addr);
+static uint8_t nicrealtek_chip_readb(const struct flashctx *flash,
+				     const chipaddr addr);
 static const struct par_programmer par_programmer_nicrealtek = {
 		.chip_readb		= nicrealtek_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -69,7 +73,8 @@ int nicrealtek_init(void)
 	return 0;
 }
 
-void nicrealtek_chip_writeb(uint8_t val, chipaddr addr)
+static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val,
+				   chipaddr addr)
 {
 	/* Output addr and data, set WE to 0, set OE to 1, set CS to 0,
 	 * enable software access.
@@ -83,7 +88,8 @@ void nicrealtek_chip_writeb(uint8_t val, chipaddr addr)
 	     io_base_addr + BIOS_ROM_ADDR);
 }
 
-uint8_t nicrealtek_chip_readb(const chipaddr addr)
+static uint8_t nicrealtek_chip_readb(const struct flashctx *flash,
+				     const chipaddr addr)
 {
 	uint8_t val;
 
diff --git a/pm49fl00x.c b/pm49fl00x.c
index 3f74758973fa143f02a9b769378e8d08bd09e148..42db2aa9639eae6009c6cda5ee35550740062e86 100644
--- a/pm49fl00x.c
+++ b/pm49fl00x.c
@@ -22,28 +22,32 @@
 
 #include "flash.h"
 
-static void write_lockbits_49fl00x(chipaddr bios, unsigned int size,
-			    unsigned char bits, unsigned int block_size)
+static void write_lockbits_49fl00x(const struct flashctx *flash,
+				   unsigned int size, unsigned char bits,
+				   unsigned int block_size)
 {
 	unsigned int i, left = size;
+	chipaddr bios = flash->virtual_registers;
 
 	for (i = 0; left >= block_size; i++, left -= block_size) {
 		/* pm49fl002 */
 		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 flashctx *flash)
 {
-	write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size);
+	write_lockbits_49fl00x(flash, flash->total_size * 1024, 0,
+			       flash->page_size);
 	return 0;
 }
 
 int lock_49fl00x(struct flashctx *flash)
 {
-	write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 1, flash->page_size);
+	write_lockbits_49fl00x(flash, flash->total_size * 1024, 1,
+			       flash->page_size);
 	return 0;
 }
diff --git a/programmer.c b/programmer.c
index 5eabdaf9975e37aa95f1ab59dc01cde10abbbb18..2928d68b35a649dfffa66fccb4cc54dccbb87317 100644
--- a/programmer.c
+++ b/programmer.c
@@ -1,7 +1,7 @@
 /*
  * This file is part of the flashrom project.
  *
- * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2009,2010,2011 Carl-Daniel Hailfinger
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,61 +53,65 @@ void fallback_unmap(void *virt_addr, size_t len)
 }
 
 /* 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(const struct flashctx *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(const struct flashctx *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 flashctx *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(const struct flashctx *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 flashctx *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(const struct flashctx *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 flashctx *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(const struct flashctx *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;
 }
 
diff --git a/programmer.h b/programmer.h
index c80b851063c4f9616fa7c5fcf22e39ab4fb3190d..9942686b30bca31bebce578e8567ab41ab40968d 100644
--- a/programmer.h
+++ b/programmer.h
@@ -93,8 +93,8 @@ struct programmer_entry {
 
 	int (*init) (void);
 
-	void * (*map_flash_region) (const char *descr, unsigned long phys_addr,
-				    size_t len);
+	void *(*map_flash_region) (const char *descr, unsigned long phys_addr,
+				   size_t len);
 	void (*unmap_flash_region) (void *virt_addr, size_t len);
 
 	void (*delay) (int usecs);
@@ -300,13 +300,6 @@ 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);
-void internal_chip_writel(uint32_t val, chipaddr addr);
-uint8_t internal_chip_readb(const chipaddr addr);
-uint16_t internal_chip_readw(const chipaddr addr);
-uint32_t internal_chip_readl(const chipaddr addr);
-void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
 #endif
 
 /* hwaccess.c */
@@ -341,91 +334,46 @@ void rmmio_valb(void *addr);
 void rmmio_valw(void *addr);
 void rmmio_vall(void *addr);
 
-/* programmer.c */
-int noop_shutdown(void);
-void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
-void fallback_unmap(void *virt_addr, size_t len);
-uint8_t noop_chip_readb(const chipaddr addr);
-void noop_chip_writeb(uint8_t val, chipaddr addr);
-void fallback_chip_writew(uint16_t val, chipaddr addr);
-void fallback_chip_writel(uint32_t val, chipaddr addr);
-void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
-uint16_t fallback_chip_readw(const chipaddr addr);
-uint32_t fallback_chip_readl(const chipaddr addr);
-void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
-struct par_programmer {
-	void (*chip_writeb) (uint8_t val, chipaddr addr);
-	void (*chip_writew) (uint16_t val, chipaddr addr);
-	void (*chip_writel) (uint32_t val, chipaddr addr);
-	void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len);
-	uint8_t (*chip_readb) (const chipaddr addr);
-	uint16_t (*chip_readw) (const chipaddr addr);
-	uint32_t (*chip_readl) (const chipaddr addr);
-	void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
-};
-extern const struct par_programmer *par_programmer;
-void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses);
-
 /* dummyflasher.c */
 #if CONFIG_DUMMY == 1
 int dummy_init(void);
 void *dummy_map(const char *descr, unsigned long phys_addr, size_t len);
 void dummy_unmap(void *virt_addr, size_t len);
-void dummy_chip_writeb(uint8_t val, chipaddr addr);
-void dummy_chip_writew(uint16_t val, chipaddr addr);
-void dummy_chip_writel(uint32_t val, chipaddr addr);
-void dummy_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
-uint8_t dummy_chip_readb(const chipaddr addr);
-uint16_t dummy_chip_readw(const chipaddr addr);
-uint32_t dummy_chip_readl(const chipaddr addr);
-void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
 #endif
 
 /* nic3com.c */
 #if CONFIG_NIC3COM == 1
 int nic3com_init(void);
-void nic3com_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t nic3com_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_3com[];
 #endif
 
 /* gfxnvidia.c */
 #if CONFIG_GFXNVIDIA == 1
 int gfxnvidia_init(void);
-void gfxnvidia_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t gfxnvidia_chip_readb(const chipaddr addr);
 extern const struct pcidev_status gfx_nvidia[];
 #endif
 
 /* drkaiser.c */
 #if CONFIG_DRKAISER == 1
 int drkaiser_init(void);
-void drkaiser_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t drkaiser_chip_readb(const chipaddr addr);
 extern const struct pcidev_status drkaiser_pcidev[];
 #endif
 
 /* nicrealtek.c */
 #if CONFIG_NICREALTEK == 1
 int nicrealtek_init(void);
-void nicrealtek_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t nicrealtek_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_realtek[];
 #endif
 
 /* nicnatsemi.c */
 #if CONFIG_NICNATSEMI == 1
 int nicnatsemi_init(void);
-void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t nicnatsemi_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_natsemi[];
 #endif
 
 /* nicintel.c */
 #if CONFIG_NICINTEL == 1
 int nicintel_init(void);
-void nicintel_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t nicintel_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_intel[];
 #endif
 
@@ -444,24 +392,18 @@ extern const struct pcidev_status ogp_spi[];
 /* satamv.c */
 #if CONFIG_SATAMV == 1
 int satamv_init(void);
-void satamv_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t satamv_chip_readb(const chipaddr addr);
 extern const struct pcidev_status satas_mv[];
 #endif
 
 /* satasii.c */
 #if CONFIG_SATASII == 1
 int satasii_init(void);
-void satasii_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t satasii_chip_readb(const chipaddr addr);
 extern const struct pcidev_status satas_sii[];
 #endif
 
 /* atahpt.c */
 #if CONFIG_ATAHPT == 1
 int atahpt_init(void);
-void atahpt_chip_writeb(uint8_t val, chipaddr addr);
-uint8_t atahpt_chip_readb(const chipaddr addr);
 extern const struct pcidev_status ata_hpt[];
 #endif
 
@@ -565,9 +507,9 @@ struct spi_programmer {
 	enum spi_controller type;
 	unsigned int max_data_read;
 	unsigned int max_data_write;
-	int (*command)(unsigned int writecnt, unsigned int readcnt,
+	int (*command)(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
 		   const unsigned char *writearr, unsigned char *readarr);
-	int (*multicommand)(struct spi_command *cmds);
+	int (*multicommand)(struct flashctx *flash, struct spi_command *cmds);
 
 	/* Optimized functions for this programmer */
 	int (*read)(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
@@ -575,9 +517,9 @@ struct spi_programmer {
 };
 
 extern const struct spi_programmer *spi_programmer;
-int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+int default_spi_send_command(struct flashctx *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 flashctx *flash, struct spi_command *cmds);
 int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 int default_spi_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 void register_spi_programmer(const struct spi_programmer *programmer);
@@ -632,12 +574,34 @@ struct opaque_programmer {
 extern const struct opaque_programmer *opaque_programmer;
 void register_opaque_programmer(const struct opaque_programmer *pgm);
 
+/* programmer.c */
+int noop_shutdown(void);
+void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
+void fallback_unmap(void *virt_addr, size_t len);
+uint8_t noop_chip_readb(const struct flashctx *flash, const chipaddr addr);
+void noop_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr);
+void fallback_chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr);
+void fallback_chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr);
+void fallback_chip_writen(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len);
+uint16_t fallback_chip_readw(const struct flashctx *flash, const chipaddr addr);
+uint32_t fallback_chip_readl(const struct flashctx *flash, const chipaddr addr);
+void fallback_chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len);
+struct par_programmer {
+	void (*chip_writeb) (const struct flashctx *flash, uint8_t val, chipaddr addr);
+	void (*chip_writew) (const struct flashctx *flash, uint16_t val, chipaddr addr);
+	void (*chip_writel) (const struct flashctx *flash, uint32_t val, chipaddr addr);
+	void (*chip_writen) (const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len);
+	uint8_t (*chip_readb) (const struct flashctx *flash, const chipaddr addr);
+	uint16_t (*chip_readw) (const struct flashctx *flash, const chipaddr addr);
+	uint32_t (*chip_readl) (const struct flashctx *flash, const chipaddr addr);
+	void (*chip_readn) (const struct flashctx *flash, 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);
+
 /* serprog.c */
 #if CONFIG_SERPROG == 1
 int serprog_init(void);
-void serprog_chip_writeb(uint8_t val, chipaddr addr);
-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);
 #endif
 
diff --git a/satamv.c b/satamv.c
index b5d964e99429ec3503162b28c1eef08d53220c28..e39385b24c2032ff3af95377bb26adfbc82b34eb 100644
--- a/satamv.c
+++ b/satamv.c
@@ -41,6 +41,10 @@ const struct pcidev_status satas_mv[] = {
 #define PCI_BAR2_CONTROL		0x00c08
 #define GPIO_PORT_CONTROL		0x104f0
 
+static void satamv_chip_writeb(const struct flashctx *flash, uint8_t val,
+			       chipaddr addr);
+static uint8_t satamv_chip_readb(const struct flashctx *flash,
+				 const chipaddr addr);
 static const struct par_programmer par_programmer_satamv = {
 		.chip_readb		= satamv_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -183,13 +187,15 @@ static uint8_t satamv_indirect_chip_readb(const chipaddr addr)
 }
 
 /* FIXME: Prefer direct access to BAR2 if BAR2 is active. */
-void satamv_chip_writeb(uint8_t val, chipaddr addr)
+static void satamv_chip_writeb(const struct flashctx *flash, uint8_t val,
+			       chipaddr addr)
 {
 	satamv_indirect_chip_writeb(val, addr);
 }
 
 /* FIXME: Prefer direct access to BAR2 if BAR2 is active. */
-uint8_t satamv_chip_readb(const chipaddr addr)
+static uint8_t satamv_chip_readb(const struct flashctx *flash,
+				 const chipaddr addr)
 {
 	return satamv_indirect_chip_readb(addr);
 }
diff --git a/satasii.c b/satasii.c
index e51e3aec008534a74d01b27d06c07777be53dab8..387c605d587849c4fd5c8dce41118f3b5fbc5ae0 100644
--- a/satasii.c
+++ b/satasii.c
@@ -42,6 +42,10 @@ const struct pcidev_status satas_sii[] = {
 	{},
 };
 
+static void satasii_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr);
+static uint8_t satasii_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr);
 static const struct par_programmer par_programmer_satasii = {
 		.chip_readb		= satasii_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -95,7 +99,8 @@ int satasii_init(void)
 	return 0;
 }
 
-void satasii_chip_writeb(uint8_t val, chipaddr addr)
+static void satasii_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr)
 {
 	uint32_t ctrl_reg, data_reg;
 
@@ -112,7 +117,8 @@ void satasii_chip_writeb(uint8_t val, chipaddr addr)
 	while (pci_mmio_readl(sii_bar) & (1 << 25)) ;
 }
 
-uint8_t satasii_chip_readb(const chipaddr addr)
+static uint8_t satasii_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr)
 {
 	uint32_t ctrl_reg;
 
diff --git a/sb600spi.c b/sb600spi.c
index 9d82b47d30684bb158ef88fcb7f8227999fbe697..c3d77106e59ec65ecff0f5c2c8baa3dbf6b98b33 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -88,8 +88,10 @@ static void execute_command(void)
 		;
 }
 
-static int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		      const unsigned char *writearr, unsigned char *readarr)
+static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *writearr,
+				  unsigned char *readarr)
 {
 	int count;
 	/* First byte is cmd which can not being sent through FIFO. */
diff --git a/serprog.c b/serprog.c
index 539e4887e51daf1e83edf48b1ebde310aab3fdec..65539a1a5e8c7f5c1f460fd4256198dab62c8d96 100644
--- a/serprog.c
+++ b/serprog.c
@@ -299,7 +299,8 @@ static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
 	return 0;
 }
 
-static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+static int serprog_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
 				    const unsigned char *writearr,
 				    unsigned char *readarr);
 static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
@@ -314,6 +315,12 @@ static struct spi_programmer spi_programmer_serprog = {
 	.write_256	= default_spi_write_256,
 };
 
+static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr);
+static uint8_t serprog_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr);
+static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
+			       const chipaddr addr, size_t len);
 static const struct par_programmer par_programmer_serprog = {
 		.chip_readb		= serprog_chip_readb,
 		.chip_readw		= fallback_chip_readw,
@@ -680,7 +687,8 @@ static void sp_check_opbuf_usage(int bytes_to_be_added)
 	}
 }
 
-void serprog_chip_writeb(uint8_t val, chipaddr addr)
+static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
+				chipaddr addr)
 {
 	msg_pspew("%s\n", __func__);
 	if (sp_max_write_n) {
@@ -711,7 +719,8 @@ void serprog_chip_writeb(uint8_t val, chipaddr addr)
 	}
 }
 
-uint8_t serprog_chip_readb(const chipaddr addr)
+static uint8_t serprog_chip_readb(const struct flashctx *flash,
+				  const chipaddr addr)
 {
 	unsigned char c;
 	unsigned char buf[3];
@@ -757,7 +766,8 @@ static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
 }
 
 /* The externally called version that makes sure that max_read_n is obeyed. */
-void serprog_chip_readn(uint8_t * buf, const chipaddr addr, size_t len)
+static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
+			       const chipaddr addr, size_t len)
 {
 	size_t lenm = len;
 	chipaddr addrm = addr;
@@ -792,9 +802,10 @@ void serprog_delay(int usecs)
 	sp_prev_was_write = 0;
 }
 
-static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			     const unsigned char *writearr,
-			     unsigned char *readarr)
+static int serprog_spi_send_command(struct flashctx *flash,
+				    unsigned int writecnt, unsigned int readcnt,
+				    const unsigned char *writearr,
+				    unsigned char *readarr)
 {
 	unsigned char *parmbuf;
 	int ret;
@@ -822,14 +833,15 @@ static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
  * 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. */
-static int serprog_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
+			    unsigned int start, unsigned int len)
 {
 	unsigned int i, cur_len;
 	const unsigned int max_read = spi_programmer_serprog.max_data_read;
 	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;
 	}
diff --git a/sharplhf00l04.c b/sharplhf00l04.c
index d572e962d01774215ac29277df9593347372fd38..5767b4aaa5b8155547f075db7d50bd9679f246dd 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -26,25 +26,26 @@
  * FIXME: This file is unused.
  */
 
-int erase_lhf00l04_block(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen)
+int erase_lhf00l04_block(struct flashctx *flash, unsigned int blockaddr,
+			 unsigned int blocklen)
 {
 	chipaddr bios = flash->virtual_memory + blockaddr;
 	chipaddr wrprotect = flash->virtual_registers + blockaddr + 2;
 	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);
diff --git a/spi.c b/spi.c
index 2eeb1af3dafe711ee0182ba5a1d98ccf52f4906a..02c83f7bfafca72c404bce95fc1ba87edbcd2f2f 100644
--- a/spi.c
+++ b/spi.c
@@ -42,8 +42,9 @@ const struct spi_programmer spi_programmer_none = {
 
 const struct spi_programmer *spi_programmer = &spi_programmer_none;
 
-int spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		const unsigned char *writearr, unsigned char *readarr)
+int spi_send_command(struct flashctx *flash, unsigned int writecnt,
+		     unsigned int readcnt, const unsigned char *writearr,
+		     unsigned char *readarr)
 {
 	if (!spi_programmer->command) {
 		msg_perr("%s called, but SPI is unsupported on this "
@@ -52,11 +53,11 @@ int spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		return 1;
 	}
 
-	return spi_programmer->command(writecnt, readcnt,
-						      writearr, readarr);
+	return spi_programmer->command(flash, writecnt, readcnt, writearr,
+				       readarr);
 }
 
-int spi_send_multicommand(struct spi_command *cmds)
+int spi_send_multicommand(struct flashctx *flash, struct spi_command *cmds)
 {
 	if (!spi_programmer->multicommand) {
 		msg_perr("%s called, but SPI is unsupported on this "
@@ -65,11 +66,13 @@ int spi_send_multicommand(struct spi_command *cmds)
 		return 1;
 	}
 
-	return spi_programmer->multicommand(cmds);
+	return spi_programmer->multicommand(flash, cmds);
 }
 
-int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-			     const unsigned char *writearr, unsigned char *readarr)
+int default_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+			     unsigned int readcnt,
+			     const unsigned char *writearr,
+			     unsigned char *readarr)
 {
 	struct spi_command cmd[] = {
 	{
@@ -84,20 +87,22 @@ int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		.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 flashctx *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;
 }
 
-int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		     unsigned int len)
 {
 	unsigned int max_data = spi_programmer->max_data_read;
 	if (max_data == MAX_DATA_UNSPECIFIED) {
@@ -109,7 +114,8 @@ int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, u
 	return spi_read_chunked(flash, buf, start, len, max_data);
 }
 
-int default_spi_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int default_spi_write_256(struct flashctx *flash, uint8_t *buf,
+			  unsigned int start, unsigned int len)
 {
 	unsigned int max_data = spi_programmer->max_data_write;
 	if (max_data == MAX_DATA_UNSPECIFIED) {
@@ -121,7 +127,8 @@ int default_spi_write_256(struct flashctx *flash, uint8_t *buf, unsigned int sta
 	return spi_write_chunked(flash, buf, start, len, max_data);
 }
 
-int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		  unsigned int len)
 {
 	unsigned int addrbase = 0;
 	if (!spi_programmer->read) {
@@ -135,7 +142,7 @@ int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsi
 	 * 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");
@@ -160,7 +167,8 @@ int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsi
  * .write_256 = spi_chip_write_1
  */
 /* real chunksize is up to 256, logical chunksize is 256 */
-int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		       unsigned int len)
 {
 	if (!spi_programmer->write_256) {
 		msg_perr("%s called, but SPI page write is unsupported on this "
@@ -177,7 +185,7 @@ int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start,
  * 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 flashctx *flash)
 {
 	switch (spi_programmer->type) {
 #if CONFIG_INTERNAL == 1
diff --git a/spi25.c b/spi25.c
index abcf6d071a82de6fd362d60a8b71a2b8f7214a00..1e3bed953b96e913d68b645cfed6f0f487fac87c 100644
--- a/spi25.c
+++ b/spi25.c
@@ -29,13 +29,13 @@
 #include "programmer.h"
 #include "spi.h"
 
-static int spi_rdid(unsigned char *readarr, int bytes)
+static int spi_rdid(struct flashctx *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,22 @@ static int spi_rdid(unsigned char *readarr, int bytes)
 	return 0;
 }
 
-static int spi_rems(unsigned char *readarr)
+static int spi_rems(struct flashctx *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 +68,21 @@ static int spi_rems(unsigned char *readarr)
 	return 0;
 }
 
-static int spi_res(unsigned char *readarr, int bytes)
+static int spi_res(struct flashctx *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 +93,13 @@ static int spi_res(unsigned char *readarr, int bytes)
 	return 0;
 }
 
-int spi_write_enable(void)
+int spi_write_enable(struct flashctx *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 +107,12 @@ int spi_write_enable(void)
 	return result;
 }
 
-int spi_write_disable(void)
+int spi_write_disable(struct flashctx *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 flashctx *flash, int bytes)
@@ -119,7 +121,7 @@ static int probe_spi_rdid_generic(struct flashctx *flash, int bytes)
 	uint32_t id1;
 	uint32_t id2;
 
-	if (spi_rdid(readarr, bytes)) {
+	if (spi_rdid(flash, readarr, bytes)) {
 		return 0;
 	}
 
@@ -199,7 +201,7 @@ int probe_spi_rems(struct flashctx *flash)
 	unsigned char readarr[JEDEC_REMS_INSIZE];
 	uint32_t id1, id2;
 
-	if (spi_rems(readarr)) {
+	if (spi_rems(flash, readarr)) {
 		return 0;
 	}
 
@@ -242,7 +244,7 @@ int probe_spi_res1(struct flashctx *flash)
 	/* 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 +252,14 @@ int probe_spi_res1(struct flashctx *flash)
 	/* 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 +282,7 @@ int probe_spi_res2(struct flashctx *flash)
 	unsigned char readarr[2];
 	uint32_t id1, id2;
 
-	if (spi_res(readarr, 2)) {
+	if (spi_res(flash, readarr, 2)) {
 		return 0;
 	}
 
@@ -298,7 +301,7 @@ int probe_spi_res2(struct flashctx *flash)
 	return 1;
 }
 
-uint8_t spi_read_status_register(void)
+uint8_t spi_read_status_register(struct flashctx *flash)
 {
 	static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
 	/* FIXME: No workarounds for driver/hardware bugs in generic code. */
@@ -306,7 +309,8 @@ uint8_t spi_read_status_register(void)
 	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 +418,7 @@ int spi_prettyprint_status_register(struct flashctx *flash)
 {
 	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 +469,7 @@ int spi_chip_erase_60(struct flashctx *flash)
 		.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 +479,7 @@ int spi_chip_erase_60(struct flashctx *flash)
 	 * 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 +506,7 @@ int spi_chip_erase_c7(struct flashctx *flash)
 		.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,13 +515,14 @@ int spi_chip_erase_c7(struct flashctx *flash)
 	 * 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;
 }
 
-int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_52(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -543,7 +548,7 @@ int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int b
 		.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 +557,7 @@ int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int b
 	/* 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;
@@ -563,7 +568,8 @@ int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int b
  * 32k for SST
  * 4-32k non-uniform for EON
  */
-int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_d8(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -589,7 +595,7 @@ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int b
 		.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 +604,7 @@ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int b
 	/* 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;
@@ -607,7 +613,8 @@ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int b
 /* Block size is usually
  * 4k for PMC
  */
-int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_d7(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -633,7 +640,7 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int b
 		.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,14 +649,15 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int b
 	/* 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;
 }
 
 /* Sector size is usually 4k, though Macronix eliteflash has 64k */
-int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_20(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -675,7 +683,7 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int b
 		.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,13 +692,14 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int b
 	/* 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;
 }
 
-int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
 		msg_cerr("%s called with incorrect arguments\n",
@@ -700,7 +709,8 @@ int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int b
 	return spi_chip_erase_60(flash);
 }
 
-int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int spi_block_erase_c7(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
 		msg_cerr("%s called with incorrect arguments\n",
@@ -710,13 +720,13 @@ int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int b
 	return spi_chip_erase_c7(flash);
 }
 
-int spi_write_status_enable(void)
+int spi_write_status_enable(struct flashctx *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 +761,7 @@ static int spi_write_status_register_ewsr(struct flashctx *flash, int status)
 		.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 +776,7 @@ static int spi_write_status_register_ewsr(struct flashctx *flash, int status)
 	 * 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 +809,7 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)
 		.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 +824,7 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)
 	 * 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 +850,8 @@ int spi_write_status_register(struct flashctx *flash, int status)
 	return ret;
 }
 
-int spi_byte_program(unsigned int addr, uint8_t databyte)
+int spi_byte_program(struct flashctx *flash, unsigned int addr,
+		     uint8_t databyte)
 {
 	int result;
 	struct spi_command cmds[] = {
@@ -867,7 +878,7 @@ int spi_byte_program(unsigned int addr, uint8_t databyte)
 		.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 +886,8 @@ int spi_byte_program(unsigned int addr, uint8_t databyte)
 	return result;
 }
 
-int spi_nbyte_program(unsigned int addr, uint8_t *bytes, unsigned int len)
+int spi_nbyte_program(struct flashctx *flash, unsigned int addr, uint8_t *bytes,
+		      unsigned int len)
 {
 	int result;
 	/* FIXME: Switch to malloc based on len unless that kills speed. */
@@ -914,7 +926,7 @@ int spi_nbyte_program(unsigned int addr, uint8_t *bytes, unsigned int len)
 
 	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 +943,7 @@ int spi_disable_blockprotect(struct flashctx *flash)
 	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 +954,7 @@ int spi_disable_blockprotect(struct flashctx *flash)
 		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 +962,8 @@ int spi_disable_blockprotect(struct flashctx *flash)
 	return 0;
 }
 
-int spi_nbyte_read(unsigned int address, uint8_t *bytes, unsigned int len)
+int spi_nbyte_read(struct flashctx *flash, unsigned int address, uint8_t *bytes,
+		   unsigned int len)
 {
 	const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
 		JEDEC_READ,
@@ -960,7 +973,7 @@ int spi_nbyte_read(unsigned int address, uint8_t *bytes, unsigned int len)
 	};
 
 	/* Send Read */
-	return spi_send_command(sizeof(cmd), len, cmd, bytes);
+	return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
 }
 
 /*
@@ -968,7 +981,8 @@ int spi_nbyte_read(unsigned int address, uint8_t *bytes, unsigned int len)
  * FIXME: Use the chunk code from Michael Karcher instead.
  * Each page is read separately in chunks with a maximum size of chunksize.
  */
-int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize)
+int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		     unsigned int len, unsigned int chunksize)
 {
 	int rc = 0;
 	unsigned int i, j, starthere, lenhere, toread;
@@ -991,7 +1005,7 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, u
 		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;
 		}
@@ -1007,7 +1021,8 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, u
  * FIXME: Use the chunk code from Michael Karcher instead.
  * Each page is written separately in chunks with a maximum size of chunksize.
  */
-int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize)
+int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		      unsigned int len, unsigned int chunksize)
 {
 	int rc = 0;
 	unsigned int i, j, starthere, lenhere, towrite;
@@ -1035,10 +1050,10 @@ int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
 		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)
@@ -1055,23 +1070,25 @@ int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
  * (e.g. due to size constraints in IT87* for over 512 kB)
  */
 /* real chunksize is 1, logical chunksize is 1 */
-int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		     unsigned int len)
 {
 	unsigned int i;
 	int 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);
 	}
 
 	return 0;
 }
 
-int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start,
+		  unsigned int len)
 {
 	uint32_t pos = start;
 	int result;
@@ -1149,7 +1166,7 @@ int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsi
 	}
 
 
-	result = spi_send_multicommand(cmds);
+	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during start command execution\n",
 			 __func__);
@@ -1158,7 +1175,7 @@ int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsi
 		 */
 		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. */
@@ -1168,15 +1185,16 @@ int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsi
 	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) {
diff --git a/sst28sf040.c b/sst28sf040.c
index ca401648dd0fb9085cc1a24533ba02e9c604e77e..a9a740cdac6a37c7f739816890cb3d2cd06b9bd6 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -34,13 +34,13 @@ int protect_28sf040(struct flashctx *flash)
 {
 	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,34 +49,36 @@ int unprotect_28sf040(struct flashctx *flash)
 {
 	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;
 }
 
-int erase_sector_28sf040(struct flashctx *flash, unsigned int address, unsigned int sector_size)
+int erase_sector_28sf040(struct flashctx *flash, unsigned int address,
+			 unsigned int sector_size)
 {
 	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;
 }
 
 /* chunksize is 1 */
-int write_28sf040(struct flashctx *flash, uint8_t *src, unsigned int start, unsigned int len)
+int write_28sf040(struct flashctx *flash, uint8_t *src, unsigned int start,
+		  unsigned int len)
 {
 	int i;
 	chipaddr bios = flash->virtual_memory;
@@ -90,11 +92,11 @@ int write_28sf040(struct flashctx *flash, uint8_t *src, unsigned int start, unsi
 			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,17 +106,18 @@ static int erase_28sf040(struct flashctx *flash)
 {
 	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;
 }
 
-int erase_chip_28sf040(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+int erase_chip_28sf040(struct flashctx *flash, unsigned int addr,
+		       unsigned int blocklen)
 {
 	if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
 		msg_cerr("%s called with incorrect arguments\n",
diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c
index bcfb0433e702adf5dfd77962e697a8bac3cb69cd..37f0628f0fdb0c9b631082955b813a4482878e3e 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -23,11 +23,14 @@
 #include "flash.h"
 #include "chipdrivers.h"
 
-static int write_lockbits_block_49lfxxxc(struct flashctx *flash, unsigned long address, unsigned char bits)
+static int write_lockbits_block_49lfxxxc(struct flashctx *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;
 }
@@ -59,13 +62,14 @@ int unlock_49lfxxxc(struct flashctx *flash)
 	return write_lockbits_49lfxxxc(flash, 0);
 }
 
-int erase_sector_49lfxxxc(struct flashctx *flash, unsigned int address, unsigned int sector_size)
+int erase_sector_49lfxxxc(struct flashctx *flash, unsigned int address,
+			  unsigned int sector_size)
 {
 	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);
diff --git a/sst_fwhub.c b/sst_fwhub.c
index 3656c8107b8a763019f8c896169fd090a919f881..c802a33bb10ac324872b8b39bfce5dac4cc8119d 100644
--- a/sst_fwhub.c
+++ b/sst_fwhub.c
@@ -29,7 +29,7 @@ static int check_sst_fwhub_block_lock(struct flashctx *flash, int offset)
 	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 @@ static int clear_sst_fwhub_block_lock(struct flashctx *flash, int offset)
 
 	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");
diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c
index 65d520d9b7959a4bdb9a85231bd6d893a5890dc5..9b6443e5093c5c2cd54fb402ba9006b8b545535b 100644
--- a/stm50flw0x0x.c
+++ b/stm50flw0x0x.c
@@ -60,8 +60,10 @@ static int unlock_block_stm50flw0x0x(struct flashctx *flash, int offset)
 		// 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 +71,8 @@ static int unlock_block_stm50flw0x0x(struct flashctx *flash, int offset)
 		}
 	} 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;
 		}
@@ -94,15 +96,16 @@ int unlock_stm50flw0x0x(struct flashctx *flash)
 }
 
 /* This function is unused. */
-int erase_sector_stm50flw0x0x(struct flashctx *flash, unsigned int sector, unsigned int sectorsize)
+int erase_sector_stm50flw0x0x(struct flashctx *flash, unsigned int sector,
+			      unsigned int sectorsize)
 {
 	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);
diff --git a/w29ee011.c b/w29ee011.c
index e86c2f4bc7e6d00b6bc26f23f0347f749c29240d..d2af23dc8f4ff520c4c23e69063e05b9f1ae2fd8 100644
--- a/w29ee011.c
+++ b/w29ee011.c
@@ -38,29 +38,29 @@ int probe_w29ee011(struct flashctx *flash)
 	}
 
 	/* 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);
diff --git a/w39.c b/w39.c
index 6af50b87004fc1be30d127f494cc5bb89e372137..e6dc8deeaf9de24064852aa827fb44dfe19b34f1 100644
--- a/w39.c
+++ b/w39.c
@@ -26,7 +26,7 @@ static int printlock_w39_fwh_block(struct flashctx *flash, unsigned int offset)
 	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 @@ static int unlock_w39_fwh_block(struct flashctx *flash, unsigned int offset)
 	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 @@ static int unlock_w39_fwh_block(struct flashctx *flash, unsigned int offset)
 			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 @@ static uint8_t w39_idmode_readb(struct flashctx *flash, unsigned int offset)
 	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;
@@ -160,7 +160,7 @@ static int unlock_w39_fwh(struct flashctx *flash)
 	return 0;
 }
 
-int printlock_w39l040(struct flashctx * flash)
+int printlock_w39l040(struct flashctx *flash)
 {
 	uint8_t lock;
 	int ret;
diff --git a/wbsio_spi.c b/wbsio_spi.c
index 50ea1aa1f6a83353a10abd6efefb3dd427379c7c..740a48c980deb02a8dc417683d2c8c6d4a944266 100644
--- a/wbsio_spi.c
+++ b/wbsio_spi.c
@@ -60,9 +60,12 @@ done:
 	return flashport;
 }
 
-static int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
-		      const unsigned char *writearr, unsigned char *readarr);
-static int wbsio_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
+static int wbsio_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *writearr,
+				  unsigned char *readarr);
+static int wbsio_spi_read(struct flashctx *flash, uint8_t *buf,
+			  unsigned int start, unsigned int len);
 
 static const struct spi_programmer spi_programmer_wbsio = {
 	.type = SPI_CONTROLLER_WBSIO,
@@ -110,8 +113,10 @@ int wbsio_check_for_spi(void)
  * 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,
-		      const unsigned char *writearr, unsigned char *readarr)
+static int wbsio_spi_send_command(struct flashctx *flash, unsigned int writecnt,
+				  unsigned int readcnt,
+				  const unsigned char *writearr,
+				  unsigned char *readarr)
 {
 	int i;
 	uint8_t mode = 0;
@@ -194,7 +199,8 @@ static int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 	return 0;
 }
 
-static int wbsio_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
+static int wbsio_spi_read(struct flashctx *flash, uint8_t *buf,
+			  unsigned int start, unsigned int len)
 {
 	return read_memmapped(flash, buf, start, len);
 }