[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