<font size="2"><font face="arial,helvetica,sans-serif">hi carl,</font></font><div><font size="2"><font face="arial,helvetica,sans-serif">  i tried your patch, the read seems very good. But i found that the readback.rom is not exactly the same as i flashed with the factory tools.</font></font></div>
<div><font size="2"><font face="arial,helvetica,sans-serif">but that does not mean that flashrom read comand is not correct, because i had faced that the factory tools also could cause some byte flashed</font></font></div>
<div><font size="2"><font face="arial,helvetica,sans-serif">incorrectly.</font></font></div><div><font size="2"><font face="arial,helvetica,sans-serif">the log is attached which i test with my SF100.<br clear="all"></font></font><div>
Best wishes</div>Wang Qing Pei <br>Phone: 86+18930528086<br>
<br><br><div class="gmail_quote">On Fri, Nov 12, 2010 at 12:29 PM, Carl-Daniel Hailfinger <span dir="ltr"><<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">New version: Even more guesswork, and support for partial reads.<br>
If the tests of the previous version have the results I hope for, this<br>
version will allow partial reads without any regressions.<br>
<div class="im"><br>
On 12.11.2010 03:29, Carl-Daniel Hailfinger wrote:<br>
> New version: More guesswork, split read chunk size from bulk transfer<br>
> buffer size.<br>
><br>
<br>
</div>Support bulk read on Dediprog SF100.<br>
Should result in native speed for plain read and erase.<br>
Should result in a measurable speedup for writes due to a fast verify.<br>
<br>
Read tests with chunksize = 0x20 would be appreciated.<br>
Read tests with chunksize = 0x1 would be appreciated.<br>
Both should be a lot slower, but still yield correct images.<br>
<div class="im"><br>
Packet size is 512 bytes. Depending on your USB hardware and the<br>
Dediprog firmware version, this may not work at all.<br>
Add lots of error checking where it was missing before.<br>
</div>Somewhat tested, experimental, may hang/crash the programmer.<br>
<br>
Write tests of random images are appreciated.<br>
<div class="im"><br>
Please note that flashrom needs full access permissions for the USB<br>
device.<br>
<br>
Signed-off-by: Carl-Daniel Hailfinger <<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>><br>
<br>
Index: flashrom-dediprog_read_bulk/dediprog.c<br>
===================================================================<br>
--- flashrom-dediprog_read_bulk/dediprog.c      (Revision 1232)<br>
+++ flashrom-dediprog_read_bulk/dediprog.c      (Arbeitskopie)<br>
@@ -27,6 +27,7 @@<br>
<br>
 #define DEFAULT_TIMEOUT 3000<br>
 static usb_dev_handle *dediprog_handle;<br>
+static int dediprog_endpoint;<br>
<br>
 #if 0<br>
 /* Might be useful for other pieces of code as well. */<br>
</div>@@ -150,9 +151,63 @@<br>
<div class="im"><br>
 int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)<br>
 {<br>
</div>+       int ret = 0;<br>
<div class="im">+       int i;<br>
+       int chunksize = 0x200; /* 512, other sizes may not work at all. */<br>
+       const int bulktransfer_chunksize = 0x200; /* 512, other sizes may not work at all. */<br>
</div>+       /* count only covers full chunksize blocks. */<br>
+       int count = (len - start % chunksize) / chunksize;<br>
<div class="im">+       /* Guessed. */<br>
+       const char count_and_chunk[] = {<br>
+                               count & 0xff,<br>
+                               (count >> 8) & 0xff,<br>
+                               chunksize & 0xff,<br>
+                               (chunksize >> 8) & 0xff};<br>
</div>+       int residue = start % chunksize ? chunksize - start % chunksize : 0;<br>
+       int bulkoffset = (start + residue) / chunksize;<br>
<div class="im">+       char tmpbuf[bulktransfer_chunksize];<br>
+<br>
        msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len);<br>
-       /* Chosen read length is 16 bytes for now. */<br>
-       return spi_read_chunked(flash, buf, start, len, 16);<br>
</div>+       if (residue) {<br>
+               msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",<br>
+                        start, residue);<br>
+               ret = spi_read_chunked(flash, buf, start, residue, 16);<br>
+       }<br>
+       if (ret)<br>
+               return ret;<br>
<div class="im">+<br>
+       /* Command Read SPI Bulk. No idea which read command is used on the<br>
+        * SPI side. offset is a total guess, I only saw it being 0 everywhere.<br>
+        */<br>
</div>+       ret = usb_control_msg(dediprog_handle, 0x42, 0x20, 0x0000, bulkoffset, (char *)count_and_chunk, sizeof(count_and_chunk), DEFAULT_TIMEOUT);<br>
<div class="im">+       if (ret != sizeof(count_and_chunk)) {<br>
+               msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret,<br>
+                        usb_strerror());<br>
+               return 1;<br>
+       }<br>
+<br>
+       for (i = 0; i < count; i++) {<br>
+               /* Crude progress bar, enable with -VV */<br>
+               msg_pspew(".");<br>
+               ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint, tmpbuf, bulktransfer_chunksize, DEFAULT_TIMEOUT);<br>
</div>+               memcpy(buf + residue + i * chunksize, tmpbuf, chunksize);<br>
<div class="im">+               if (ret != chunksize) {<br>
+                       msg_perr("SPI bulk read %i failed, expected %i, got %i "<br>
+                                "%s!\n", i, chunksize, ret, usb_strerror());<br>
+                       return 1;<br>
+               }<br>
+       }<br>
</div>+       len -= residue + i * chunksize;<br>
+       if (len) {<br>
+               msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",<br>
+                        start, len);<br>
+               ret = spi_read_chunked(flash, buf + residue + i * chunksize,<br>
+                                      start + residue + i * chunksize, len, 16);<br>
+       }<br>
+       if (ret)<br>
+               return ret;<br>
<div class="im">+<br>
+       return 0;<br>
 }<br>
<br>
 int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt,<br>
</div>@@ -345,6 +400,7 @@<br>
<div class="im">        struct usb_device *dev;<br>
        char *voltage;<br>
        int millivolt = 3500;<br>
+       int ret;<br>
<br>
        msg_pspew("%s\n", __func__);<br>
<br>
</div>@@ -371,8 +427,23 @@<br>
<div class="im">                 dev->descriptor.idVendor,<br>
                 dev->descriptor.idProduct);<br>
        dediprog_handle = usb_open(dev);<br>
-       usb_set_configuration(dediprog_handle, 1);<br>
-       usb_claim_interface(dediprog_handle, 0);<br>
+       ret = usb_set_configuration(dediprog_handle, 1);<br>
+       if (ret < 0) {<br>
+               msg_perr("Could not set USB device configuration: %i %s\n",<br>
+                        ret, usb_strerror());<br>
+               if (usb_close(dediprog_handle))<br>
+                       msg_perr("Could not close USB device!\n");<br>
+               return 1;<br>
+       }<br>
+       ret = usb_claim_interface(dediprog_handle, 0);<br>
+       if (ret < 0) {<br>
+               msg_perr("Could not claim USB device interface %i: %i %s\n",<br>
+                        0, ret, usb_strerror());<br>
+               if (usb_close(dediprog_handle))<br>
+                       msg_perr("Could not close USB device!\n");<br>
+               return 1;<br>
+       }<br>
+       dediprog_endpoint = 2;<br>
        /* URB 6. Command A. */<br>
        if (dediprog_command_a())<br>
                return 1;<br>
</div>@@ -461,8 +532,12 @@<br>
<div><div></div><div class="h5">        if (dediprog_set_spi_voltage(0x0))<br>
                return 1;<br>
<br>
+       if (usb_release_interface(dediprog_handle, 0)) {<br>
+               msg_perr("Could not release USB interface!\n");<br>
+               return 1;<br>
+       }<br>
        if (usb_close(dediprog_handle)) {<br>
-               msg_perr("Couldn't close USB device!\n");<br>
+               msg_perr("Could not close USB device!\n");<br>
                return 1;<br>
        }<br>
        return 0;<br>
<br>
<br>
--<br>
<a href="http://www.hailfinger.org/" target="_blank">http://www.hailfinger.org/</a><br>
<br>
<br>
_______________________________________________<br>
flashrom mailing list<br>
<a href="mailto:flashrom@flashrom.org">flashrom@flashrom.org</a><br>
<a href="http://www.flashrom.org/mailman/listinfo/flashrom" target="_blank">http://www.flashrom.org/mailman/listinfo/flashrom</a><br>
</div></div></blockquote></div><br></div>