From patchwork Mon Apr 28 22:52:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: Flashrom stuck using 100% cpu while probing for a chip Date: Mon, 28 Apr 2014 22:52:45 -0000 From: GatoLoko X-Patchwork-Id: 4133 Message-Id: <535EDBBD.5010702@gmail.com> To: David Hendricks Cc: Stefan Tauner , flashrom Carl-Daniel told me to try again the same patch I tried the last time. [22:08:58] GatoLoko: yeah, definitely needs my timeout patches [22:18:38] which one? [22:20:19] the one mentioned here? --> www.flashrom.org/pipermail/flashrom/2011-October/008048.html [22:55:35] GatoLoko: yes Since it doesn't apply to the current tree I've had to handpick the changes and adapt it a little bit (attached is a modified patch). Once built I get the same results I got the last time: it takes a long time probing for each chip, but in the end skips them all, as if it didn't recognize mine (which is a Macronix MX25L4005APC-12G). Shouldn't this chip be supported by the MX25L4005(A/C)? For reference, the chip's datasheet is here: www.alldatasheet.com/datasheet-pdf/pdf/267916/MCNIX/MX25L4005APC-12G.html diff -u flashrom-orig/bitbang_spi.c flashrom-timeout/bitbang_spi.c --- flashrom-orig/bitbang_spi.c 2014-04-29 00:25:21.714943586 +0200 +++ flashrom-timeout/bitbang_spi.c 2014-04-29 00:25:35.335010172 +0200 @@ -46,10 +46,11 @@ return master->get_miso(); } -static void bitbang_spi_request_bus(const struct bitbang_spi_master * const master) +static int bitbang_spi_request_bus(const struct bitbang_spi_master * const master) { if (master->request_bus) - master->request_bus(); + return master->request_bus(); + return 0; } static void bitbang_spi_release_bus(const struct bitbang_spi_master * const master) @@ -136,14 +137,16 @@ const unsigned char *writearr, unsigned char *readarr) { - int i; + int i, ret; const struct bitbang_spi_master *master = flash->pgm->spi.data; /* 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(master); + ret = bitbang_spi_request_bus(master); + if (ret) + return ret; bitbang_spi_set_cs(master, 0); for (i = 0; i < writecnt; i++) bitbang_spi_rw_byte(master, writearr[i]); Sólo en flashrom-timeout/: .bitbang_spi.c.swp Subdirectorios comunes: flashrom-orig/Documentation y flashrom-timeout/Documentation diff -u flashrom-orig/mcp6x_spi.c flashrom-timeout/mcp6x_spi.c --- flashrom-orig/mcp6x_spi.c 2014-04-29 00:25:22.074945346 +0200 +++ flashrom-timeout/mcp6x_spi.c 2014-04-29 00:25:35.379010387 +0200 @@ -40,22 +40,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) diff -u flashrom-orig/nicintel_spi.c flashrom-timeout/nicintel_spi.c --- flashrom-orig/nicintel_spi.c 2014-04-29 00:25:21.706943547 +0200 +++ flashrom-timeout/nicintel_spi.c 2014-04-29 00:25:35.327010132 +0200 @@ -71,6 +71,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 dev_entry nics_intel_spi[] = { @@ -83,17 +86,27 @@ {0}, }; -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) { diff -u flashrom-orig/ogp_spi.c flashrom-timeout/ogp_spi.c --- flashrom-orig/ogp_spi.c 2014-04-29 00:25:21.710943567 +0200 +++ flashrom-timeout/ogp_spi.c 2014-04-29 00:25:35.331010152 +0200 @@ -53,9 +53,13 @@ {0}, }; -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) Sólo en flashrom-timeout/: patched.log diff -u flashrom-orig/programmer.h flashrom-timeout/programmer.h --- flashrom-orig/programmer.h 2014-04-29 00:25:21.710943567 +0200 +++ flashrom-timeout/programmer.h 2014-04-29 00:25:35.331010152 +0200 @@ -157,7 +157,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); /* Length of half a clock period in usecs. */ unsigned int half_period; diff -u flashrom-orig/sb600spi.c flashrom-timeout/sb600spi.c --- flashrom-orig/sb600spi.c 2014-04-29 00:25:21.950944740 +0200 +++ flashrom-timeout/sb600spi.c 2014-04-29 00:25:35.359010289 +0200 @@ -159,12 +159,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(struct flashctx *flash, unsigned int writecnt, @@ -177,6 +184,7 @@ unsigned char cmd = *writearr++; unsigned int readoffby1; unsigned char readwrite; + int ret; writecnt--; @@ -225,7 +233,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 Subdirectorios comunes: flashrom-orig/.svn y flashrom-timeout/.svn Subdirectorios comunes: flashrom-orig/util y flashrom-timeout/util