[flashrom] [PATCH] Support Dediprog SF100 bulk read

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Tue Nov 16 00:51:32 CET 2010


New patch, incorporates the latest reverse engineering results.

Might even work for plain reads. Verify and write will be corrupt
because that code path is not handled yet.
Tests with offset=0x1, offset=0x200 and offset=0x10000 would be
appreciated. The resulting images should be shifted by 1, 512 and
65536 bytes.

Support Dediprog SF100 bulk read.

Packet size is 512 bytes. Depending on your USB hardware and the
Dediprog firmware version, this may not work at all.
Add lots of error checking where it was missing before.
Untested, experimental, may hang/crash the programmer.

Read tests of random images are appreciated.

Please note that flashrom needs full access permissions for the USB
device.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Index: flashrom-dediprog_read_bulk/dediprog.c
===================================================================
--- flashrom-dediprog_read_bulk/dediprog.c	(Revision 1232)
+++ flashrom-dediprog_read_bulk/dediprog.c	(Arbeitskopie)
@@ -27,6 +27,7 @@
 
 #define DEFAULT_TIMEOUT 3000
 static usb_dev_handle *dediprog_handle;
+static int dediprog_endpoint;
 
 #if 0
 /* Might be useful for other pieces of code as well. */
@@ -150,9 +151,47 @@
 
 int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
+	int ret;
+	int i;
+	const int chunksize = 0x200; /* Other sizes will NOT work at all. */
+	int count = flash->total_size * 1024 / chunksize;
+	/* Guessed. */
+	const char count_and_chunk[] = {
+				count & 0xff,
+				(count >> 8) & 0xff,
+				chunksize & 0xff,
+				(chunksize >> 8) & 0xff};
+	char tmpbuf[chunksize]; /* FIXME: Read directly into buf? */
+	int offset = 0; /* start address. */
+
 	msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len);
-	/* Chosen read length is 16 bytes for now. */
-	return spi_read_chunked(flash, buf, start, len, 16);
+	if ((len != flash->total_size * 1024) || (start != 0)) {
+		msg_perr("Only a full chip read is supported for now. Wanted "
+			 "start=%i, length=%i\n.", start, len);
+		return 1;
+	}
+
+	/* Command Read SPI Bulk. No idea which read command is used on the
+	 * SPI side.
+	 */
+	ret = usb_control_msg(dediprog_handle, 0x42, 0x20, offset % 0x10000, offset / 0x10000, (char *)count_and_chunk, sizeof(count_and_chunk), DEFAULT_TIMEOUT);
+	if (ret != sizeof(count_and_chunk)) {
+		msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret,
+			 usb_strerror());
+		return 1;
+	}
+
+	for (i = 0; i < count; i++) {
+		ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint, tmpbuf, chunksize, DEFAULT_TIMEOUT);
+		memcpy(buf + i * chunksize, tmpbuf, chunksize);
+		if (ret != chunksize) {
+			msg_perr("SPI bulk read %i failed, expected %i, got %i "
+				 "%s!\n", i, chunksize, ret, usb_strerror());
+			return 1;
+		}
+	}
+
+	return 0;
 }
 
 int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,
@@ -345,6 +384,7 @@
 	struct usb_device *dev;
 	char *voltage;
 	int millivolt = 3500;
+	int ret;
 
 	msg_pspew("%s\n", __func__);
 
@@ -371,8 +411,23 @@
 		 dev->descriptor.idVendor,
 		 dev->descriptor.idProduct);
 	dediprog_handle = usb_open(dev);
-	usb_set_configuration(dediprog_handle, 1);
-	usb_claim_interface(dediprog_handle, 0);
+	ret = usb_set_configuration(dediprog_handle, 1);
+	if (ret < 0) {
+		msg_perr("Could not set USB device configuration: %i %s\n",
+			 ret, usb_strerror());
+		if (usb_close(dediprog_handle))
+			msg_perr("Could not close USB device!\n");
+		return 1;
+	}
+	ret = usb_claim_interface(dediprog_handle, 0);
+	if (ret < 0) {
+		msg_perr("Could not claim USB device interface %i: %i %s\n",
+			 0, ret, usb_strerror());
+		if (usb_close(dediprog_handle))
+			msg_perr("Could not close USB device!\n");
+		return 1;
+	}
+	dediprog_endpoint = 2;
 	/* URB 6. Command A. */
 	if (dediprog_command_a())
 		return 1;
@@ -461,8 +516,12 @@
 	if (dediprog_set_spi_voltage(0x0))
 		return 1;
 
+	if (usb_release_interface(dediprog_handle, 0)) {
+		msg_perr("Could not release USB interface!\n");
+		return 1;
+	}
 	if (usb_close(dediprog_handle)) {
-		msg_perr("Couldn't close USB device!\n");
+		msg_perr("Could not close USB device!\n");
 		return 1;
 	}
 	return 0;



-- 
http://www.hailfinger.org/





More information about the flashrom mailing list