[flashrom] [PATCH] ICH SPI Preop handling

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Thu Sep 17 15:28:36 CEST 2009


On 16.09.2009 15:33, Carl-Daniel Hailfinger wrote:
> The current ICH SPI preop handling is a hack which spews lots of
> warnings, but still yields correct results.
> With the multicommand infrastructure I introduced in r645, it became
> possible to integrate ICH SPI preopcodes cleanly into the flashrom design.
>
> The new code checks for every opcode in a multicommand array if it is a
> preopcode. If yes, it checks if the next opcode is associated with that
> preopcode and in that case it simply runs the opcode because the correct
> preopcode will be run automatically before the opcode.
>   

Updated patch with comments from FENG Yu Ning incorporated. I also shortened
struct spi_command *spicommands
to
struct spi_command *cmds
in a few places. I think the code is still readable, and we don't break
the 80 char limit anymore.

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

Index: flashrom-ich9_multicommand_preop/flash.h
===================================================================
--- flashrom-ich9_multicommand_preop/flash.h	(Revision 725)
+++ flashrom-ich9_multicommand_preop/flash.h	(Arbeitskopie)
@@ -498,7 +498,7 @@
 struct spi_programmer {
 	int (*command)(unsigned int writecnt, unsigned int readcnt,
 		   const unsigned char *writearr, unsigned char *readarr);
-	int (*multicommand)(struct spi_command *spicommands);
+	int (*multicommand)(struct spi_command *cmds);
 
 	/* Optimized functions for this programmer */
 	int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
@@ -514,7 +514,7 @@
 int probe_spi_res(struct flashchip *flash);
 int spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr);
-int spi_send_multicommand(struct spi_command *spicommands);
+int spi_send_multicommand(struct spi_command *cmds);
 int spi_write_enable(void);
 int spi_write_disable(void);
 int spi_chip_erase_60(struct flashchip *flash);
@@ -539,7 +539,7 @@
 uint32_t spi_get_valid_read_addr(void);
 int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 			     const unsigned char *writearr, unsigned char *readarr);
-int default_spi_send_multicommand(struct spi_command *spicommands);
+int default_spi_send_multicommand(struct spi_command *cmds);
 
 /* 82802ab.c */
 int probe_82802ab(struct flashchip *flash);
@@ -565,7 +565,7 @@
 		    const unsigned char *writearr, unsigned char *readarr);
 int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
-int ich_spi_send_multicommand(struct spi_command *spicommands);
+int ich_spi_send_multicommand(struct spi_command *cmds);
 
 /* it87spi.c */
 extern uint16_t it8716f_flashport;
Index: flashrom-ich9_multicommand_preop/spi.c
===================================================================
--- flashrom-ich9_multicommand_preop/spi.c	(Revision 725)
+++ flashrom-ich9_multicommand_preop/spi.c	(Arbeitskopie)
@@ -118,7 +118,7 @@
 						      writearr, readarr);
 }
 
-int spi_send_multicommand(struct spi_command *spicommands)
+int spi_send_multicommand(struct spi_command *cmds)
 {
 	if (!spi_programmer[spi_controller].multicommand) {
 		fprintf(stderr, "%s called, but SPI is unsupported on this "
@@ -126,7 +126,7 @@
 		return 1;
 	}
 
-	return spi_programmer[spi_controller].multicommand(spicommands);
+	return spi_programmer[spi_controller].multicommand(cmds);
 }
 
 int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
@@ -148,13 +148,12 @@
 	return spi_send_multicommand(cmd);
 }
 
-int default_spi_send_multicommand(struct spi_command *spicommands)
+int default_spi_send_multicommand(struct spi_command *cmds)
 {
 	int result = 0;
-	while ((spicommands->writecnt || spicommands->readcnt) && !result) {
-		result = spi_send_command(spicommands->writecnt, spicommands->readcnt,
-					  spicommands->writearr, spicommands->readarr);
-		spicommands++;
+	for (; (cmds->writecnt || cmds->readcnt) && !result; cmds++) {
+		result = spi_send_command(cmds->writecnt, cmds->readcnt,
+					  cmds->writearr, cmds->readarr);
 	}
 	return result;
 }
@@ -494,7 +493,7 @@
 int spi_chip_erase_60(struct flashchip *flash)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -518,7 +517,7 @@
 		return result;
 	}
 	
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
@@ -540,7 +539,7 @@
 int spi_chip_erase_c7(struct flashchip *flash)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -564,7 +563,7 @@
 		return result;
 	}
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n", __func__);
 		return result;
@@ -596,7 +595,7 @@
 int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -614,7 +613,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
@@ -640,7 +639,7 @@
 int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -658,7 +657,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n", __func__);
 		return result;
@@ -702,7 +701,7 @@
 int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -720,7 +719,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
@@ -779,7 +778,7 @@
 int spi_write_status_register(int status)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_EWSR_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_EWSR },
@@ -797,7 +796,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
@@ -808,7 +807,7 @@
 int spi_byte_program(int addr, uint8_t byte)
 {
 	int result;
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -826,7 +825,7 @@
 		.readarr	= NULL,
 	}};
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
@@ -844,7 +843,7 @@
 		(address >> 8) & 0xff,
 		(address >> 0) & 0xff,
 	};
-	struct spi_command spicommands[] = {
+	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
 		.writearr	= (const unsigned char[]){ JEDEC_WREN },
@@ -873,7 +872,7 @@
 
 	memcpy(&cmd[4], bytes, len);
 
-	result = spi_send_multicommand(spicommands);
+	result = spi_send_multicommand(cmds);
 	if (result) {
 		fprintf(stderr, "%s failed during command execution\n",
 			__func__);
Index: flashrom-ich9_multicommand_preop/ichspi.c
===================================================================
--- flashrom-ich9_multicommand_preop/ichspi.c	(Revision 725)
+++ flashrom-ich9_multicommand_preop/ichspi.c	(Arbeitskopie)
@@ -742,22 +742,26 @@
 	return result;
 }
 
-int ich_spi_send_multicommand(struct spi_command *spicommands)
+int ich_spi_send_multicommand(struct spi_command *cmds)
 {
 	int ret = 0;
-	while ((spicommands->writecnt || spicommands->readcnt) && !ret) {
-		ret = ich_spi_send_command(spicommands->writecnt, spicommands->readcnt,
-					   spicommands->writearr, spicommands->readarr);
-		/* This awful hack needs to be smarter.
-		 */
-		if ((ret == SPI_INVALID_OPCODE) &&
-		    ((spicommands->writearr[0] == JEDEC_WREN) ||
-		     (spicommands->writearr[0] == JEDEC_EWSR))) {
-			printf_debug(" due to SPI master limitation, ignoring"
-				     " and hoping it will be run as PREOP\n");
-			ret = 0;
-		}
-		spicommands++;
+	int oppos, preoppos;
+	for (; (cmds->writecnt || cmds->readcnt) && !ret; cmds++) {
+		/* Is the next command valid or a terminator? */
+		if ((cmds + 1)->writecnt || (cmds + 1)->readcnt) {
+			preoppos = find_preop(curopcodes, cmds->writearr[0]);
+			oppos = find_opcode(curopcodes, (cmds + 1)->writearr[0]);
+			/* Is the current opcode a preopcode for the next opcode? */
+			if ((oppos != -1) && (preoppos != -1) &&
+			    (curopcodes->opcode[oppos].atomic == preoppos)) {
+				printf_debug("opcode 0x%02x will be run as PREOP\n",
+					     cmds->writearr[0]);
+				continue;
+			}
+		}	
+			
+		ret = ich_spi_send_command(cmds->writecnt, cmds->readcnt,
+					   cmds->writearr, cmds->readarr);
 	}
 	return ret;
 }


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





More information about the flashrom mailing list