<br><div class="gmail_extra"><div class="gmail_quote">On Wed, Oct 3, 2012 at 3:59 PM, Carl-Daniel Hailfinger <span dir="ltr"><<a href="mailto:c-d.hailfinger.devel.2006@gmx.net" target="_blank">c-d.hailfinger.devel.2006@gmx.net</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Not for merge... yet.<br>
It works for dummy, nothing else was tested.<br>
Limitations/bugs mentioned in the patch.<br>
<br>
Signed-off-by: Carl-Daniel Hailfinger <<a href="mailto:c-d.hailfinger.devel.2006@gmx.net" target="_blank">c-d.hailfinger.devel.2006@gmx.net</a>><br>
<br>
Index: flashrom-spi_cache_rdid/spi.c<br>
===================================================================<br>
--- flashrom-spi_cache_rdid/spi.c       (Revision 1611)<br>
+++ flashrom-spi_cache_rdid/spi.c       (Arbeitskopie)<br>
@@ -24,18 +24,46 @@<br>
<br>
 #include <strings.h><br>
 #include <string.h><br>
+#include <stdlib.h><br>
 #include "flash.h"<br>
 #include "flashchips.h"<br>
 #include "chipdrivers.h"<br>
 #include "programmer.h"<br>
 #include "spi.h"<br>
<br>
+/* FIXME: We want a per-command cache, not just a RDID cache.<br>
+ * FIXME: We should cache this for spi_send_multicommand programmers as well.<br>
+ */<br>
+struct rdidcache {<br>
+       int available;<br>
+       unsigned char *readarr;<br>
+} rdidcache = {0};<br>
+<br>
 int spi_send_command(struct flashctx *flash, unsigned int writecnt,<br>
                     unsigned int readcnt, const unsigned char *writearr,<br>
                     unsigned char *readarr)<br>
 {<br>
-       return flash->pgm->spi.command(flash, writecnt, readcnt, writearr,<br>
+       int ret;<br>
+       unsigned char *tmp;<br>
+<br>
+       if ((writearr[0] == JEDEC_RDID) && (rdidcache.available >= readcnt)) {<br>
+               memcpy(readarr, rdidcache.readarr, readcnt);<br>
+               return 0;<br>
+       }<br>
+       ret = flash->pgm->spi.command(flash, writecnt, readcnt, writearr,<br>
                                       readarr);<br>
+       if (!ret && (writearr[0] == JEDEC_RDID) && (rdidcache.available < readcnt)) {<br>
+               tmp = realloc(rdidcache.readarr, readcnt);<br>
+               if (!tmp) {<br>
+                       /* Oh well. Don't cache stuff, then. No problem. */<br>
+                       msg_perr("Doom due to OOM! Brace for impact!\n");<br>
+                       return ret;<br>
+               }<br>
+               rdidcache.readarr = tmp;<br>
+               rdidcache.available = readcnt;<br>
+               memcpy(rdidcache.readarr, readarr, readcnt);<br>
+       }<br>
+       return ret;<br>
 }<br>
<br>
 int spi_send_multicommand(struct flashctx *flash, struct spi_command *cmds)<span><font color="#888888"><br></font></span></blockquote></div><div><br></div><div>Interesting approach. However, I think 3-byte vs. 4-byte RDID commands and caching REMS might make patching spi_send_command rather messy.</div>


<div><br></div><div>I made a patch that takes a different route by changing probe_spi_{rdid,rdid4,rems} functions instead. My patch can be viewed via Gerrit on Chromium.org @ <a href="https://gerrit.chromium.org/gerrit/#/c/35376/2" target="_blank">https://gerrit.chromium.org/gerrit/#/c/35376/2</a> (doesn't apply cleanly against upsteam currently).</div>


<div><br></div>-- <br>David Hendricks (dhendrix)<br>Systems Software Engineer, Google Inc.<br>
</div>