diff options
Diffstat (limited to 'raiden_debug_spi.c')
| -rw-r--r-- | raiden_debug_spi.c | 50 | 
1 files changed, 42 insertions, 8 deletions
| diff --git a/raiden_debug_spi.c b/raiden_debug_spi.c index 08f8928b..1f30b6a2 100644 --- a/raiden_debug_spi.c +++ b/raiden_debug_spi.c @@ -133,6 +133,16 @@ enum raiden_debug_spi_request {  #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.   */  #define TRANSFER_TIMEOUT_MS     (200 + 800) @@ -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); - -	if (status) { -		return status; -	} +	for (int write_attempt = 0; write_attempt < WRITE_RETY_ATTEMPTS; +	         write_attempt++) { -	status = read_response(flash, write_count, read_count, -			write_buffer, read_buffer); +		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; +			} +		} +	}  	return status;  } | 
