mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-10-31 13:20:42 +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:
		 Edward O'Callaghan
					Edward O'Callaghan
				
			
				
					committed by
					
						 Edward O'Callaghan
						Edward O'Callaghan
					
				
			
			
				
	
			
			
			 Edward O'Callaghan
						Edward O'Callaghan
					
				
			
						parent
						
							e8c0ee7c7e
						
					
				
				
					commit
					2141250162
				
			| @@ -132,6 +132,16 @@ enum raiden_debug_spi_request { | ||||
| #define MAX_PACKET_SIZE         (64) | ||||
| #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. | ||||
|  */ | ||||
| @@ -245,16 +255,40 @@ static int send_command(struct flashctx *flash, | ||||
| { | ||||
| 	int status = -1; | ||||
|  | ||||
| 	status = write_command(flash, write_count, read_count, | ||||
| 			write_buffer, read_buffer); | ||||
| 	for (int write_attempt = 0; write_attempt < WRITE_RETY_ATTEMPTS; | ||||
| 	         write_attempt++) { | ||||
|  | ||||
| 	if (status) { | ||||
| 		return status; | ||||
| 		status = write_command(flash, write_count, read_count, | ||||
| 		                       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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user