[flashrom] [PATCH] Add native AAI transfer support to the dediprog driver

Nico Huber nico.huber at secunet.com
Mon Jun 18 11:30:45 CEST 2012


Second try for this patch.

This enables native AAI transfer support in the dediprog driver. The
function to write chunks of data, dediprog_spi_bulk_write(), is reused.
To tell the programmer how to handle the data on the spi bus, a flag in
the fourth byte sent with the usb command is used. The second word was
mistaken for the size of the chunks sent over usb earlier. The third
byte (first of the second word) is now set to zero. This also adds some
checks for the size of data chunks sent over usb.

Signed-off-by: Nico Huber <nico.huber at secunet.com>

Index: dediprog.c
===================================================================
--- dediprog.c	(Revision 1545)
+++ dediprog.c	(Arbeitskopie)
@@ -31,6 +31,9 @@
 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 @@
 	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,20 @@
 	 * 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];
 
+	if (chunksize != 256) {
+		msg_perr("%s: Chunk sizes other than 256 bytes are unsupported, chunksize=%u!\n"
+			 "Please report a bug at flashrom at flashrom.org\n", __func__, chunksize);
+		return 1;
+	}
+	if (chunksize > 512) {
+		msg_perr("%s: Maximum chunk size is 512 bytes, chunksize=%u!\n"
+			 "Please report a bug at flashrom at flashrom.org\n", __func__, chunksize);
+	}
+
 	if ((start % chunksize) || (len % chunksize)) {
 		msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug "
 			 "at flashrom at flashrom.org\n", __func__, start, len);
@@ -341,10 +352,9 @@
 	/* 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 +376,8 @@
 	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 +386,13 @@
 
 	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 +406,7 @@
 
 	/* 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 +428,16 @@
 	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 +743,7 @@
 	.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)




More information about the flashrom mailing list