Let the flash context directly point to the used master

We used to have a pointer to a full `registered_master` struct in
our flash context. Beside the used master, this contained a bit
mask of supported buses. Oddly convenient, this bit mask invited
to bypass the chip driver and break the abstraction. It allowed
to place bus-specific details virtually anywhere in flashprog,
making it harder to find a good place for them.

So, get rid of the `buses_supported` bit mask by pointing directly
to the master. Only the chip driver will implicitly know which type
of master is used.

Change-Id: I9ce13d8df0e7ccc67519d888dd9cb2e2ff8d6682
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72533
diff --git a/amd_spi100.c b/amd_spi100.c
index b112bfe..43d2623 100644
--- a/amd_spi100.c
+++ b/amd_spi100.c
@@ -96,7 +96,7 @@
 			       const unsigned int writecnt, const unsigned int readcnt,
 			       const unsigned char *const writearr, unsigned char *const readarr)
 {
-	const struct spi100 *const spi100 = flash->mst->spi.data;
+	const struct spi100 *const spi100 = flash->mst.spi->data;
 
 	int ret = spi100_check_readwritecnt(writecnt, readcnt);
 	if (ret)
@@ -139,7 +139,7 @@
 
 static int spi100_read(struct flashctx *const flash, uint8_t *buf, unsigned int start, unsigned int len)
 {
-	const struct spi100 *const spi100 = flash->mst->spi.data;
+	const struct spi100 *const spi100 = flash->mst.spi->data;
 	const chipsize_t chip_size = flashprog_flash_getsize(flash);
 
 	/* Don't consider memory mapping at all
diff --git a/at45db.c b/at45db.c
index 463442c..acde996 100644
--- a/at45db.c
+++ b/at45db.c
@@ -241,7 +241,7 @@
 
 	/* We have to split this up into chunks to fit within the programmer's read size limit, but those
 	 * chunks can cross page boundaries. */
-	const unsigned int max_data_read = flash->mst->spi.max_data_read;
+	const unsigned int max_data_read = flash->mst.spi->max_data_read;
 	const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
 	while (len > 0) {
 		unsigned int chunk = min(max_chunk, len);
@@ -272,7 +272,7 @@
 
 	/* We have to split this up into chunks to fit within the programmer's read size limit, but those
 	 * chunks can cross page boundaries. */
-	const unsigned int max_data_read = flash->mst->spi.max_data_read;
+	const unsigned int max_data_read = flash->mst.spi->max_data_read;
 	const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
 	while (len > 0) {
 		const unsigned int addr_at45 = at45db_convert_addr(addr, page_size);
@@ -463,7 +463,7 @@
 	}
 
 	/* Create a suitable buffer to store opcode, address and data chunks for buffer1. */
-	const unsigned int max_data_write = flash->mst->spi.max_data_write;
+	const unsigned int max_data_write = flash->mst.spi->max_data_write;
 	const unsigned int max_chunk = max_data_write > 4 && max_data_write - 4 <= page_size ?
 				       max_data_write - 4 : page_size;
 	uint8_t buf[4 + max_chunk];
diff --git a/bitbang_spi.c b/bitbang_spi.c
index a377eb2..c43fa2f 100644
--- a/bitbang_spi.c
+++ b/bitbang_spi.c
@@ -166,7 +166,7 @@
 				    unsigned char *readarr)
 {
 	unsigned int i;
-	const struct bitbang_spi_master_data *data = flash->mst->spi.data;
+	const struct bitbang_spi_master_data *data = flash->mst.spi->data;
 	const struct bitbang_spi_master *master = data->mst;
 
 	/* FIXME: Run bitbang_spi_request_bus here or in programmer init?
diff --git a/buspirate_spi.c b/buspirate_spi.c
index 34cf11f..d12c100 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -617,7 +617,7 @@
 static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
 					 const unsigned char *writearr, unsigned char *readarr)
 {
-	struct bp_spi_data *bp_data = flash->mst->spi.data;
+	struct bp_spi_data *bp_data = flash->mst.spi->data;
 	unsigned int i = 0;
 	int ret = 0;
 
@@ -673,7 +673,7 @@
 static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
 					 const unsigned char *writearr, unsigned char *readarr)
 {
-	struct bp_spi_data *bp_data = flash->mst->spi.data;
+	struct bp_spi_data *bp_data = flash->mst.spi->data;
 	int i = 0, ret = 0;
 
 	if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096)
diff --git a/ch347_spi.c b/ch347_spi.c
index fb6e59a..27e3374 100644
--- a/ch347_spi.c
+++ b/ch347_spi.c
@@ -182,7 +182,7 @@
 static int ch347_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
 		unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
 {
-	struct ch347_spi_data *ch347_data = flash->mst->spi.data;
+	struct ch347_spi_data *ch347_data = flash->mst.spi->data;
 	int ret = 0;
 
 	ch347_cs_control(ch347_data, CH347_CS_ASSERT | CH347_CS_CHANGE, CH347_CS_IGNORE);
diff --git a/dediprog.c b/dediprog.c
index ffc8a1b..9fc0baf 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -371,7 +371,7 @@
 		struct flashctx *const flash, uint8_t *data_packet, unsigned int count,
 		uint8_t dedi_spi_cmd, unsigned int *value, unsigned int *idx, unsigned int start, int is_read)
 {
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	if (count > MAX_BLOCK_COUNT) {
 		msg_perr("%s: Unsupported transfer length of %u blocks!\n"
@@ -444,7 +444,7 @@
 static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
 {
 	int err = 1;
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	/* chunksize must be 512, other sizes will NOT work at all. */
 	const unsigned int chunksize = 512;
@@ -550,7 +550,7 @@
 	const unsigned int chunksize = 0x200;
 	unsigned int residue = start % chunksize ? min(len, chunksize - start % chunksize) : 0;
 	unsigned int bulklen;
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	dediprog_set_leds(LED_BUSY, dp_data);
 
@@ -600,7 +600,7 @@
 	 * space in a USB bulk transfer must be filled with 0xff padding.
 	 */
 	const unsigned int count = len / chunksize;
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	/*
 	 * We should change this check to
@@ -674,7 +674,7 @@
 	const unsigned int chunksize = flash->chip->page_size;
 	unsigned int residue = start % chunksize ? chunksize - start % chunksize : 0;
 	unsigned int bulklen;
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	dediprog_set_leds(LED_BUSY, dp_data);
 
@@ -754,14 +754,14 @@
 				     unsigned char *readarr)
 {
 	int ret;
-	const struct dediprog_data *dp_data = flash->mst->spi.data;
+	const struct dediprog_data *dp_data = flash->mst.spi->data;
 
 	msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
-	if (writecnt > flash->mst->spi.max_data_write) {
+	if (writecnt > flash->mst.spi->max_data_write) {
 		msg_perr("Invalid writecnt=%i, aborting.\n", writecnt);
 		return 1;
 	}
-	if (readcnt > flash->mst->spi.max_data_read) {
+	if (readcnt > flash->mst.spi->max_data_read) {
 		msg_perr("Invalid readcnt=%i, aborting.\n", readcnt);
 		return 1;
 	}
diff --git a/dirtyjtag_spi.c b/dirtyjtag_spi.c
index 3074489..e648cfa 100644
--- a/dirtyjtag_spi.c
+++ b/dirtyjtag_spi.c
@@ -174,7 +174,7 @@
 					     unsigned int writecnt, unsigned int readcnt,
 					     const unsigned char *writearr, unsigned char *readarr)
 {
-	struct dirtyjtag_spi_data *context = flash->mst->spi.data;
+	struct dirtyjtag_spi_data *context = flash->mst.spi->data;
 	const size_t max_xfer_size = 30; // max transfer size in DJTAG1
 	size_t len = writecnt + readcnt;
 	size_t num_xfer = (len + max_xfer_size - 1 ) / max_xfer_size; // ceil(len/max_xfer_size)
@@ -224,7 +224,7 @@
 					     unsigned int writecnt, unsigned int readcnt,
 					     const unsigned char *writearr, unsigned char *readarr)
 {
-	struct dirtyjtag_spi_data *const context = flash->mst->spi.data;
+	struct dirtyjtag_spi_data *const context = flash->mst.spi->data;
 	const size_t max_xfer_size = 62; /* max transfer size in DJTAG2 */
 	uint8_t transfer_buffer[2 + max_xfer_size]; /* 1B command + 1B len + payload */
 	size_t i;
diff --git a/dummyflasher.c b/dummyflasher.c
index 6b74ce2..948dc0b 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -1149,7 +1149,7 @@
 				  unsigned char *readarr)
 {
 	unsigned int i;
-	struct emu_data *emu_data = flash->mst->spi.data;
+	struct emu_data *emu_data = flash->mst.spi->data;
 	if (!emu_data) {
 		msg_perr("No data in flash context!\n");
 		return 1;
@@ -1188,14 +1188,14 @@
 
 static int dummy_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	const struct emu_data *const data = flash->mst->spi.data;
+	const struct emu_data *const data = flash->mst.spi->data;
 	return spi_write_chunked(flash, buf, start, len, data->spi_write_256_chunksize);
 }
 
 static bool dummy_spi_probe_opcode(const struct flashctx *flash, uint8_t opcode)
 {
 	size_t i;
-	const struct emu_data *emu_data = flash->mst->spi.data;
+	const struct emu_data *emu_data = flash->mst.spi->data;
 	for (i = 0; i < emu_data->spi_blacklist_size; i++) {
 		if (emu_data->spi_blacklist[i] == opcode)
 			return false;
diff --git a/flashprog.c b/flashprog.c
index 1878997..bca0b20 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -574,7 +574,7 @@
 			return -1;
 		}
 		*flash->chip = *chip;
-		flash->mst = mst;
+		flash->mst.par = &mst->par; /* both `mst` are unions, so we need only one pointer */
 
 		if (flash->chip->prepare_access && flash->chip->prepare_access(flash, PREPARE_PROBE))
 			goto free_chip;
@@ -768,7 +768,7 @@
 		const uint8_t *opcode = spi_get_opcode_from_erasefn(eraser.block_erase, &native_4ba);
 		for (i = 0; opcode[i]; i++) {
 			if ((native_4ba && !spi_master_4ba(flash)) ||
-			    !flash->mst->spi.probe_opcode(flash, opcode[i])) {
+			    !flash->mst.spi->probe_opcode(flash, opcode[i])) {
 				if (log)
 					msg_cdbg("block erase function and layout found "
 						 "but SPI master doesn't support the function. ");
diff --git a/ft2232_spi.c b/ft2232_spi.c
index e3b19d0..889db98 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -215,7 +215,7 @@
 /* Returns 0 upon success, a negative number upon errors. */
 static int ft2232_spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds)
 {
-	struct ft2232_data *spi_data = flash->mst->spi.data;
+	struct ft2232_data *spi_data = flash->mst.spi->data;
 	struct ftdi_context *ftdic = &spi_data->ftdi_context;
 	static unsigned char buf[FTDI_HW_BUFFER_SIZE];
 	size_t i = 0;
diff --git a/ichspi.c b/ichspi.c
index c7e8fe7..74b4e3e 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -758,7 +758,7 @@
 
 /* Read len bytes from the fdata/spid register into the data array.
  *
- * Note that using len > flash->mst->spi.max_data_read will return garbage or
+ * Note that using len > flash->mst.spi->max_data_read will return garbage or
  * may even crash.
  */
 static void ich_read_data(uint8_t *data, int len, int reg0_off)
@@ -776,7 +776,7 @@
 
 /* Fill len bytes from the data array into the fdata/spid registers.
  *
- * Note that using len > flash->mst->spi.max_data_write will trash the registers
+ * Note that using len > flash->mst.spi->max_data_write will trash the registers
  * following the data registers.
  */
 static void ich_fill_data(const uint8_t *data, int len, int reg0_off)
@@ -1083,7 +1083,7 @@
 		      uint8_t datalength, uint8_t * data)
 {
 	/* max_data_read == max_data_write for all Intel/VIA SPI masters */
-	uint8_t maxlength = flash->mst->spi.max_data_read;
+	uint8_t maxlength = flash->mst.spi->max_data_read;
 
 	if (ich_generation == CHIPSET_ICH_UNKNOWN) {
 		msg_perr("%s: unsupported chipset\n", __func__);
@@ -1449,7 +1449,7 @@
 
 	while (len > 0) {
 		/* Obey programmer limit... */
-		block_len = min(len, flash->mst->opaque.max_data_read);
+		block_len = min(len, flash->mst.opaque->max_data_read);
 		/* as well as flash chip page borders as demanded in the Intel datasheets. */
 		block_len = min(block_len, 256 - (addr & 0xFF));
 
@@ -1490,7 +1490,7 @@
 	while (len > 0) {
 		ich_hwseq_set_addr(addr);
 		/* Obey programmer limit... */
-		block_len = min(len, flash->mst->opaque.max_data_write);
+		block_len = min(len, flash->mst.opaque->max_data_write);
 		/* as well as flash chip page borders as demanded in the Intel datasheets. */
 		block_len = min(block_len, 256 - (addr & 0xFF));
 		ich_fill_data(buf, block_len, ICH9_REG_FDATA0);
diff --git a/include/flash.h b/include/flash.h
index 340af59..db47219 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -350,7 +350,11 @@
 	/* Some flash devices have an additional register space; semantics are like above. */
 	uintptr_t physical_registers;
 	chipaddr virtual_registers;
-	struct registered_master *mst;
+	union {
+		struct par_master *par;
+		struct spi_master *spi;
+		struct opaque_master *opaque;
+	} mst;
 	const struct flashprog_layout *layout;
 	struct flashprog_layout *default_layout;
 	struct {
@@ -432,6 +436,7 @@
 void unmap_flash(struct flashctx *flash);
 int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 int erase_flash(struct flashctx *flash);
+struct registered_master;
 int probe_flash(struct registered_master *mst, int startchip, struct flashctx *fill_flash, int force);
 int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len);
 void emergency_help_message(void);
diff --git a/include/programmer.h b/include/programmer.h
index 418eadd..edef52b 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -498,11 +498,11 @@
 /* spi_master feature checks */
 static inline bool spi_master_4ba(const struct flashctx *const flash)
 {
-	return flash->mst->spi.features & SPI_MASTER_4BA;
+	return flash->mst.spi->features & SPI_MASTER_4BA;
 }
 static inline bool spi_master_no_4ba_modes(const struct flashctx *const flash)
 {
-	return flash->mst->spi.features & SPI_MASTER_NO_4BA_MODES;
+	return flash->mst.spi->features & SPI_MASTER_NO_4BA_MODES;
 }
 
 /* usbdev.c */
diff --git a/jlink_spi.c b/jlink_spi.c
index 61338b6..7534cbb 100644
--- a/jlink_spi.c
+++ b/jlink_spi.c
@@ -109,7 +109,7 @@
 {
 	uint32_t length;
 	uint8_t *buffer;
-	struct jlink_spi_data *jlink_data = flash->mst->spi.data;
+	struct jlink_spi_data *jlink_data = flash->mst.spi->data;
 
 	length = writecnt + readcnt;
 
diff --git a/linux_mtd.c b/linux_mtd.c
index ca05305..e52b8a5 100644
--- a/linux_mtd.c
+++ b/linux_mtd.c
@@ -175,7 +175,7 @@
 
 static int linux_mtd_probe(struct flashctx *flash)
 {
-	struct linux_mtd_data *data = flash->mst->opaque.data;
+	struct linux_mtd_data *data = flash->mst.opaque->data;
 
 	if (data->no_erase)
 		flash->chip->feature_bits |= FEATURE_NO_ERASE;
@@ -190,7 +190,7 @@
 static int linux_mtd_read(struct flashctx *flash, uint8_t *buf,
 			  unsigned int start, unsigned int len)
 {
-	struct linux_mtd_data *data = flash->mst->opaque.data;
+	struct linux_mtd_data *data = flash->mst.opaque->data;
 	unsigned int eb_size = flash->chip->block_erasers[0].eraseblocks[0].size;
 	unsigned int i;
 
@@ -224,7 +224,7 @@
 static int linux_mtd_write(struct flashctx *flash, const uint8_t *buf,
 				unsigned int start, unsigned int len)
 {
-	struct linux_mtd_data *data = flash->mst->opaque.data;
+	struct linux_mtd_data *data = flash->mst.opaque->data;
 	unsigned int chunksize = flash->chip->block_erasers[0].eraseblocks[0].size;
 	unsigned int i;
 
@@ -265,7 +265,7 @@
 static int linux_mtd_erase(struct flashctx *flash,
 			unsigned int start, unsigned int len)
 {
-	struct linux_mtd_data *data = flash->mst->opaque.data;
+	struct linux_mtd_data *data = flash->mst.opaque->data;
 	uint32_t u;
 
 	if (data->no_erase) {
diff --git a/linux_spi.c b/linux_spi.c
index 891c493..37b242d 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -206,7 +206,7 @@
 				  const unsigned char *txbuf,
 				  unsigned char *rxbuf)
 {
-	struct linux_spi_data *spi_data = flash->mst->spi.data;
+	struct linux_spi_data *spi_data = flash->mst.spi->data;
 	int iocontrol_code;
 	struct spi_ioc_transfer msg[2] = {
 		{
@@ -242,7 +242,7 @@
 
 static int linux_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
 {
-	struct linux_spi_data *spi_data = flash->mst->spi.data;
+	struct linux_spi_data *spi_data = flash->mst.spi->data;
 	/* Older kernels use a single buffer for combined input and output
 	   data. So account for longest possible command + address, too. */
 	return spi_read_chunked(flash, buf, start, len, spi_data->max_kernel_buf_size - 5);
@@ -250,7 +250,7 @@
 
 static int linux_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	struct linux_spi_data *spi_data = flash->mst->spi.data;
+	struct linux_spi_data *spi_data = flash->mst.spi->data;
 	/* 5 bytes must be reserved for longest possible command + address. */
 	return spi_write_chunked(flash, buf, start, len, spi_data->max_kernel_buf_size - 5);
 }
diff --git a/memory_bus.c b/memory_bus.c
index ff6799e..365c53c 100644
--- a/memory_bus.c
+++ b/memory_bus.c
@@ -24,8 +24,8 @@
 					 uintptr_t phys_addr, size_t len)
 {
 	void *ret;
-	if (flash->mst->par.map_flash)
-		ret = flash->mst->par.map_flash(descr, phys_addr, len);
+	if (flash->mst.par->map_flash)
+		ret = flash->mst.par->map_flash(descr, phys_addr, len);
 	else
 		ret = fallback_map(descr, phys_addr, len);
 	msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
@@ -35,8 +35,8 @@
 
 static void programmer_unmap_flash_region(const struct flashctx *flash, void *virt_addr, size_t len)
 {
-	if (flash->mst->par.unmap_flash)
-		flash->mst->par.unmap_flash(virt_addr, len);
+	if (flash->mst.par->unmap_flash)
+		flash->mst.par->unmap_flash(virt_addr, len);
 	else
 		fallback_unmap(virt_addr, len);
 	msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
diff --git a/opaque.c b/opaque.c
index 72bb131..eacc09f 100644
--- a/opaque.c
+++ b/opaque.c
@@ -28,22 +28,22 @@
 
 int probe_opaque(struct flashctx *flash)
 {
-	return flash->mst->opaque.probe(flash);
+	return flash->mst.opaque->probe(flash);
 }
 
 int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
 {
-	return flash->mst->opaque.read(flash, buf, start, len);
+	return flash->mst.opaque->read(flash, buf, start, len);
 }
 
 int write_opaque(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	return flash->mst->opaque.write(flash, buf, start, len);
+	return flash->mst.opaque->write(flash, buf, start, len);
 }
 
 int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen)
 {
-	return flash->mst->opaque.erase(flash, blockaddr, blocklen);
+	return flash->mst.opaque->erase(flash, blockaddr, blocklen);
 }
 
 int register_opaque_master(const struct opaque_master *mst, void *data)
diff --git a/parallel.c b/parallel.c
index fb3def8..abed345 100644
--- a/parallel.c
+++ b/parallel.c
@@ -24,43 +24,43 @@
 
 void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
 {
-	flash->mst->par.chip_writeb(flash, val, addr);
+	flash->mst.par->chip_writeb(flash, val, addr);
 }
 
 void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
 {
-	flash->mst->par.chip_writew(flash, val, addr);
+	flash->mst.par->chip_writew(flash, val, addr);
 }
 
 void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
 {
-	flash->mst->par.chip_writel(flash, val, addr);
+	flash->mst.par->chip_writel(flash, val, addr);
 }
 
 void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
 {
-	flash->mst->par.chip_writen(flash, buf, addr, len);
+	flash->mst.par->chip_writen(flash, buf, addr, len);
 }
 
 uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
 {
-	return flash->mst->par.chip_readb(flash, addr);
+	return flash->mst.par->chip_readb(flash, addr);
 }
 
 uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
 {
-	return flash->mst->par.chip_readw(flash, addr);
+	return flash->mst.par->chip_readw(flash, addr);
 }
 
 uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
 {
-	return flash->mst->par.chip_readl(flash, addr);
+	return flash->mst.par->chip_readl(flash, addr);
 }
 
 void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
 		size_t len)
 {
-	flash->mst->par.chip_readn(flash, buf, addr, len);
+	flash->mst.par->chip_readn(flash, buf, addr, len);
 }
 
 int register_par_master(const struct par_master *mst, const enum chipbustype buses,
diff --git a/pickit2_spi.c b/pickit2_spi.c
index a7b658e..9a0691e 100644
--- a/pickit2_spi.c
+++ b/pickit2_spi.c
@@ -202,7 +202,7 @@
 				     const unsigned char *writearr, unsigned char *readarr)
 {
 	const unsigned int total_packetsize = writecnt + readcnt + 20;
-	struct pickit2_spi_data *pickit2_data = flash->mst->spi.data;
+	struct pickit2_spi_data *pickit2_data = flash->mst.spi->data;
 
 	/* Maximum number of bytes per transaction (including command overhead) is 64. Lets play it safe
 	 * and always assume the worst case scenario of 20 bytes command overhead.
diff --git a/sb600spi.c b/sb600spi.c
index 41496a5..8918ea4 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -193,14 +193,14 @@
 /* Check the number of bytes to be transmitted and extract opcode. */
 static int check_readwritecnt(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt)
 {
-	unsigned int maxwritecnt = flash->mst->spi.max_data_write + 3;
+	unsigned int maxwritecnt = flash->mst.spi->max_data_write + 3;
 	if (writecnt > maxwritecnt) {
 		msg_pinfo("%s: SPI controller can not send %d bytes, it is limited to %d bytes\n",
 			  __func__, writecnt, maxwritecnt);
 		return SPI_INVALID_LENGTH;
 	}
 
-	unsigned int maxreadcnt = flash->mst->spi.max_data_read;
+	unsigned int maxreadcnt = flash->mst.spi->max_data_read;
 	if (readcnt > maxreadcnt) {
 		msg_pinfo("%s: SPI controller can not receive %d bytes, it is limited to %d bytes\n",
 			  __func__, readcnt, maxreadcnt);
diff --git a/spi.c b/spi.c
index 1c1586e..296e8df 100644
--- a/spi.c
+++ b/spi.c
@@ -30,13 +30,13 @@
 		     unsigned int readcnt, const unsigned char *writearr,
 		     unsigned char *readarr)
 {
-	return flash->mst->spi.command(flash, writecnt, readcnt, writearr,
+	return flash->mst.spi->command(flash, writecnt, readcnt, writearr,
 				       readarr);
 }
 
 int spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds)
 {
-	return flash->mst->spi.multicommand(flash, cmds);
+	return flash->mst.spi->multicommand(flash, cmds);
 }
 
 int default_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
@@ -74,7 +74,7 @@
 int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
 		     unsigned int len)
 {
-	unsigned int max_data = flash->mst->spi.max_data_read;
+	unsigned int max_data = flash->mst.spi->max_data_read;
 	if (max_data == MAX_DATA_UNSPECIFIED) {
 		msg_perr("%s called, but SPI read chunk size not defined on this hardware.\n"
 			 "Please report a bug at flashprog@flashprog.org\n", __func__);
@@ -85,7 +85,7 @@
 
 int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	unsigned int max_data = flash->mst->spi.max_data_write;
+	unsigned int max_data = flash->mst.spi->max_data_write;
 	if (max_data == MAX_DATA_UNSPECIFIED) {
 		msg_perr("%s called, but SPI write chunk size not defined on this hardware.\n"
 			 "Please report a bug at flashprog@flashprog.org\n", __func__);
@@ -105,7 +105,7 @@
 		   o multi-die 4-byte-addressing chips,
 		   o dediprog that has a protocol limit of 32MiB-512B. */
 		to_read = min(ALIGN_DOWN(start + 16*MiB, 16*MiB) - start, len);
-		ret = flash->mst->spi.read(flash, buf, start, to_read);
+		ret = flash->mst.spi->read(flash, buf, start, to_read);
 		if (ret)
 			return ret;
 	}
@@ -121,13 +121,13 @@
 /* real chunksize is up to 256, logical chunksize is 256 */
 int spi_chip_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	return flash->mst->spi.write_256(flash, buf, start, len);
+	return flash->mst.spi->write_256(flash, buf, start, len);
 }
 
 int spi_aai_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
 {
-	if (flash->mst->spi.write_aai)
-		return flash->mst->spi.write_aai(flash, buf, start, len);
+	if (flash->mst.spi->write_aai)
+		return flash->mst.spi->write_aai(flash, buf, start, len);
 	return default_spi_write_aai(flash, buf, start, len);
 }