mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02: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:
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user