[flashrom] [PATCH 2/3] fixup! Add SPI support to serprog protocol.
Stefan Tauner
stefan.tauner at student.tuwien.ac.at
Tue Jun 21 22:22:12 CEST 2011
- mostly formatting
- drop the 256 B write limit and set max_data_write to 2^24 in case of 0
- add debug output
Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
serprog-protocol.txt | 1 +
serprog.c | 95 +++++++++++++++++++++++++++++---------------------
2 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/serprog-protocol.txt b/serprog-protocol.txt
index cced0dc..2391aef 100644
--- a/serprog-protocol.txt
+++ b/serprog-protocol.txt
@@ -69,6 +69,7 @@ Additional information of the above commands:
Sending a byte with more than 1 bit set will make the programmer decide among them
on it's own. Bit values as with Q_BUSTYPE.
0x13 (O_SPIOP):
+ Send and receive bytes via SPI.
Maximum slen is Q_WRNMAXLEN result after Q_BUSTYPE returns
only SPI or S_BUSTYPE == SPI is used. Same for rlen and Q_RDNMAXLEN.
This operation is immediate, meaning it doesnt use the operation buffer.
diff --git a/serprog.c b/serprog.c
index d61d0d7..5f2c014 100644
--- a/serprog.c
+++ b/serprog.c
@@ -425,14 +425,15 @@ int serprog_init(void)
if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
msg_perr("Warning: NAK to query supported buses\n");
- c = CHIP_BUSTYPE_NONSPI; /* A reasonable default for now. */
+ c = CHIP_BUSTYPE_NONSPI; /* A reasonable default for now. */
}
buses_supported = c;
/* Check for the minimum operational set of commands. */
if (buses_supported & CHIP_BUSTYPE_SPI) {
uint8_t bt = CHIP_BUSTYPE_SPI;
if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
- msg_perr("Error: SPI operation not supported while the SPI bustype is\n");
+ msg_perr("Error: SPI operation not supported while the "
+ "bustype is SPI\n");
exit(1);
}
/* Success of any of these commands is optional. We dont need
@@ -445,21 +446,20 @@ int serprog_init(void)
v = ((unsigned int)(rbuf[0]) << 0);
v |= ((unsigned int)(rbuf[1]) << 8);
v |= ((unsigned int)(rbuf[2]) << 16);
- /* Limit to 256 because we dont need longer writes. */
- if ((v==0)||(v>256)) {
- v = 256;
- }
+ if (v == 0)
+ v = (1 << 24) - 1; /* SPI-op maximum. */
spi_programmer_serprog.max_data_write = v;
+ msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
}
if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
uint32_t v;
v = ((unsigned int)(rbuf[0]) << 0);
v |= ((unsigned int)(rbuf[1]) << 8);
v |= ((unsigned int)(rbuf[2]) << 16);
- if (v==0) {
- v = (1<<24)-1; /* SPI-op maximum. */
- }
+ if (v == 0)
+ v = (1 << 24) - 1; /* SPI-op maximum. */
spi_programmer_serprog.max_data_read = v;
+ msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
}
bt = buses_supported;
sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
@@ -468,12 +468,14 @@ int serprog_init(void)
if (buses_supported & CHIP_BUSTYPE_NONSPI) {
if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
- msg_perr("Error: Initialize operation buffer not supported\n");
+ msg_perr("Error: Initialize operation buffer "
+ "not supported\n");
exit(1);
}
if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
- msg_perr("Error: Write to opbuf: delay not supported\n");
+ msg_perr("Error: Write to opbuf: "
+ "delay not supported\n");
exit(1);
}
@@ -483,14 +485,15 @@ int serprog_init(void)
msg_perr("Error: Single byte read not supported\n");
exit(1);
}
- /* This could be translated to single byte reads (if missing), *
- * but now we dont support that. */
+ /* This could be translated to single byte reads (if missing),
+ * but now we dont support that. */
if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
msg_perr("Error: Read n bytes not supported\n");
exit(1);
}
if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
- msg_perr("Error: Write to opbuf: write byte not supported\n");
+ msg_perr("Error: Write to opbuf: "
+ "write byte not supported\n");
exit(1);
}
@@ -502,27 +505,29 @@ int serprog_init(void)
sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
if (!sp_max_write_n) {
- sp_max_write_n = (1<<24);
+ sp_max_write_n = (1 << 24);
}
- msg_pdbg(MSGHEADER "Maximum write-n length %d\n",
- sp_max_write_n);
+ msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
+ sp_max_write_n);
sp_write_n_buf = malloc(sp_max_write_n);
if (!sp_write_n_buf) {
- msg_perr("Error: cannot allocate memory for Write-n buffer\n");
+ msg_perr("Error: cannot allocate memory for "
+ "Write-n buffer\n");
exit(1);
}
sp_write_n_bytes = 0;
}
- if ((sp_check_commandavail(S_CMD_Q_RDNMAXLEN))
- &&((sp_docommand(S_CMD_Q_RDNMAXLEN,0,NULL, 3, rbuf) == 0))) {
+ if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
+ (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
- msg_pdbg(MSGHEADER "Maximum read-n length %d\n",
- sp_max_read_n ? sp_max_read_n : (1<<24));
+ msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
+ sp_max_read_n ? sp_max_read_n : (1 << 24));
} else {
- msg_pdbg(MSGHEADER "Maximum read-n length not reported\n");
+ msg_pdbg(MSGHEADER "Maximum read-n length "
+ "not reported\n");
sp_max_read_n = 0;
}
@@ -544,7 +549,8 @@ int serprog_init(void)
if (sp_check_commandavail(S_CMD_O_INIT)) {
/* This would be inconsistent. */
if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
- msg_perr("Error: Execute operation buffer not supported\n");
+ msg_perr("Error: Execute operation buffer not "
+ "supported\n");
exit(1);
}
@@ -553,11 +559,13 @@ int serprog_init(void)
exit(1);
}
- if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2, &sp_device_opbuf_size)) {
- msg_perr("Warning: NAK to query operation buffer size\n");
+ if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
+ &sp_device_opbuf_size)) {
+ msg_perr("Warning: NAK to query operation buffer "
+ "size\n");
}
msg_pdbg(MSGHEADER "operation buffer size %d\n",
- sp_device_opbuf_size);
+ sp_device_opbuf_size);
}
sp_prev_was_write = 0;
@@ -757,38 +765,45 @@ void serprog_delay(int delay)
}
int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr)
+ const unsigned char *writearr,
+ unsigned char *readarr)
{
unsigned char *parmbuf;
int ret;
msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
sp_execute_opbuf();
- parmbuf = malloc(writecnt+6);
- if (!parmbuf) sp_die("Error: cannot malloc SPI send param buffer");
+ parmbuf = malloc(writecnt + 6);
+ if (!parmbuf)
+ sp_die("Error: cannot malloc SPI send param buffer");
parmbuf[0] = (writecnt >> 0) & 0xFF;
parmbuf[1] = (writecnt >> 8) & 0xFF;
parmbuf[2] = (writecnt >> 16) & 0xFF;
parmbuf[3] = (readcnt >> 0) & 0xFF;
parmbuf[4] = (readcnt >> 8) & 0xFF;
parmbuf[5] = (readcnt >> 16) & 0xFF;
- memcpy(parmbuf+6, writearr, writecnt);
- ret = sp_docommand(S_CMD_O_SPIOP, writecnt+6, parmbuf, readcnt, readarr);
+ memcpy(parmbuf + 6, writearr, writecnt);
+ ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
+ readarr);
free(parmbuf);
return ret;
}
+/* FIXME: This function is optimized so that it does not split each
+ * transaction into chip page_size long blocks unnecessarily like
+ * spi_read_chunked. When spi_read_chunked is fixed this method can be
+ * removed. */
int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
{
int i;
- int max_read = spi_programmer_serprog.max_data_read;
- /* This function is optimized in that it doesnt split the read into
- chip page_size length blocks unnecessarily. */
- for(i=0;i<len;) {
- int rv;
- int len_left = ((len-i)>max_read) ? max_read : (len-i);
- if ((rv=spi_nbyte_read(start+i, buf+i, len_left))) return rv;
- i += len_left;
+ const int max_read = spi_programmer_serprog.max_data_read;
+ for(i = 0; i < len; ) {
+ int ret;
+ int cur_len = min(max_read, (len - i));
+ ret = spi_nbyte_read(start + i, buf + i, cur_len);
+ if (ret)
+ return ret;
+ i += cur_len;
}
return 0;
}
--
1.7.1
More information about the flashrom
mailing list