Am 05.10.2010 22:42 schrieb Iain Paton:
>>> root@p7fe-64:~/flashrom# ./flashrom -p nicintel_spi -V
>>> flashrom v0.9.2-r1186 on Linux 2.6.35-dt (x86_64), built with libpci
>>> 3.1.4, GCC 4.4.3, little endian
>>> Initializing nicintel_spi programmer
>>> Found "Intel 82540EM Gigabit Ethernet Controller" (8086:100e, BDF
>>> 06:02.0).
>
> I have a few of these cards, so maybe I'll try a different one just to
> be sure there's nothing odd going on with this one.

Here is an updated timeout patch (no functional changes for
nicintel_spi). A year has passed, and I'm still trying to find someone
who can test and ack it.

GatoLoko: This new patch also addresses the SB600 timeout issue you were
seeing.

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

Index: flashrom-bitbang_timeout/ogp_spi.c
===================================================================
--- flashrom-bitbang_timeout/ogp_spi.c  (Revision 1450)
+++ flashrom-bitbang_timeout/ogp_spi.c  (Arbeitskopie)
@@ -50,9 +50,13 @@
        {},
 };
 
-static void ogp_request_spibus(void)
+static int ogp_request_spibus(void)
 {
+       /* FIXME: Do we have to check if any other SPI accesses are running
+        * right now? Can the request fail?
+        */
        pci_mmio_writel(1, ogp_spibar + ogp_reg_sel);
+       return 0;
 }
 
 static void ogp_release_spibus(void)
Index: flashrom-bitbang_timeout/bitbang_spi.c
===================================================================
--- flashrom-bitbang_timeout/bitbang_spi.c      (Revision 1450)
+++ flashrom-bitbang_timeout/bitbang_spi.c      (Arbeitskopie)
@@ -51,10 +51,11 @@
        return bitbang_spi_master->get_miso();
 }
 
-static void bitbang_spi_request_bus(void)
+static int bitbang_spi_request_bus(void)
 {
        if (bitbang_spi_master->request_bus)
-               bitbang_spi_master->request_bus();
+               return bitbang_spi_master->request_bus();
+       return 0;
 }
 
 static void bitbang_spi_release_bus(void)
@@ -99,7 +100,7 @@
 
        register_spi_programmer(&spi_programmer_bitbang);
 
-       /* FIXME: Run bitbang_spi_request_bus here or in programmer init? */
+       /* FIXME: Run bitbang_spi_request_bus here or per command? */
        bitbang_spi_set_cs(1);
        bitbang_spi_set_sck(0);
        bitbang_spi_set_mosi(0);
@@ -144,13 +145,15 @@
 static int bitbang_spi_send_command(unsigned int writecnt, unsigned int 
readcnt,
                const unsigned char *writearr, unsigned char *readarr)
 {
-       int i;
+       int i, ret;
 
        /* FIXME: Run bitbang_spi_request_bus here or in programmer init?
         * Requesting and releasing the SPI bus is handled in here to allow the
         * programmer to use its own SPI engine for native accesses.
         */
-       bitbang_spi_request_bus();
+       ret = bitbang_spi_request_bus();
+       if (ret)
+               return ret;
        bitbang_spi_set_cs(0);
        for (i = 0; i < writecnt; i++)
                bitbang_spi_readwrite_byte(writearr[i]);
Index: flashrom-bitbang_timeout/nicintel_spi.c
===================================================================
--- flashrom-bitbang_timeout/nicintel_spi.c     (Revision 1450)
+++ flashrom-bitbang_timeout/nicintel_spi.c     (Arbeitskopie)
@@ -58,6 +58,9 @@
 // #define FL_BUSY     30
 // #define FL_ER       31
 
+/* 1000000 loops are roughly 1 s. */
+#define MAX_REQUEST_LOOPS      1000000
+
 uint8_t *nicintel_spibar;
 
 const struct pcidev_status nics_intel_spi[] = {
@@ -69,16 +72,27 @@
        {},
 };
 
-static void nicintel_request_spibus(void)
+static void nicintel_release_spibus(void);
+
+static int nicintel_request_spibus(void)
 {
        uint32_t tmp;
+       int i = 0;
 
        tmp = pci_mmio_readl(nicintel_spibar + FLA);
        tmp |= 1 << FL_REQ;
        pci_mmio_writel(tmp, nicintel_spibar + FLA);
 
        /* Wait until we are allowed to use the SPI bus. */
-       while (!(pci_mmio_readl(nicintel_spibar + FLA) & (1 << FL_GNT))) ;
+       while (!(pci_mmio_readl(nicintel_spibar + FLA) & (1 << FL_GNT))) {
+               if (i++ > MAX_REQUEST_LOOPS) {
+                       nicintel_release_spibus();
+                       msg_perr("%s: Timeout! Aborting.\n", __func__);
+                       return TIMEOUT_ERROR;
+               }
+       }
+
+       return 0;
 }
 
 static void nicintel_release_spibus(void)
Index: flashrom-bitbang_timeout/sb600spi.c
===================================================================
--- flashrom-bitbang_timeout/sb600spi.c (Revision 1450)
+++ flashrom-bitbang_timeout/sb600spi.c (Arbeitskopie)
@@ -80,12 +80,19 @@
        return ret;
 }
 
-static void execute_command(void)
+static int execute_command(void)
 {
+       int timeout = 10000000;
+
        mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
 
-       while (mmio_readb(sb600_spibar + 2) & 1)
+       while ((mmio_readb(sb600_spibar + 2) & 1) && --timeout)
                ;
+       if (!timeout) {
+               msg_perr("SB600: execute_command timeout!\n");
+               return TIMEOUT_ERROR;
+       }
+       return 0;
 }
 
 static int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
@@ -96,6 +103,7 @@
        unsigned char cmd = *writearr++;
        unsigned int readoffby1;
        unsigned char readwrite;
+       int ret;
 
        writecnt--;
 
@@ -144,7 +152,9 @@
                return SPI_PROGRAMMER_ERROR;
 
        msg_pspew("Executing: \n");
-       execute_command();
+       ret = execute_command();
+       if (ret)
+               return ret;
 
        /*
         * After the command executed, we should find out the index of the
Index: flashrom-bitbang_timeout/mcp6x_spi.c
===================================================================
--- flashrom-bitbang_timeout/mcp6x_spi.c        (Revision 1450)
+++ flashrom-bitbang_timeout/mcp6x_spi.c        (Arbeitskopie)
@@ -39,22 +39,38 @@
 #define MCP6X_SPI_REQUEST      0
 #define MCP6X_SPI_GRANT                8
 
+/* 1000000 loops are roughly 1 s. */
+#define MAX_REQUEST_LOOPS      1000000
+
 void *mcp6x_spibar = NULL;
 
 /* Cached value of last GPIO state. */
 static uint8_t mcp_gpiostate;
 
-static void mcp6x_request_spibus(void)
+static void mcp6x_release_spibus(void);
+
+static int mcp6x_request_spibus(void)
 {
+       int i = 0;
+
        mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
        mcp_gpiostate |= 1 << MCP6X_SPI_REQUEST;
        mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 
        /* Wait until we are allowed to use the SPI bus. */
-       while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_GRANT))) ;
+       while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_GRANT))) {
+               if (i++ > MAX_REQUEST_LOOPS) {
+                       /* Update the cache. */
+                       mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
+                       mcp6x_release_spibus();
+                       msg_perr("%s: Timeout! Aborting.\n", __func__);
+                       return TIMEOUT_ERROR;
+               }
+       }
 
        /* Update the cache. */
        mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
+       return 0;
 }
 
 static void mcp6x_release_spibus(void)
Index: flashrom-bitbang_timeout/programmer.h
===================================================================
--- flashrom-bitbang_timeout/programmer.h       (Revision 1450)
+++ flashrom-bitbang_timeout/programmer.h       (Arbeitskopie)
@@ -137,7 +137,7 @@
        void (*set_sck) (int val);
        void (*set_mosi) (int val);
        int (*get_miso) (void);
-       void (*request_bus) (void);
+       int (*request_bus) (void);
        void (*release_bus) (void);
 };
 


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


_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to