mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-11-04 07:00:39 +01:00 
			
		
		
		
	raiden_debug_spi.c: Implement retry mechanism
This overcomes a problem with the ServoMicro where USB packets can be ack'd by the device without triggering interrupts or loading data into the USB endpoints. The retry mechanism attempts the USB read 3 times before reattempting the write call to avoid performing multiple SPI transfers due to a USB problem. This process repeats 3 times before we return the last error code. Intermediary problems are reported in the status code. Based off the downstream commit: https://chromium-review.googlesource.com/c/chromiumos/third_party/flashrom/+/2038271 Change-Id: I76cde68852fa4963582d57c7dcb9f24de32c6da8 Signed-off-by: Edward O'Callaghan <quasisec@google.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/39310 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
		
				
					committed by
					
						
						Edward O'Callaghan
					
				
			
			
				
	
			
			
			
						parent
						
							e8c0ee7c7e
						
					
				
				
					commit
					2141250162
				
			@@ -132,6 +132,16 @@ enum raiden_debug_spi_request {
 | 
				
			|||||||
#define MAX_PACKET_SIZE         (64)
 | 
					#define MAX_PACKET_SIZE         (64)
 | 
				
			||||||
#define PAYLOAD_SIZE            (MAX_PACKET_SIZE - PACKET_HEADER_SIZE)
 | 
					#define PAYLOAD_SIZE            (MAX_PACKET_SIZE - PACKET_HEADER_SIZE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Servo Micro has an error where it is capable of acknowledging USB packets
 | 
				
			||||||
 | 
					 * without loading it into the USB endpoint buffers or triggering interrupts.
 | 
				
			||||||
 | 
					 * See crbug.com/952494. Retry mechanisms have been implemented to recover
 | 
				
			||||||
 | 
					 * from these rare failures allowing the process to continue.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define WRITE_RETY_ATTEMPTS     (3)
 | 
				
			||||||
 | 
					#define READ_RETY_ATTEMPTS      (3)
 | 
				
			||||||
 | 
					#define RETY_INTERVAL_US        (100 * 1000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This timeout is so large because the Raiden SPI timeout is 800ms.
 | 
					 * This timeout is so large because the Raiden SPI timeout is 800ms.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -245,16 +255,40 @@ static int send_command(struct flashctx *flash,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int status = -1;
 | 
						int status = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = write_command(flash, write_count, read_count,
 | 
						for (int write_attempt = 0; write_attempt < WRITE_RETY_ATTEMPTS;
 | 
				
			||||||
			write_buffer, read_buffer);
 | 
						         write_attempt++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status) {
 | 
							status = write_command(flash, write_count, read_count,
 | 
				
			||||||
		return status;
 | 
							                       write_buffer, read_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (status) {
 | 
				
			||||||
 | 
								/* Write operation failed. */
 | 
				
			||||||
 | 
								msg_perr("Raiden: Write command failed\n"
 | 
				
			||||||
 | 
									"Write attempt = %d\n"
 | 
				
			||||||
 | 
									"status = %d\n",
 | 
				
			||||||
 | 
									write_attempt + 1, status);
 | 
				
			||||||
 | 
								programmer_delay(RETY_INTERVAL_US);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (int read_attempt = 0; read_attempt < READ_RETY_ATTEMPTS; read_attempt++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								status = read_response(flash, write_count, read_count,
 | 
				
			||||||
 | 
										write_buffer, read_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (status != 0) {
 | 
				
			||||||
 | 
									/* Read operation failed. */
 | 
				
			||||||
 | 
									msg_perr("Raiden: Read response failed\n"
 | 
				
			||||||
 | 
										"Write attempt = %d\n"
 | 
				
			||||||
 | 
										"Read attempt = %d\n"
 | 
				
			||||||
 | 
										"status = %d\n",
 | 
				
			||||||
 | 
										write_attempt + 1, read_attempt + 1, status);
 | 
				
			||||||
 | 
									programmer_delay(RETY_INTERVAL_US);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									/* We were successful at performing the SPI transfer. */
 | 
				
			||||||
 | 
									return status;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = read_response(flash, write_count, read_count,
 | 
					 | 
				
			||||||
			write_buffer, read_buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user