memory_mapped: Reduce `decode_sizes` to a single `max_rom_decode`

We used to store the maximum decode size, i.e. the maximum memory-mapped
range of the flash chip, per bus type (Parallel, LPC, FWH, SPI). There
was no programmer in the tree that really made use of it, though:
* The chipset drivers usually focus on a single bus type. And even if
  they advertise the whole default set (PAR, LPC, FWH), they only pro-
  vide a maximum decode size for one of them. The latter is probably
  wrong, should really more than one bus type be supported.
* PCI and external programmers all support only a single bus type, with
  the exception of `serprog` which doesn't set a maximum decode size.

What made the distinction even less useful is that for some chips that
support multiple bus types, i.e. LPC+FWH, we can't even detect which
type it is. The existing code around this also only tried to provide
the best possible warning message at the expense of breaking the pro-
grammer abstraction.

Hence, unify the set of sizes into a single `max_rom_decode` property.
We store it inside the `registered_master` struct right away, to avoid
any more use of globals.

Change-Id: I2aaea18d5b4255eb843a625b016ee74bb145ed85
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72531
diff --git a/amd_spi100.c b/amd_spi100.c
index 14096ec..b112bfe 100644
--- a/amd_spi100.c
+++ b/amd_spi100.c
@@ -309,5 +309,5 @@
 
 	spi100_check_4ba(spi100);
 
-	return register_spi_master(&spi100_master, spi100);
+	return register_spi_master(&spi100_master, 0, spi100);
 }
diff --git a/atahpt.c b/atahpt.c
index 5b375a0..beaa52d 100644
--- a/atahpt.c
+++ b/atahpt.c
@@ -74,7 +74,7 @@
 	reg32 |= (1 << 24);
 	rpci_write_long(dev, REG_FLASH_ACCESS, reg32);
 
-	return register_par_master(&par_master_atahpt, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_atahpt, BUS_PARALLEL, 0, NULL);
 }
 
 static void atahpt_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/atapromise.c b/atapromise.c
index dcdf4c2..62c7e3d 100644
--- a/atapromise.c
+++ b/atapromise.c
@@ -141,14 +141,12 @@
 		return 1;
 	}
 
-	max_rom_decode.parallel = rom_size;
-
 	msg_pwarn("Do not use this device as a generic programmer. It will leave anything outside\n"
 		  "the first %zu kB of the flash chip in an undefined state. It works fine for the\n"
 		  "purpose of updating the firmware of this device (padding may necessary).\n",
 		  rom_size / 1024);
 
-	return register_par_master(&par_master_atapromise, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_atapromise, BUS_PARALLEL, rom_size, NULL);
 }
 
 static void atapromise_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/atavia.c b/atavia.c
index dc7317c..c788b1b 100644
--- a/atavia.c
+++ b/atavia.c
@@ -159,7 +159,7 @@
 		return 1;
 	}
 
-	return register_par_master(&lpc_master_atavia, BUS_LPC, NULL);
+	return register_par_master(&lpc_master_atavia, BUS_LPC, 0, NULL);
 }
 
 static void atavia_chip_writeb(const struct flashctx *flash, uint8_t val, const chipaddr addr)
diff --git a/bitbang_spi.c b/bitbang_spi.c
index 610dc28..a377eb2 100644
--- a/bitbang_spi.c
+++ b/bitbang_spi.c
@@ -117,7 +117,7 @@
 
 	data->mst = master;
 	data->spi_data = spi_data;
-	register_spi_master(&mst, data);
+	register_spi_master(&mst, 0, data);
 
 	/* Only mess with the bus if we're sure nobody else uses it. */
 	bitbang_spi_request_bus(master, spi_data);
diff --git a/board_enable.c b/board_enable.c
index 365e0c0..56498c0 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -601,8 +601,9 @@
  * Suited for all boards with ITE IT8705F.
  * The SIS950 Super I/O probably requires a similar flash write enable.
  */
-int it8705f_write_enable(uint8_t port)
+int it8705f_write_enable(struct flashprog_programmer *const prog, const uint8_t port)
 {
+	struct internal_data *const internal = prog->data;
 	uint8_t tmp;
 	int ret = 0;
 
@@ -620,16 +621,16 @@
 		msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
 		if (tmp & 0x02) {
 			/* The data sheet contradicts itself about max size. */
-			max_rom_decode.parallel = 1024 * 1024;
+			internal->max_rom_decode = 1024 * 1024;
 			msg_pinfo("IT8705F with very unusual settings.\n"
 				  "Please send the output of \"flashprog -V -p internal\" to\n"
 				  "flashprog@flashprog.org with \"IT8705: your board name: flashprog -V\"\n"
 				  "as the subject to help us finish support for your Super I/O. Thanks.\n");
 			ret = 1;
 		} else if (tmp & 0x08) {
-			max_rom_decode.parallel = 512 * 1024;
+			internal->max_rom_decode = 512 * 1024;
 		} else {
-			max_rom_decode.parallel = 256 * 1024;
+			internal->max_rom_decode = 256 * 1024;
 		}
 		/* Safety checks. The data sheet is unclear here: Segments 1+3
 		 * overlap, no segment seems to cover top - 1MB to top - 512kB.
@@ -672,8 +673,8 @@
 			 */
 			ret = 1;
 		}
-		msg_pdbg("Maximum IT8705F parallel flash decode size is %u.\n",
-			max_rom_decode.parallel);
+		msg_pdbg("Maximum IT8705F parallel flash decode size is %zu.\n",
+			internal->max_rom_decode);
 		if (ret) {
 			msg_pinfo("Not enabling IT8705F flash write.\n");
 		} else {
@@ -2753,6 +2754,7 @@
 int board_flash_enable(struct flashprog_programmer *const prog,
 		       const char *vendor, const char *model, const char *cb_vendor, const char *cb_model)
 {
+	struct internal_data *const internal = prog->data;
 	const struct board_match *board = NULL;
 	int ret = 0;
 
@@ -2782,7 +2784,7 @@
 
 	/* limit the maximum size of the parallel bus */
 	if (board->max_rom_decode_parallel)
-		max_rom_decode.parallel = board->max_rom_decode_parallel * 1024;
+		internal->max_rom_decode = board->max_rom_decode_parallel * 1024;
 
 	if (board->enable != NULL) {
 		msg_pinfo("Enabling full flash access for board \"%s %s\"... ",
diff --git a/buspirate_spi.c b/buspirate_spi.c
index b2c58c6..34cf11f 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -607,7 +607,7 @@
 		goto init_err_cleanup_exit;
 	}
 
-	return register_spi_master(&spi_master_buspirate, bp_data);
+	return register_spi_master(&spi_master_buspirate, 0, bp_data);
 
 init_err_cleanup_exit:
 	buspirate_spi_shutdown(bp_data);
diff --git a/ch341a_spi.c b/ch341a_spi.c
index 6a2bdfb..00c2cc7 100644
--- a/ch341a_spi.c
+++ b/ch341a_spi.c
@@ -508,7 +508,7 @@
 	if ((config_stream(CH341A_STM_I2C_100K) < 0) || (enable_pins(true) < 0))
 		goto dealloc_transfers;
 
-	return register_spi_master(&spi_master_ch341a_spi, NULL);
+	return register_spi_master(&spi_master_ch341a_spi, 0, NULL);
 
 dealloc_transfers:
 	for (i = 0; i < USB_IN_TRANSFERS; i++) {
diff --git a/ch347_spi.c b/ch347_spi.c
index aa1ee0b..fb6e59a 100644
--- a/ch347_spi.c
+++ b/ch347_spi.c
@@ -359,7 +359,7 @@
 	if (ch347_spi_config(ch347_data, div) < 0)
 		goto error_exit;
 
-	return register_spi_master(&spi_master_ch347_spi, ch347_data);
+	return register_spi_master(&spi_master_ch347_spi, 0, ch347_data);
 
 error_exit:
 	ch347_spi_shutdown(ch347_data);
diff --git a/chipset_enable.c b/chipset_enable.c
index 7dcadc5..2d958e3 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -378,8 +378,10 @@
 	return enable_flash_ich_bios_cntl_common(ich_generation, addr, NULL, 0);
 }
 
-static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich_generation)
+static int enable_flash_ich_fwh_decode(struct flashprog_programmer *prog,
+				       struct pci_dev *dev, enum ich_chipset ich_generation)
 {
+	struct internal_data *const internal = prog->data;
 	uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */
 	bool implemented = 0;
 	void *ilb = NULL; /* Only for Baytrail */
@@ -547,18 +549,19 @@
 			contiguous = 0;
 		}
 	}
-	max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
-	msg_pdbg("Maximum FWH chip size: 0x%x bytes\n", max_rom_decode.fwh);
+	internal->max_rom_decode = min(max_decode_fwh_idsel, max_decode_fwh_decode);
+	msg_pdbg("Maximum FWH chip size: 0x%zx bytes\n", internal->max_rom_decode);
 
 	return 0;
 }
 
-static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+static int enable_flash_ich_fwh(struct flashprog_programmer *prog,
+				struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
 {
 	int err;
 
 	/* Configure FWH IDSEL decoder maps. */
-	if ((err = enable_flash_ich_fwh_decode(dev, ich_generation)) != 0)
+	if ((err = enable_flash_ich_fwh_decode(prog, dev, ich_generation)) != 0)
 		return err;
 
 	internal_buses_supported &= BUS_FWH;
@@ -567,22 +570,22 @@
 
 static int enable_flash_ich0(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_fwh(dev, CHIPSET_ICH, 0x4e);
+	return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH, 0x4e);
 }
 
 static int enable_flash_ich2345(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_fwh(dev, CHIPSET_ICH2345, 0x4e);
+	return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH2345, 0x4e);
 }
 
 static int enable_flash_ich6(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_fwh(dev, CHIPSET_ICH6, 0xdc);
+	return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH6, 0xdc);
 }
 
 static int enable_flash_poulsbo(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_fwh(dev, CHIPSET_POULSBO, 0xd8);
+	return enable_flash_ich_fwh(prog, dev, CHIPSET_POULSBO, 0xd8);
 }
 
 static enum chipbustype enable_flash_ich_report_gcs(
@@ -756,7 +759,8 @@
 	return boot_straps[bbs].bus;
 }
 
-static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+static int enable_flash_ich_spi(struct flashprog_programmer *prog, struct pci_dev *dev,
+				enum ich_chipset ich_generation, uint8_t bios_cntl)
 {
 	/* Get physical address of Root Complex Register Block */
 	uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000;
@@ -770,7 +774,7 @@
 	const enum chipbustype boot_buses = enable_flash_ich_report_gcs(dev, ich_generation, rcrb);
 
 	/* Handle FWH-related parameters and initialization */
-	int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl);
+	int ret_fwh = enable_flash_ich_fwh(prog, dev, ich_generation, bios_cntl);
 	if (ret_fwh == ERROR_FATAL)
 		return ret_fwh;
 
@@ -819,80 +823,80 @@
 
 static int enable_flash_tunnelcreek(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_TUNNEL_CREEK, 0xd8);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_TUNNEL_CREEK, 0xd8);
 }
 
 static int enable_flash_s12x0(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_CENTERTON, 0xd8);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_CENTERTON, 0xd8);
 }
 
 static int enable_flash_ich7(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_ICH7, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_ICH7, 0xdc);
 }
 
 static int enable_flash_ich8(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_ICH8, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_ICH8, 0xdc);
 }
 
 static int enable_flash_ich9(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_ICH9, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_ICH9, 0xdc);
 }
 
 static int enable_flash_ich10(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_ICH10, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_ICH10, 0xdc);
 }
 
 /* Ibex Peak aka. 5 series & 3400 series */
 static int enable_flash_pch5(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc);
 }
 
 /* Cougar Point aka. 6 series & c200 series */
 static int enable_flash_pch6(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc);
 }
 
 /* Panther Point aka. 7 series */
 static int enable_flash_pch7(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc);
 }
 
 /* Lynx Point aka. 8 series */
 static int enable_flash_pch8(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc);
 }
 
 /* Lynx Point LP aka. 8 series low-power */
 static int enable_flash_pch8_lp(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc);
 }
 
 /* Wellsburg (for Haswell-EP Xeons) */
 static int enable_flash_pch8_wb(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
 }
 
 /* Wildcat Point */
 static int enable_flash_pch9(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
 }
 
 /* Wildcat Point LP */
 static int enable_flash_pch9_lp(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
-	return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT_LP, 0xdc);
+	return enable_flash_ich_spi(prog, dev, CHIPSET_9_SERIES_WILDCAT_POINT_LP, 0xdc);
 }
 
 /* Sunrise Point */
@@ -1033,7 +1037,7 @@
 	physunmap(rcrb, 4);
 
 	/* Handle fwh_idsel parameter */
-	int ret_fwh = enable_flash_ich_fwh_decode(dev, ich_generation);
+	int ret_fwh = enable_flash_ich_fwh_decode(prog, dev, ich_generation);
 	if (ret_fwh == ERROR_FATAL)
 		return ret_fwh;
 
@@ -1176,6 +1180,7 @@
 
 static int enable_flash_cs5530(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
+	struct internal_data *const internal = prog->data;
 	uint8_t reg8;
 
 #define DECODE_CONTROL_REG2		0x5b	/* F0 index 0x5b */
@@ -1212,18 +1217,18 @@
 	reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG);
 	if (reg8 & CS5530_ISA_MASTER) {
 		/* We have A0-A23 available. */
-		max_rom_decode.parallel = 16 * 1024 * 1024;
+		internal->max_rom_decode = 16*MiB;
 	} else {
 		reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG);
 		if (reg8 & CS5530_ENABLE_SA2320) {
 			/* We have A0-19, A20-A23 available. */
-			max_rom_decode.parallel = 16 * 1024 * 1024;
+			internal->max_rom_decode = 16*MiB;
 		} else if (reg8 & CS5530_ENABLE_SA20) {
 			/* We have A0-19, A20 available. */
-			max_rom_decode.parallel = 2 * 1024 * 1024;
+			internal->max_rom_decode = 2*MiB;
 		} else {
 			/* A20 and above are not active. */
-			max_rom_decode.parallel = 1024 * 1024;
+			internal->max_rom_decode = 1*MiB;
 		}
 	}
 
@@ -1328,23 +1333,26 @@
 
 static int enable_flash_amd_768_8111(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
+	struct internal_data *const internal = prog->data;
 	/* Enable decoding of 0xFFB00000 to 0xFFFFFFFF (5 MB). */
-	max_rom_decode.lpc = 5 * 1024 * 1024;
+	internal->max_rom_decode = 5 * 1024 * 1024;
 	return enable_flash_amd_via(dev, name, 0xC0);
 }
 
 static int enable_flash_vt82c586(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
+	struct internal_data *const internal = prog->data;
 	/* Enable decoding of 0xFFF80000 to 0xFFFFFFFF. (512 kB) */
-	max_rom_decode.parallel = 512 * 1024;
+	internal->max_rom_decode = 512 * 1024;
 	return enable_flash_amd_via(dev, name, 0xC0);
 }
 
 /* Works for VT82C686A/B too. */
 static int enable_flash_vt82c596(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
+	struct internal_data *const internal = prog->data;
 	/* Enable decoding of 0xFFF00000 to 0xFFFFFFFF. (1 MB) */
-	max_rom_decode.parallel = 1024 * 1024;
+	internal->max_rom_decode = 1024 * 1024;
 	return enable_flash_amd_via(dev, name, 0xE0);
 }
 
diff --git a/cli_classic.c b/cli_classic.c
index 79159c3..fede2ca 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -189,48 +189,16 @@
 	return ret;
 }
 
-/* Returns the number of buses commonly supported by the current programmer and flash chip where the latter
- * can not be completely accessed due to size/address limits of the programmer. */
-static unsigned int count_max_decode_exceedings(const struct flashctx *flash,
-		const struct decode_sizes *max_rom_decode_)
+/* Returns true if the flash chip cannot be completely accessed due to size/address limits of the programmer. */
+static bool max_decode_exceeded(const struct registered_master *const mst, const struct flashctx *const flash)
 {
-	unsigned int limitexceeded = 0;
-	uint32_t size = flash->chip->total_size * 1024;
-	enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
+	if (flashprog_flash_getsize(flash) <= mst->max_rom_decode)
+		return false;
 
-	if ((buses & BUS_PARALLEL) && (max_rom_decode_->parallel < size)) {
-		limitexceeded++;
-		msg_pdbg("Chip size %u kB is bigger than supported "
-			 "size %u kB of chipset/board/programmer "
-			 "for %s interface, "
-			 "probe/read/erase/write may fail. ", size / 1024,
-			 max_rom_decode_->parallel / 1024, "Parallel");
-	}
-	if ((buses & BUS_LPC) && (max_rom_decode_->lpc < size)) {
-		limitexceeded++;
-		msg_pdbg("Chip size %u kB is bigger than supported "
-			 "size %u kB of chipset/board/programmer "
-			 "for %s interface, "
-			 "probe/read/erase/write may fail. ", size / 1024,
-			 max_rom_decode_->lpc / 1024, "LPC");
-	}
-	if ((buses & BUS_FWH) && (max_rom_decode_->fwh < size)) {
-		limitexceeded++;
-		msg_pdbg("Chip size %u kB is bigger than supported "
-			 "size %u kB of chipset/board/programmer "
-			 "for %s interface, "
-			 "probe/read/erase/write may fail. ", size / 1024,
-			 max_rom_decode_->fwh / 1024, "FWH");
-	}
-	if ((buses & BUS_SPI) && (max_rom_decode_->spi < size)) {
-		limitexceeded++;
-		msg_pdbg("Chip size %u kB is bigger than supported "
-			 "size %u kB of chipset/board/programmer "
-			 "for %s interface, "
-			 "probe/read/erase/write may fail. ", size / 1024,
-			 max_rom_decode_->spi / 1024, "SPI");
-	}
-	return limitexceeded;
+	msg_pdbg("Chip size %u kB is bigger than supported size %zu kB of\n"
+		 "chipset/board/programmer for memory-mapped interface, probe/read/erase/write\n"
+		 "may fail.\n", flash->chip->total_size, mst->max_rom_decode / KiB);
+	return true;
 }
 
 int main(int argc, char *argv[])
@@ -604,12 +572,15 @@
 	msg_pdbg("The following protocols are supported: %s.\n", tempstr);
 	free(tempstr);
 
+	struct registered_master *matched_master = NULL;
 	for (j = 0; j < registered_master_count; j++) {
 		startchip = 0;
 		while (chipcount < (int)ARRAY_SIZE(flashes)) {
 			startchip = probe_flash(&registered_masters[j], startchip, &flashes[chipcount], 0);
 			if (startchip == -1)
 				break;
+			if (chipcount == 0)
+				matched_master = &registered_masters[j];
 			chipcount++;
 			startchip++;
 		}
@@ -680,16 +651,7 @@
 
 	print_chip_support_status(fill_flash->chip);
 
-	unsigned int limitexceeded = count_max_decode_exceedings(fill_flash, &max_rom_decode);
-	if (limitexceeded > 0 && !force) {
-		enum chipbustype commonbuses = fill_flash->mst->buses_supported & fill_flash->chip->bustype;
-
-		/* Sometimes chip and programmer have more than one bus in common,
-		 * and the limit is not exceeded on all buses. Tell the user. */
-		if ((bitcount(commonbuses) > limitexceeded)) {
-			msg_pdbg("There is at least one interface available which could support the size of\n"
-				 "the selected flash chip.\n");
-		}
+	if (max_decode_exceeded(matched_master, fill_flash) && !force) {
 		msg_cerr("This flash chip is too big for this programmer (--verbose/-V gives details).\n"
 			 "Use --force/-f to override at your own risk.\n");
 		ret = 1;
diff --git a/dediprog.c b/dediprog.c
index 60bea4c..ffc8a1b 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -1325,7 +1325,7 @@
 	if (dediprog_set_leds(LED_NONE, dp_data))
 		goto init_err_cleanup_exit;
 
-	return register_spi_master(&spi_master_dediprog, dp_data);
+	return register_spi_master(&spi_master_dediprog, 0, dp_data);
 
 init_err_cleanup_exit:
 	dediprog_shutdown(dp_data);
diff --git a/digilent_spi.c b/digilent_spi.c
index afdbcd3..ee4d497 100644
--- a/digilent_spi.c
+++ b/digilent_spi.c
@@ -449,7 +449,7 @@
 	if (spi_set_mode(0x00) != 0)
 		goto close_handle;
 
-	return register_spi_master(&spi_master_digilent_spi, NULL);
+	return register_spi_master(&spi_master_digilent_spi, 0, NULL);
 
 close_handle:
 	libusb_close(handle);
diff --git a/dirtyjtag_spi.c b/dirtyjtag_spi.c
index 06099de..3074489 100644
--- a/dirtyjtag_spi.c
+++ b/dirtyjtag_spi.c
@@ -399,7 +399,7 @@
 		goto cleanup_libusb_handle;
 	}
 
-	return register_spi_master(&dirtyjtag_spi, djtag_data);
+	return register_spi_master(&dirtyjtag_spi, 0, djtag_data);
 
 cleanup_libusb_handle:
 	libusb_attach_kernel_driver(handle, 0);
diff --git a/drkaiser.c b/drkaiser.c
index 0a67f09..6fcb5d2 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -74,8 +74,7 @@
 	if (drkaiser_bar == ERROR_PTR)
 		return 1;
 
-	max_rom_decode.parallel = 128 * 1024;
-	return register_par_master(&par_master_drkaiser, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_drkaiser, BUS_PARALLEL, 128*KiB, NULL);
 }
 
 static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/dummyflasher.c b/dummyflasher.c
index 548c16f..6b74ce2 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -503,9 +503,9 @@
 	if (dummy_buses_supported & BUS_NONSPI)
 		ret |= register_par_master(&par_master_dummyflasher,
 					   dummy_buses_supported & BUS_NONSPI,
-					   data);
+					   0, data);
 	if (dummy_buses_supported & BUS_SPI)
-		ret |= register_spi_master(&spi_master_dummyflasher, data);
+		ret |= register_spi_master(&spi_master_dummyflasher, 0, data);
 
 	return ret;
 }
diff --git a/flashprog.c b/flashprog.c
index 4e669c7..1878997 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -40,12 +40,6 @@
 static const struct programmer_entry *programmer = NULL;
 static char *programmer_param = NULL;
 
-/*
- * Programmers supporting multiple buses can have differing size limits on
- * each bus. Store the limits for each bus in a common struct.
- */
-struct decode_sizes max_rom_decode;
-
 /* If nonzero, used as the start address of bottom-aligned flash. */
 unsigned long flashbase;
 
@@ -141,13 +135,6 @@
 	programmer = prog->driver;
 	programmer_param = prog->param;
 	/* Initialize all programmer specific data. */
-	/* Default to unlimited decode sizes. */
-	max_rom_decode = (const struct decode_sizes) {
-		.parallel	= 0xffffffff,
-		.lpc		= 0xffffffff,
-		.fwh		= 0xffffffff,
-		.spi		= 0xffffffff,
-	};
 	/* Default to top aligned flash at 4 GB. */
 	flashbase = 0;
 	/* Registering shutdown functions is now allowed. */
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 020eadc..e3b19d0 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -691,7 +691,7 @@
 	spi_data->aux_bits = aux_bits;
 	spi_data->pindir = pindir;
 
-	return register_spi_master(&spi_master_ft2232, spi_data);
+	return register_spi_master(&spi_master_ft2232, 0, spi_data);
 
 ftdi_err:
 	if ((f = ftdi_usb_close(ftdic)) < 0) {
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 5055b8b..253180e 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -102,7 +102,7 @@
 
 	/* Write/erase doesn't work. */
 	programmer_may_write = false;
-	return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, 0, NULL);
 }
 
 static void gfxnvidia_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/ichspi.c b/ichspi.c
index b4555b9..c7e8fe7 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -1827,7 +1827,7 @@
 		}
 		ich_init_opcodes();
 		ich_set_bbar(0);
-		register_spi_master(&spi_master_ich7, NULL);
+		register_spi_master(&spi_master_ich7, 0, NULL);
 		break;
 	case CHIPSET_ICH8:
 	default:		/* Future version might behave the same */
@@ -2065,7 +2065,7 @@
 
 			register_opaque_master(&opaque_master_ich_hwseq, NULL);
 		} else {
-			register_spi_master(&spi_master_ich9, NULL);
+			register_spi_master(&spi_master_ich9, 0, NULL);
 		}
 		break;
 	}
@@ -2095,7 +2095,7 @@
 	/* Not sure if it speaks all these bus protocols. */
 	internal_buses_supported &= BUS_LPC | BUS_FWH;
 	ich_generation = CHIPSET_ICH7;
-	register_spi_master(&spi_master_via, NULL);
+	register_spi_master(&spi_master_via, 0, NULL);
 
 	msg_pdbg("0x00: 0x%04x     (SPIS)\n", mmio_readw(ich_spibar + 0));
 	msg_pdbg("0x02: 0x%04x     (SPIC)\n", mmio_readw(ich_spibar + 2));
diff --git a/include/programmer.h b/include/programmer.h
index 6425788..418eadd 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -20,6 +20,7 @@
 #ifndef __PROGRAMMER_H__
 #define __PROGRAMMER_H__ 1
 
+#include <limits.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdbool.h>
@@ -99,6 +100,7 @@
 struct flashprog_programmer {
 	const struct programmer_entry *driver;
 	char *param; /* TODO: Replace with flashprog_cfg (cf. flashrom/master) */
+	void *data;
 };
 
 int programmer_init(struct flashprog_programmer *);
@@ -226,7 +228,7 @@
 void w836xx_ext_enter(uint16_t port);
 void w836xx_ext_leave(uint16_t port);
 void probe_superio_winbond(void);
-int it8705f_write_enable(uint8_t port);
+int it8705f_write_enable(struct flashprog_programmer *, uint8_t port);
 uint8_t sio_read(uint16_t port, uint8_t reg);
 void sio_write(uint16_t port, uint8_t reg, uint8_t data);
 void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
@@ -254,6 +256,9 @@
 #endif // defined(__i386__) || defined(__x86_64__)
 
 /* internal.c */
+struct internal_data {
+	size_t max_rom_decode;
+};
 struct superio {
 	uint16_t vendor;
 	uint16_t port;
@@ -281,14 +286,7 @@
 
 
 /* flashprog.c */
-struct decode_sizes {
-	uint32_t parallel;
-	uint32_t lpc;
-	uint32_t fwh;
-	uint32_t spi;
-};
 // FIXME: These need to be local, not global
-extern struct decode_sizes max_rom_decode;
 extern bool programmer_may_write;
 extern unsigned long flashbase;
 char *extract_programmer_param(const char *param_name);
@@ -326,7 +324,7 @@
 int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
 int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
 bool default_spi_probe_opcode(const struct flashctx *flash, uint8_t opcode);
-int register_spi_master(const struct spi_master *mst, void *data);
+int register_spi_master(const struct spi_master *mst, size_t max_rom_decode, void *data);
 
 /* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */
 enum ich_chipset {
@@ -374,7 +372,7 @@
 void enter_conf_mode_ite(uint16_t port);
 void exit_conf_mode_ite(uint16_t port);
 void probe_superio_ite(void);
-int init_superio_ite(void);
+int init_superio_ite(struct flashprog_programmer *);
 
 #if CONFIG_LINUX_MTD == 1 && LINUX_MTD_AS_INTERNAL == 1
 /* trivial wrapper to avoid cluttering internal_init() with #if */
@@ -424,7 +422,7 @@
 	int (*shutdown)(void *data);
 	void *data;
 };
-int register_par_master(const struct par_master *mst, const enum chipbustype buses, void *data);
+int register_par_master(const struct par_master *mst, const enum chipbustype buses, size_t max_rom_decode, void *data);
 
 /* programmer.c */
 void *fallback_map(const char *descr, uintptr_t phys_addr, size_t len);
@@ -435,7 +433,10 @@
 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);
+#define DEFAULT_MAX_DECODE_PARALLEL (16*MiB)
+#define MAX_ROM_DECODE_UNLIMITED UINT32_MAX
 struct registered_master {
+	size_t max_rom_decode;
 	enum chipbustype buses_supported;
 	union {
 		struct par_master par;
diff --git a/internal.c b/internal.c
index 72a7a22..8af2690 100644
--- a/internal.c
+++ b/internal.c
@@ -180,6 +180,19 @@
 	if (ret)
 		return ret;
 
+	struct internal_data *const internal = malloc(sizeof(*internal));
+	if (!internal) {
+		msg_perr("Out of memory!\n");
+		ret = 1;
+		goto internal_init_exit;
+	}
+	if (register_shutdown(shutdown_free, internal)) {
+		ret = 1;
+		goto internal_init_exit;
+	}
+	internal->max_rom_decode = 0;
+	prog->data = internal;
+
 	/* Unconditionally reset global state from previous operation. */
 	laptop_ok = false;
 
@@ -268,7 +281,7 @@
 #if defined(__i386__) || defined(__x86_64__)
 	/* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
 	 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
-	init_superio_ite();
+	init_superio_ite(prog);
 
 	if (board_flash_enable(prog, board_vendor, board_model, cb_vendor, cb_model)) {
 		msg_perr("Aborting to be safe.\n");
@@ -277,8 +290,10 @@
 	}
 #endif
 
-	if (internal_buses_supported & BUS_NONSPI)
-		register_par_master(&par_master_internal, internal_buses_supported, NULL);
+	if (internal_buses_supported & BUS_NONSPI) {
+		register_par_master(&par_master_internal, internal_buses_supported,
+				    internal->max_rom_decode, NULL);
+	}
 
 	/* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
 	if (is_laptop && !laptop_ok) {
diff --git a/it8212.c b/it8212.c
index 4cf0e80..8158a95 100644
--- a/it8212.c
+++ b/it8212.c
@@ -64,8 +64,7 @@
 	/* Restore ROM BAR decode state automatically at shutdown. */
 	rpci_write_long(dev, PCI_ROM_ADDRESS, io_base_addr | 0x01);
 
-	max_rom_decode.parallel = IT8212_MEMMAP_SIZE;
-	return register_par_master(&par_master_it8212, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_it8212, BUS_PARALLEL, IT8212_MEMMAP_SIZE, NULL);
 }
 
 static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/it87spi.c b/it87spi.c
index 6dfbe5c..25e826e 100644
--- a/it87spi.c
+++ b/it87spi.c
@@ -233,11 +233,11 @@
 	if (internal_buses_supported & BUS_SPI)
 		msg_pdbg("Overriding chipset SPI with IT87 SPI.\n");
 	/* FIXME: Add the SPI bus or replace the other buses with it? */
-	register_spi_master(&spi_master_it87xx, NULL);
+	register_spi_master(&spi_master_it87xx, 0, NULL);
 	return 0;
 }
 
-int init_superio_ite(void)
+int init_superio_ite(struct flashprog_programmer *const prog)
 {
 	int i;
 	int ret = 0;
@@ -248,7 +248,7 @@
 
 		switch (superios[i].model) {
 		case 0x8705:
-			ret |= it8705f_write_enable(superios[i].port);
+			ret |= it8705f_write_enable(prog, superios[i].port);
 			break;
 		case 0x8686:
 		case 0x8716:
diff --git a/jlink_spi.c b/jlink_spi.c
index b234b0e..61338b6 100644
--- a/jlink_spi.c
+++ b/jlink_spi.c
@@ -518,7 +518,7 @@
 	if (!deassert_cs(jlink_data))
 		goto init_err;
 
-	return register_spi_master(&spi_master_jlink_spi, jlink_data);
+	return register_spi_master(&spi_master_jlink_spi, 0, jlink_data);
 
 init_err:
 	if (jaylink_devh)
diff --git a/linux_spi.c b/linux_spi.c
index aac232a..891c493 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -186,7 +186,7 @@
 	spi_data->fd = fd;
 	spi_data->max_kernel_buf_size = max_kernel_buf_size;
 
-	return register_spi_master(&spi_master_linux, spi_data);
+	return register_spi_master(&spi_master_linux, 0, spi_data);
 
 init_err:
 	close(fd);
diff --git a/mstarddc_spi.c b/mstarddc_spi.c
index 9888d1f..b9ee23f 100644
--- a/mstarddc_spi.c
+++ b/mstarddc_spi.c
@@ -142,7 +142,7 @@
 	}
 
 	// Register programmer
-	register_spi_master(&spi_master_mstarddc, NULL);
+	register_spi_master(&spi_master_mstarddc, 0, NULL);
 out:
 	free(i2c_device);
 	return ret;
diff --git a/ni845x_spi.c b/ni845x_spi.c
index beb5ea5..8b2dcb3 100644
--- a/ni845x_spi.c
+++ b/ni845x_spi.c
@@ -476,7 +476,7 @@
 		return 1;
 	}
 
-	return register_spi_master(&spi_programmer_ni845x, NULL);
+	return register_spi_master(&spi_programmer_ni845x, 0, NULL);
 }
 
 static int ni845x_spi_shutdown(void *data)
diff --git a/nic3com.c b/nic3com.c
index 64cb259..eec24bf 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -117,9 +117,7 @@
 	 */
 	OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
 
-	max_rom_decode.parallel = 128 * 1024;
-
-	return register_par_master(&par_master_nic3com, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_nic3com, BUS_PARALLEL, 128*KiB, NULL);
 }
 
 static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicintel.c b/nicintel.c
index 1c63081..573b361 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -93,8 +93,7 @@
 	 */
 	pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
 
-	max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE;
-	return register_par_master(&par_master_nicintel, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_nicintel, BUS_PARALLEL, NICINTEL_MEMMAP_SIZE, NULL);
 }
 
 static void nicintel_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicnatsemi.c b/nicnatsemi.c
index 65a42fa..44c7ef4 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -63,14 +63,14 @@
 	if (!io_base_addr)
 		return 1;
 
-	/* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
+	/*
+	 * The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
 	 * in another. My NIC has MA16 connected to A16 on the boot ROM socket
-	 * so I'm assuming it is accessible. If not then next line wants to be
-	 * max_rom_decode.parallel = 65536; and the mask in the read/write
-	 * functions below wants to be 0x0000FFFF.
+	 * so I'm assuming it is accessible. If not then max_rom_decode wants
+	 * to be 64KiB; and the mask in the read/write functions below wants
+	 * to be 0x0000FFFF.
 	 */
-	max_rom_decode.parallel = 131072;
-	return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, 128*KiB, NULL);
 }
 
 static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicrealtek.c b/nicrealtek.c
index 2f51495..df81274 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -84,7 +84,7 @@
 		break;
 	}
 
-	return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, 0, NULL);
 }
 
 static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/opaque.c b/opaque.c
index f12c7d9..72bb131 100644
--- a/opaque.c
+++ b/opaque.c
@@ -63,6 +63,7 @@
 			 __func__);
 		return ERROR_FLASHPROG_BUG;
 	}
+	rmst.max_rom_decode = MAX_ROM_DECODE_UNLIMITED;
 	rmst.buses_supported = BUS_PROG;
 	rmst.opaque = *mst;
 	if (data)
diff --git a/parallel.c b/parallel.c
index 3fb25b4..fb3def8 100644
--- a/parallel.c
+++ b/parallel.c
@@ -63,9 +63,8 @@
 	flash->mst->par.chip_readn(flash, buf, addr, len);
 }
 
-int register_par_master(const struct par_master *mst,
-			    const enum chipbustype buses,
-			    void *data)
+int register_par_master(const struct par_master *mst, const enum chipbustype buses,
+			const size_t max_rom_decode, void *data)
 {
 	struct registered_master rmst;
 
@@ -85,6 +84,10 @@
 		return ERROR_FLASHPROG_BUG;
 	}
 
+	if (max_rom_decode)
+		rmst.max_rom_decode = max_rom_decode;
+	else
+		rmst.max_rom_decode = DEFAULT_MAX_DECODE_PARALLEL;
 	rmst.buses_supported = buses;
 	rmst.par = *mst;
 	if (data)
diff --git a/pickit2_spi.c b/pickit2_spi.c
index 13a47f9..a7b658e 100644
--- a/pickit2_spi.c
+++ b/pickit2_spi.c
@@ -498,7 +498,7 @@
 		goto init_err_cleanup_exit;
 	}
 
-	return register_spi_master(&spi_master_pickit2, pickit2_data);
+	return register_spi_master(&spi_master_pickit2, 0, pickit2_data);
 
 init_err_cleanup_exit:
 	pickit2_shutdown(pickit2_data);
diff --git a/satamv.c b/satamv.c
index cefe4c4..a957505 100644
--- a/satamv.c
+++ b/satamv.c
@@ -148,8 +148,7 @@
 
 	/* 512 kByte with two 8-bit latches, and
 	 * 4 MByte with additional 3-bit latch. */
-	max_rom_decode.parallel = 4 * 1024 * 1024;
-	return register_par_master(&par_master_satamv, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_satamv, BUS_PARALLEL, 4*MiB, NULL);
 }
 
 /* BAR2 (MEM) can map NVRAM and flash. We set it to flash in the init function.
diff --git a/satasii.c b/satasii.c
index a638cdb..abb1d4c 100644
--- a/satasii.c
+++ b/satasii.c
@@ -98,7 +98,7 @@
 	if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26))))
 		msg_pwarn("Warning: Flash seems unconnected.\n");
 
-	return register_par_master(&par_master_satasii, BUS_PARALLEL, NULL);
+	return register_par_master(&par_master_satasii, BUS_PARALLEL, 0, NULL);
 }
 
 static void satasii_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/sb600spi.c b/sb600spi.c
index ba7bd3e..41496a5 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -652,8 +652,8 @@
 
 	/* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */
 	if (amd_gen < CHIPSET_YANGTZE)
-		register_spi_master(&spi_master_sb600, NULL);
+		register_spi_master(&spi_master_sb600, 0, NULL);
 	else
-		register_spi_master(&spi_master_yangtze, NULL);
+		register_spi_master(&spi_master_yangtze, 0, NULL);
 	return 0;
 }
diff --git a/serprog.c b/serprog.c
index 50ec327..90813fd 100644
--- a/serprog.c
+++ b/serprog.c
@@ -730,9 +730,9 @@
 	if (register_shutdown(serprog_shutdown, NULL))
 		goto init_err_cleanup_exit;
 	if (serprog_buses_supported & BUS_SPI)
-		register_spi_master(&spi_master_serprog, NULL);
+		register_spi_master(&spi_master_serprog, 0, NULL);
 	if (serprog_buses_supported & BUS_NONSPI)
-		register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI, NULL);
+		register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI, 0, NULL);
 	return 0;
 
 init_err_cleanup_exit:
diff --git a/spi.c b/spi.c
index ddf76f5..1c1586e 100644
--- a/spi.c
+++ b/spi.c
@@ -136,7 +136,7 @@
 	return true;
 }
 
-int register_spi_master(const struct spi_master *mst, void *data)
+int register_spi_master(const struct spi_master *mst, size_t max_rom_decode, void *data)
 {
 	struct registered_master rmst;
 
@@ -157,7 +157,10 @@
 		return ERROR_FLASHPROG_BUG;
 	}
 
-
+	if (max_rom_decode)
+		rmst.max_rom_decode = max_rom_decode;
+	else
+		rmst.max_rom_decode = MAX_ROM_DECODE_UNLIMITED;
 	rmst.buses_supported = BUS_SPI;
 	rmst.spi = *mst;
 	if (data)
diff --git a/stlinkv3_spi.c b/stlinkv3_spi.c
index b15c703..b1c7457 100644
--- a/stlinkv3_spi.c
+++ b/stlinkv3_spi.c
@@ -505,7 +505,7 @@
 	if (stlinkv3_spi_open(sck_freq_kHz))
 		goto init_err_exit;
 
-	return register_spi_master(&spi_programmer_stlinkv3, NULL);
+	return register_spi_master(&spi_programmer_stlinkv3, 0, NULL);
 
 init_err_exit:
 	if (stlinkv3_handle)
diff --git a/usbblaster_spi.c b/usbblaster_spi.c
index 5be423b..5464c11 100644
--- a/usbblaster_spi.c
+++ b/usbblaster_spi.c
@@ -110,7 +110,7 @@
 		return -1;
 	}
 
-	register_spi_master(&spi_master_usbblaster, NULL);
+	register_spi_master(&spi_master_usbblaster, 0, NULL);
 	return 0;
 }
 
diff --git a/wbsio_spi.c b/wbsio_spi.c
index d4f2aac..2b36d16 100644
--- a/wbsio_spi.c
+++ b/wbsio_spi.c
@@ -92,8 +92,7 @@
 
 	msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is "
 		 "1024 kB!\n", __func__);
-	max_rom_decode.spi = wbsio_max_mmapped;
-	register_spi_master(&spi_master_wbsio, NULL);
+	register_spi_master(&spi_master_wbsio, wbsio_max_mmapped, NULL);
 
 	return 0;
 }