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