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