On 7/22/09 4:17 PM, Carl-Daniel Hailfinger wrote:
Replace most of the switch cases in the spi code with lookup on a struct instead. This brings the SPI code in line with the generic programmer infrastructure.
This patch is a reworked version of a patch by Jakob Bornecrantz.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
I like this idea.
Acked-by: Stefan Reinauer stepan@coresystems.de
Index: flashrom-spi_programmer_struct/flash.h
--- flashrom-spi_programmer_struct/flash.h (Revision 656) +++ flashrom-spi_programmer_struct/flash.h (Arbeitskopie) @@ -420,8 +420,18 @@ 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);
/* Optimized functions for this programmer */
int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
int (*write_256)(struct flashchip *flash, uint8_t *buf);
+};
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 +462,9 @@ 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); @@ -477,6 +490,7 @@ const unsigned char *writearr, unsigned char *readarr); int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ich_spi_write_256(struct flashchip *flash, uint8_t * buf); +int ich_spi_send_multicommand(struct spi_command *spicommands);
/* it87spi.c */ extern char *it87opts; Index: flashrom-spi_programmer_struct/spi.c =================================================================== --- flashrom-spi_programmer_struct/spi.c (Revision 656) +++ flashrom-spi_programmer_struct/spi.c (Arbeitskopie) @@ -32,61 +32,125 @@
void spi_prettyprint_status_register(struct flashchip *flash);
+const struct spi_programmer spi_programmer[] = {
- { /* SPI_CONTROLLER_NONE */
.command = NULL,
.multicommand = NULL,
.read = NULL,
.write_256 = NULL,
- },
- { /* SPI_CONTROLLER_ICH7 */
.command = ich_spi_send_command,
.multicommand = ich_spi_send_multicommand,
.read = ich_spi_read,
.write_256 = ich_spi_write_256,
- },
- { /* SPI_CONTROLLER_ICH9 */
.command = ich_spi_send_command,
.multicommand = ich_spi_send_multicommand,
.read = ich_spi_read,
.write_256 = ich_spi_write_256,
- },
- { /* 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,
- },
- { /* SPI_CONTROLLER_SB600 */
.command = sb600_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = sb600_spi_read,
.write_256 = sb600_spi_write_1,
- },
- { /* SPI_CONTROLLER_VIA */
.command = ich_spi_send_command,
.multicommand = ich_spi_send_multicommand,
.read = ich_spi_read,
.write_256 = ich_spi_write_256,
- },
- { /* SPI_CONTROLLER_WBSIO */
.command = wbsio_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = wbsio_spi_read,
.write_256 = wbsio_spi_write_1,
- },
- { /* SPI_CONTROLLER_FT2232 */
.command = ft2232_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = ft2232_spi_read,
.write_256 = ft2232_spi_write_256,
- },
- { /* SPI_CONTROLLER_DUMMY */
.command = dummy_spi_send_command,
.multicommand = default_spi_send_multicommand,
.read = NULL,
.write_256 = 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__);
- if (!spi_programmer[spi_controller].command) {
fprintf(stderr, "%s called, but SPI is unsupported on this "
"hardware. Please report a bug.\n", __func__);
}return 1;
- return 1;
- return spi_programmer[spi_controller].command(writecnt, readcnt,
writearr, readarr);
}
int spi_send_multicommand(struct spi_command *spicommands) {
- int ret = 0;
- while ((spicommands->writecnt || spicommands->readcnt) && !ret) {
ret = spi_send_command(spicommands->writecnt, spicommands->readcnt,
spicommands->writearr, spicommands->readarr);
/* This awful hack needs to be replaced with a multicommand
* capable ICH/VIA SPI driver.
*/
if ((ret == SPI_INVALID_OPCODE) &&
((spicommands->writearr[0] == JEDEC_WREN) ||
(spicommands->writearr[0] == JEDEC_EWSR))) {
switch (spi_controller) {
case SPI_CONTROLLER_ICH7:
case SPI_CONTROLLER_ICH9:
case SPI_CONTROLLER_VIA:
printf_debug(" due to SPI master limitation, ignoring"
" and hoping it will be run as PREOP\n");
ret = 0;
default:
break;
}
}
spicommands++;
- if (!spi_programmer[spi_controller].multicommand) {
fprintf(stderr, "%s called, but SPI is unsupported on this "
"hardware. Please report a bug.\n", __func__);
}return 1;
- return ret;
- return spi_programmer[spi_controller].multicommand(spicommands);
}
+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,
- }, {
.writecnt = 0,
.writearr = NULL,
.readcnt = 0,
.readarr = NULL,
- }};
- return spi_send_multicommand(cmd);
+}
+int default_spi_send_multicommand(struct spi_command *spicommands) +{
- int result = 0;
- while ((spicommands->writecnt || spicommands->readcnt) && !result) {
result = spi_send_command(spicommands->writecnt, spicommands->readcnt,
spicommands->writearr, spicommands->readarr);
- }
- return result;
+}
static int spi_rdid(unsigned char *readarr, int bytes) { const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID }; @@ -298,18 +362,18 @@ uint8_t spi_read_status_register(void) { const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
/* FIXME: No workarounds for driver/hardware bugs in generic code. */ 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. */
- if (spi_controller == SPI_CONTROLLER_SB600) { /* FIXME */
return sb600_read_status_register();/* Workaround for SB600 hardware bug. Can be killed later. */
- } else {
ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
if (ret)
}printf_debug("RDSR failed!\n");
ret = spi_send_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
if (ret)
printf_debug("RDSR failed!\n");
return readarr[0];
} @@ -875,26 +939,13 @@
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:
printf_debug
("%s called, but no SPI chipset/strapping detected\n",
__FUNCTION__);
- if (!spi_programmer[spi_controller].read) {
fprintf(stderr, "%s called, but SPI read is unsupported on this"
" hardware. Please report a bug.\n", __func__);
}return 1;
- return 1;
- return spi_programmer[spi_controller].read(flash, buf, start, len);
}
/* @@ -924,26 +975,13 @@ */ 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:
printf_debug
("%s called, but no SPI chipset/strapping detected\n",
__FUNCTION__);
- if (!spi_programmer[spi_controller].write_256) {
fprintf(stderr, "%s called, but SPI page write is unsupported "
" on this hardware. Please report a bug.\n", __func__);
}return 1;
- return 1;
- return spi_programmer[spi_controller].write_256(flash, buf);
}
uint32_t spi_get_valid_read_addr(void) Index: flashrom-spi_programmer_struct/ichspi.c =================================================================== --- flashrom-spi_programmer_struct/ichspi.c (Revision 656) +++ flashrom-spi_programmer_struct/ichspi.c (Arbeitskopie) @@ -742,3 +742,23 @@
return result; }
+int ich_spi_send_multicommand(struct spi_command *spicommands) +{
- int ret = 0;
- while ((spicommands->writecnt || spicommands->readcnt) && !ret) {
ret = ich_spi_send_command(spicommands->writecnt, spicommands->readcnt,
spicommands->writearr, spicommands->readarr);
/* This awful hack needs to be smarter.
*/
if ((ret == SPI_INVALID_OPCODE) &&
((spicommands->writearr[0] == JEDEC_WREN) ||
(spicommands->writearr[0] == JEDEC_EWSR))) {
printf_debug(" due to SPI master limitation, ignoring"
" and hoping it will be run as PREOP\n");
ret = 0;
}
spicommands++;
- }
- return ret;
+}