diff --git a/dediprog.c b/dediprog.c index cdd27b099..9559eed41 100644 --- a/dediprog.c +++ b/dediprog.c @@ -31,6 +31,9 @@ static usb_dev_handle *dediprog_handle; static int dediprog_firmwareversion; static int dediprog_endpoint; +#define DEDI_SPI_CMD_PAGEWRITE 0x1 +#define DEDI_SPI_CMD_AAIWRITE 0x4 + #if 0 /* Might be useful for other pieces of code as well. */ static void print_hex(void *buf, size_t len) @@ -307,13 +310,15 @@ static int dediprog_spi_read(struct flashctx *flash, uint8_t *buf, return 0; } -/* Bulk write interface, will write multiple page_size byte chunks aligned to page_size bytes. - * @start start address - * @len length - * @return 0 on success, 1 on failure +/* Bulk write interface, will write multiple chunksize byte chunks aligned to chunksize bytes. + * @chunksize length of data chunks, only 256 supported by now + * @start start address + * @len length + * @dedi_spi_cmd dediprog specific write command for spi bus + * @return 0 on success, 1 on failure */ -static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, - unsigned int start, unsigned int len) +static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigned int chunksize, + unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { int ret; unsigned int i; @@ -321,14 +326,21 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, * chunksize is the real data size per USB bulk transfer. The remaining * space in a USB bulk transfer must be filled with 0xff padding. */ - const unsigned int chunksize = flash->page_size; const unsigned int count = len / chunksize; - const char count_and_chunk[] = {count & 0xff, - (count >> 8) & 0xff, - chunksize & 0xff, - (chunksize >> 8) & 0xff}; + const char count_and_cmd[] = {count & 0xff, (count >> 8) & 0xff, 0x00, dedi_spi_cmd}; char usbbuf[512]; + /* + * We should change this check to + * chunksize > 512 + * once we know how to handle different chunk sizes. + */ + if (chunksize != 256) { + msg_perr("%s: Chunk sizes other than 256 bytes are unsupported, chunksize=%u!\n" + "Please report a bug at flashrom@flashrom.org\n", __func__, chunksize); + return 1; + } + if ((start % chunksize) || (len % chunksize)) { msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug " "at flashrom@flashrom.org\n", __func__, start, len); @@ -341,10 +353,9 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, /* Command Write SPI Bulk. No idea which write command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, - start / 0x10000, (char *)count_and_chunk, - sizeof(count_and_chunk), DEFAULT_TIMEOUT); - if (ret != sizeof(count_and_chunk)) { + ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, + (char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); + if (ret != sizeof(count_and_cmd)) { msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, usb_strerror()); return 1; @@ -366,8 +377,8 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, return 0; } -static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, - unsigned int start, unsigned int len) +static int dediprog_spi_write(struct flashctx *flash, uint8_t *buf, + unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { int ret; const unsigned int chunksize = flash->page_size; @@ -376,6 +387,13 @@ static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, dediprog_set_leds(PASS_OFF|BUSY_ON|ERROR_OFF); + if (chunksize != 256) { + msg_pdbg("Page sizes other than 256 bytes are unsupported as " + "we don't know how dediprog\nhandles them.\n"); + /* Write everything like it was residue. */ + residue = len; + } + if (residue) { msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n", start, residue); @@ -389,8 +407,7 @@ static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, /* Round down. */ bulklen = (len - residue) / chunksize * chunksize; - ret = dediprog_spi_bulk_write(flash, buf + residue, start + residue, - bulklen); + ret = dediprog_spi_bulk_write(flash, buf + residue, chunksize, start + residue, bulklen, dedi_spi_cmd); if (ret) { dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON); return ret; @@ -412,6 +429,16 @@ static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, return 0; } +static int dediprog_spi_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) +{ + return dediprog_spi_write(flash, buf, start, len, DEDI_SPI_CMD_PAGEWRITE); +} + +static int dediprog_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) +{ + return dediprog_spi_write(flash, buf, start, len, DEDI_SPI_CMD_AAIWRITE); +} + static int dediprog_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, @@ -717,7 +744,7 @@ static const struct spi_programmer spi_programmer_dediprog = { .multicommand = default_spi_send_multicommand, .read = dediprog_spi_read, .write_256 = dediprog_spi_write_256, - .write_aai = default_spi_write_aai, + .write_aai = dediprog_spi_write_aai, }; static int dediprog_shutdown(void *data)