Index: flashrom-ich_spi_fcerr_fcdone_paranoia/chipset_enable.c
===================================================================
--- flashrom-ich_spi_fcerr_fcdone_paranoia/chipset_enable.c	(Revision 1052)
+++ flashrom-ich_spi_fcerr_fcdone_paranoia/chipset_enable.c	(Arbeitskopie)
@@ -579,8 +579,20 @@
 			     mmio_readl(spibar + 0x80));
 		msg_pdbg("0x84: 0x%08x (PR4)\n",
 			     mmio_readl(spibar + 0x84));
-		msg_pdbg("0x90: 0x%08x (SSFS, SSFC)\n",
-			     mmio_readl(spibar + 0x90));
+
+		tmp = mmio_readl(spibar + 0x90);
+		msg_pdbg("0x90: 0x%02x (SSFS)\n", tmp & 0xff);
+		msg_pdbg("AEL %i, ", (tmp >> 4) & 1);
+		msg_pdbg("FCERR %i, ", (tmp >> 3) & 1);
+		msg_pdbg("FDONE %i, ", (tmp >> 2) & 1);
+		msg_pdbg("SCIP %i\n", (tmp >> 0) & 1);
+		if (tmp & (1 << 3)) {
+			msg_pdbg("Clearing SSFS.FCERR\n");
+			mmio_writeb(1 << 3, spibar + 0x90);
+		}
+		tmp >>= 8;
+		msg_pdbg("0x91: 0x%06x (SSFC)\n", tmp);
+
 		msg_pdbg("0x94: 0x%04x     (PREOP)\n",
 			     mmio_readw(spibar + 0x94));
 		msg_pdbg("0x96: 0x%04x     (OPTYPE)\n",
Index: flashrom-ich_spi_fcerr_fcdone_paranoia/ichspi.c
===================================================================
--- flashrom-ich_spi_fcerr_fcdone_paranoia/ichspi.c	(Revision 1052)
+++ flashrom-ich_spi_fcerr_fcdone_paranoia/ichspi.c	(Arbeitskopie)
@@ -413,6 +413,12 @@
 		write_cmd = 1;
 	}
 
+	/* FIXME: This should be a time-limited while loop. */
+	if (REGREAD16(ICH7_REG_SPIS) & SPIS_SCIP) {
+		msg_perr("Error: Totally unhandled SCIP condition!\n");
+		return 1;
+	}
+
 	/* Programm Offset in Flash into FADDR */
 	REGWRITE32(ICH7_REG_SPIA, (offset & 0x00FFFFFF));	/* SPI addresses are 24 BIT only */
 
@@ -486,18 +492,22 @@
 	/* write it */
 	REGWRITE16(ICH7_REG_SPIC, temp16);
 
-	/* wait for cycle complete */
-	timeout = 100 * 1000 * 60;	// 60s is a looong timeout.
-	while (((REGREAD16(ICH7_REG_SPIS) & SPIS_CDS) == 0) && --timeout) {
+	/* Wait for Cycle Done Status or Flash Cycle Error. */
+	timeout = 100 * 60;	/* 60 ms are 9.6 million cycles at 16 MHz. */
+	while (((REGREAD16(ICH7_REG_SPIS) & (SPIS_CDS | SPIS_FCERR)) == 0) &&
+	       --timeout) {
 		programmer_delay(10);
 	}
 	if (!timeout) {
 		msg_perr("timeout\n");
+		return 1;
 	}
 
 	/* FIXME: make sure we do not needlessly cause transaction errors. */
-	if ((REGREAD16(ICH7_REG_SPIS) & SPIS_FCERR) != 0) {
-		msg_pdbg("Transaction error!\n");
+	if (REGREAD16(ICH7_REG_SPIS) & SPIS_FCERR) {
+		msg_perr("Transaction error for opcode 0x%02x!\n",
+			 op.opcode);
+		REGWRITE16(ICH7_REG_SPIS, SPIS_FCERR);
 		return 1;
 	}
 
@@ -532,6 +542,12 @@
 		write_cmd = 1;
 	}
 
+	/* FIXME: This should be a time-limited while loop. */
+	if (REGREAD16(ICH9_REG_SSFS) & SSFS_SCIP) {
+		msg_perr("Error: Totally unhandled SCIP condition!\n");
+		return 1;
+	}
+
 	/* Programm Offset in Flash into FADDR */
 	REGWRITE32(ICH9_REG_FADDR, (offset & 0x00FFFFFF));	/* SPI addresses are 24 BIT only */
 
@@ -605,18 +621,23 @@
 	/* write it */
 	REGWRITE32(ICH9_REG_SSFS, temp32);
 
-	/*wait for cycle complete */
-	timeout = 100 * 1000 * 60;	// 60s is a looong timeout.
-	while (((REGREAD32(ICH9_REG_SSFS) & SSFS_CDS) == 0) && --timeout) {
+	/* Wait for Cycle Done Status or Flash Cycle Error. */
+	timeout = 100 * 60;	/* 60 ms are 9.6 million cycles at 16 MHz. */
+	while (((REGREAD32(ICH9_REG_SSFS) & (SSFS_CDS | SSFS_FCERR)) == 0) &&
+	       --timeout) {
 		programmer_delay(10);
 	}
 	if (!timeout) {
 		msg_perr("timeout\n");
+		return 1;
 	}
 
 	/* FIXME make sure we do not needlessly cause transaction errors. */
-	if ((REGREAD32(ICH9_REG_SSFS) & SSFS_FCERR) != 0) {
-		msg_pdbg("Transaction error!\n");
+	if (REGREAD32(ICH9_REG_SSFS) & SSFS_FCERR) {
+		msg_perr("Transaction error for opcode 0x%02x!\n",
+			 op.opcode);
+		//FIXME: Really REGWRITE8?
+		REGWRITE8(ICH9_REG_SSFS, SSFS_FCERR);
 		return 1;
 	}
 

