diff --git a/flash.h b/flash.h
index 9e6ca6c..2cd5e93 100644
--- a/flash.h
+++ b/flash.h
@@ -420,8 +420,24 @@ struct spi_command {
 	const unsigned char *writearr;
 	unsigned char *readarr;
 };
+struct spi_programmer {
+	int (*command)(unsigned int writecnt, unsigned int readcnt,
+		   const unsigned char *writearr, unsigned char *readarr);
+	int (*multicommand)(struct spi_command *spicommands);
+
+	/*
+	 * XXX Special work around commands.
+	 *
+	 * These should be removed later on and instead we should filter the
+	 * command stream and apply the work arounds there.
+	 */
+	int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
+	int (*write_256)(struct flashchip *flash, uint8_t *buf);
+	uint8_t (*read_status_register)(void);
+};
 
 extern enum spi_controller spi_controller;
+extern const struct spi_programmer spi_programmer[];
 extern void *spibar;
 int probe_spi_rdid(struct flashchip *flash);
 int probe_spi_rdid4(struct flashchip *flash);
@@ -452,6 +468,9 @@ int spi_nbyte_read(int address, uint8_t *bytes, int len);
 int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
 int spi_aai_write(struct flashchip *flash, uint8_t *buf);
 uint32_t spi_get_valid_read_addr(void);
+int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+			     const unsigned char *writearr, unsigned char *readarr);
+int default_spi_send_multicommand(struct spi_command *spicommands);
 
 /* 82802ab.c */
 int probe_82802ab(struct flashchip *flash);
diff --git a/spi.c b/spi.c
index 16dfe36..0601fd8 100644
--- a/spi.c
+++ b/spi.c
@@ -32,41 +32,91 @@ void *spibar = NULL;
 
 void spi_prettyprint_status_register(struct flashchip *flash);
 
+const struct spi_programmer spi_programmer[] = {
+	{ /* SPI_CONTROLLER_NONE */
+		.command = dummy_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = NULL,
+		.write_256 = NULL,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_ICH7 */
+		.command = ich_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = ich_spi_read,
+		.write_256 = ich_spi_write_256,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_ICH9 */
+		.command = ich_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = ich_spi_read,
+		.write_256 = ich_spi_write_256,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_IT87XX */
+		.command = it8716f_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = it8716f_spi_chip_read,
+		.write_256 = it8716f_spi_chip_write_256,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_SB600 */
+		.command = sb600_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = sb600_spi_read,
+		.write_256 = sb600_spi_write_1,
+		.read_status_register = sb600_read_status_register,
+	},
+
+	{ /* SPI_CONTROLLER_VIA */
+		.command = ich_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = ich_spi_read,
+		.write_256 = ich_spi_write_256,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_WBSIO */
+		.command = wbsio_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = wbsio_spi_read,
+		.write_256 = wbsio_spi_write_1,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_FT2232 */
+		.command = ft2232_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = ft2232_spi_read,
+		.write_256 = ft2232_spi_write_256,
+		.read_status_register = NULL,
+	},
+
+	{ /* SPI_CONTROLLER_DUMMY */
+		.command = dummy_spi_send_command,
+		.multicommand = default_spi_send_multicommand,
+		.read = NULL,
+		.write_256 = NULL,
+		.read_status_register = NULL,
+	},
+};
+
+
 int spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
-	switch (spi_controller) {
-	case SPI_CONTROLLER_IT87XX:
-		return it8716f_spi_send_command(writecnt, readcnt, writearr,
-					   readarr);
-	case SPI_CONTROLLER_ICH7:
-	case SPI_CONTROLLER_ICH9:
-	case SPI_CONTROLLER_VIA:
-		return ich_spi_send_command(writecnt, readcnt, writearr, readarr);
-	case SPI_CONTROLLER_SB600:
-		return sb600_spi_send_command(writecnt, readcnt, writearr, readarr);
-	case SPI_CONTROLLER_WBSIO:
-		return wbsio_spi_send_command(writecnt, readcnt, writearr, readarr);
-	case SPI_CONTROLLER_FT2232:
-		return ft2232_spi_send_command(writecnt, readcnt, writearr, readarr);
-	case SPI_CONTROLLER_DUMMY:
-		return dummy_spi_send_command(writecnt, readcnt, writearr, readarr);
-	default:
-		printf_debug
-		    ("%s called, but no SPI chipset/strapping detected\n",
-		     __FUNCTION__);
-	}
-	return 1;
+	return spi_programmer[spi_controller].command(writecnt, readcnt,
+						      writearr, readarr);
 }
 
 int spi_send_multicommand(struct spi_command *spicommands)
 {
-	int res = 0;
-	while ((spicommands->writecnt || spicommands->readcnt) && !res) {
-		res = spi_send_command(spicommands->writecnt, spicommands->readcnt,
-				       spicommands->writearr, spicommands->readarr);
-	}
-	return res;
+	return spi_programmer[spi_controller].multicommand(spicommands);
 }
 
 static int spi_rdid(unsigned char *readarr, int bytes)
@@ -297,15 +347,12 @@ uint8_t spi_read_status_register(void)
 	unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
 	int ret;
 
-	/* Read Status Register */
-	if (spi_controller == SPI_CONTROLLER_SB600) {
-		/* SB600 uses a different way to read status register. */
-		return sb600_read_status_register();
-	} else {
-		ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
-		if (ret)
-			printf_debug("RDSR failed!\n");
-	}
+	if (spi_programmer[spi_controller].read_status_register)
+		return spi_programmer[spi_controller].read_status_register();
+
+	ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
+	if (ret)
+		printf_debug("RDSR failed!\n");
 
 	return readarr[0];
 }
@@ -766,26 +813,14 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
 
 int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-	switch (spi_controller) {
-	case SPI_CONTROLLER_IT87XX:
-		return it8716f_spi_chip_read(flash, buf, start, len);
-	case SPI_CONTROLLER_SB600:
-		return sb600_spi_read(flash, buf, start, len);
-	case SPI_CONTROLLER_ICH7:
-	case SPI_CONTROLLER_ICH9:
-	case SPI_CONTROLLER_VIA:
-		return ich_spi_read(flash, buf, start, len);
-	case SPI_CONTROLLER_WBSIO:
-		return wbsio_spi_read(flash, buf, start, len);
-	case SPI_CONTROLLER_FT2232:
-		return ft2232_spi_read(flash, buf, start, len);
-	default:
+	if (!spi_programmer[spi_controller].read) {
 		printf_debug
 		    ("%s called, but no SPI chipset/strapping detected\n",
 		     __FUNCTION__);
+		return 1;
 	}
 
-	return 1;
+	return spi_programmer[spi_controller].read(flash, buf, start, len);
 }
 
 /*
@@ -816,26 +851,14 @@ int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
  */
 int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
 {
-	switch (spi_controller) {
-	case SPI_CONTROLLER_IT87XX:
-		return it8716f_spi_chip_write_256(flash, buf);
-	case SPI_CONTROLLER_SB600:
-		return sb600_spi_write_1(flash, buf);
-	case SPI_CONTROLLER_ICH7:
-	case SPI_CONTROLLER_ICH9:
-	case SPI_CONTROLLER_VIA:
-		return ich_spi_write_256(flash, buf);
-	case SPI_CONTROLLER_WBSIO:
-		return wbsio_spi_write_1(flash, buf);
-	case SPI_CONTROLLER_FT2232:
-		return ft2232_spi_write_256(flash, buf);
-	default:
+	if (!spi_programmer[spi_controller].write_256) {
 		printf_debug
 		    ("%s called, but no SPI chipset/strapping detected\n",
 		     __FUNCTION__);
+		return 1;
 	}
 
-	return 1;
+	return spi_programmer[spi_controller].write_256(flash, buf);
 }
 
 uint32_t spi_get_valid_read_addr(void)
@@ -878,3 +901,26 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf)
 	spi_write_disable();
 	return 0;
 }
+
+int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
+			     const unsigned char *writearr, unsigned char *readarr)
+{
+	struct spi_command cmd = {
+		.writecnt = writecnt,
+		.readcnt = readcnt,
+		.writearr = writearr,
+		.readarr = readarr,
+	};
+
+	return spi_send_multicommand(&cmd);
+}
+
+int default_spi_send_multicommand(struct spi_command *spicommands)
+{
+	int res = 0;
+	while ((spicommands->writecnt || spicommands->readcnt) && !res) {
+		res = spi_send_command(spicommands->writecnt, spicommands->readcnt,
+				       spicommands->writearr, spicommands->readarr);
+	}
+	return res;
+}
