Hello Brian Nemec,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to review the following change.
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 470 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/1
diff --git a/raiden_debug_spi.c b/raiden_debug_spi.c index 6cb32b3..5e07967 100644 --- a/raiden_debug_spi.c +++ b/raiden_debug_spi.c @@ -48,7 +48,10 @@ * include/usb_spi.h * common/usb_spi.c * - * bInterfaceProtocol determines which protocol is used by the USB SPI device. + * 2 Versions of the protocol exist in deployed devices: + * The raiden_debug_spi.c interface used will switch between them automatically + * depending on the protocol version reported in the bInterfaceProtocol + * * * * USB SPI Version 1: @@ -117,8 +120,191 @@ * 0x20001-0x20063 Lower bits store the positive value representation * of the libusb_error enum. See the libusb documentation: * http://libusb.sourceforge.net/api-1.0/group__misc.html + * + * + * + * USB SPI Version 2: + * + * USB SPI version 2 adds support for larger SPI transfers and reduces the + * number of USB packets transferred. This improves performance when + * writing or reading large chunks of memory from a device. A packet ID + * field is used to distinguish the different packet types. Additional + * packets have been included to query the device for it's configuration + * allowing the interface to be used on platforms with different SPI + * limitations. It includes validation and a packet to recover from the + * situations where USB packets are lost. + * + * + * Example: USB SPI request with 128 byte write and 0 byte read. + * + * Packet #1 Host to Device: + * packet id = PACKET_ID_V2_COMMAND + * write count = 128 + * read count = 0 + * payload = First 58 bytes from the write buffer, + * start is byte 0 + * + * Packet #2 Host to Device: + * packet id = PACKET_ID_V2_COMMAND_CONTINUE + * data index = 58 + * payload = next 60 bytes from the write buffer, + * starting at byte 58 + * + * Packet #3 Host to Device: + * packet id = PACKET_ID_V2_COMMAND_CONTINUE + * data index = 118 + * payload = next 10 bytes from the write buffer, + * starting at byte 118 + * + * Packet #4 Device to Host: + * packet id = PACKET_ID_V2_RESPONSE + * status code = status code from device + * payload = 0 bytes + * + * Command Packet (Host to Device): + * + * Start of USB SPI command, containing the number of bytes to write and + * read and a payload of bytes to write. If the payload is unable to fit + * in one USB packet, it contains the first 58 bytes. + * + * +----------------+------------------+-----------------+------------------------+ + * | packet id : 2B | write count : 2B | read count : 2B | write payload : <= 58B | + * +----------------+------------------+-----------------+------------------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * Valid values packet id = PACKET_ID_V2_COMMAND + * + * write count: 2 byte, zero based count of bytes to write + * + * read count: 2 byte, zero based count of bytes to read + * + * write payload: Up to 62 bytes of data to write to SPI, the total + * length of all TX packets must match write count. + * Due to data alignment constraints, this must be an + * even number of bytes unless this is the final packet. + * + * + * Response Packet (Device to Host): + * + * Start of the USB SPI response, containing the status code and + * any bytes read in the payload. If read buffer can not fit in + * a single packet, it represents the first 60 bytes. + * + * +----------------+------------------+-----------------------+ + * | packet id : 2B | status code : 2B | read payload : <= 60B | + * +----------------+------------------+-----------------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * Valid values packet id = PACKET_ID_V2_RESPONSE + * + * status code: 2 byte status code + * 0x0000: Success + * 0x0001: SPI timeout + * 0x0002: Busy, try again + * This can happen if someone else has acquired the shared memory + * buffer that the SPI driver uses as /dev/null + * 0x0003: Write count invalid. The byte limit is platform specific + * and is set during the configure USB SPI response. + * 0x0004: Read count invalid. The byte limit is platform specific + * and is set during the configure USB SPI response. + * 0x0005: The SPI bridge is disabled. + * 0x0006: The RX continue packet's data index is invalid. This + * can indicate a USB transfer failure to the device. + * 0x0007: The RX endpoint has received more data than write count. + * This can indicate a USB transfer failure to the device. + * 0x0008: An unexpected packet arrived that the device could not + * process. + * 0x8000: Unknown error mask + * The bottom 15 bits will contain the bottom 14 bits from the EC + * error code. + * + * read payload: Up to 62 bytes of data read from SPI, the total + * length of all RX packets must match read count + * unless an error status was returned. Due to data + * alignment constraints, this must be a even number + * of bytes unless this is the final packet. + * + * + * Continue Packet (Bidirectional): + * + * Continuation packet for the writes and read buffers. Both packets + * follow the same format, a data index counts the number of bytes + * previously transferred in the USB SPI transfer and a payload of bytes. + * + * +----------------+-----------------+-------------------------------+ + * | packet id : 2B | data index : 2B | write / read payload : <= 60B | + * +----------------+-----------------+-------------------------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * The packet id has 2 values depending on direction: + * packet id = PACKET_ID_V2_COMMAND_CONTINUE indicates the + * packet is being transmitted from the host to the device + * packet id = PACKET_ID_V2_RESPONSE_CONTINUE indicates the + * packet is being transmitted from the device to the host. + * + * data index: The data index indicates the number of bytes in the + * read or write buffers have already been transmitted. + * It is used to validate that no packets have been dropped + * and that the prior packets have been correctly decoded. + * this value corresponds to the position in the destination + * destination to start copying the payload into. + * + * read and write payload: + * Contains up to 60 bytes of payload data to transfer to + * the SPI write buffer or from the SPI read buffer. + * + * + * Command Get Configuration Packet (Host to Device): + * + * Query the device to request it's USB SPI configuration indicating + * the number of bytes it can write and read. + * + * +----------------+ + * | packet id : 2B | + * +----------------+ + * + * packet id: 2 byte enum PACKET_ID_V2_COMMAND_GET_USB_SPI_CONFIG + * + * Response Configuration Packet (Device to Host): + * + * Response packet form the device to report the maximum write and + * read size supported by the device. + * + * +----------------+----------------------+---------------------+ + * | packet id : 2B | max write count : 2B | max read count : 2B | + * +----------------+----------------------+---------------------+ + * + * packet id: 2 byte enum PACKET_ID_V2_COMMAND_GET_USB_SPI_CONFIG + * + * max write count : 2 byte count of the maximum number of bytes + * the device can write to SPI in one transaction. + * + * max read count : 2 byte count of the maximum number of bytes + * the device can read from SPI in one transaction. + * + * Command Restart Response Packet (Host to Device): + * + * Command to restart the response transfer from the device. This enables + * the host to recover from a lost packet when reading the response + * without restarting the SPI transfer. + * + * +----------------+ + * | packet id : 2B | + * +----------------+ + * + * packet id: 2 byte enum PACKET_ID_V2_COMMAND_GET_USB_SPI_CONFIG + * + * send_command return codes have the following format: + * + * 0x00000: Status code success. + * 0x00001-0x0FFFF: Error code returned by the USB SPI device. + * 0x10001-0x1FFFF: USB SPI Host error codes + * 0x20001-0x20063 Lower bits store the positive value representation + * of the libusb_error enum. See the libusb documentation: + * http://libusb.sourceforge.net/api-1.0/group__misc.html */
+ #include "programmer.h" #include "spi.h" #include "usb_device.h" @@ -138,6 +324,7 @@ #define GOOGLE_VID (0x18D1) #define GOOGLE_RAIDEN_SPI_SUBCLASS (0x51) #define GOOGLE_RAIDEN_SPI_PROTOCOL_V1 (0x01) +#define GOOGLE_RAIDEN_SPI_PROTOCOL_V2 (0x02)
enum { /* The host failed to transfer the data with no libusb error. */ @@ -185,6 +372,7 @@ */ #define WRITE_RETRY_ATTEMPTS (3) #define READ_RETRY_ATTEMPTS (3) +#define GET_CONFIG_RETRY_ATTEMPTS (3) #define RETRY_INTERVAL_US (100 * 1000)
/* @@ -200,6 +388,17 @@ * All of the USB SPI packets have size equal to the max USB packet size of 64B */ #define PAYLOAD_SIZE_V1 (62) +#define PACKET_HEADER_SIZE (2) + +#define HOST_VERSION (1) + +#define PAYLOAD_SIZE_V2_START (58) + +#define PAYLOAD_SIZE_V2_RESPONSE (60) + +#define PAYLOAD_SIZE_V2_CONTINUE (60) + +#define PAYLOAD_SIZE_V2_ERROR (60)
#define SPI_TRANSFER_V1_MAX (PAYLOAD_SIZE_V1)
@@ -224,10 +423,86 @@ usb_spi_response_v1_t response; } __attribute__((packed)) usb_spi_packet_v1_t;
+/* + * Version 2 protocol specific attributes + */ + +enum packet_id_type { + + /* Request USB SPI configuration data from device. */ + PACKET_ID_V2_COMMAND_GET_USB_SPI_CONFIG = 0, + /* USB SPI configuration data from device. */ + PACKET_ID_V2_RESPONSE_USB_SPI_CONFIG = 1, + + /* Start a USB SPI transfer and deliver first packet of data to write. */ + PACKET_ID_V2_COMMAND = 2, + /* Additional packets containing write payload. */ + PACKET_ID_V2_COMMAND_CONTINUE = 3, + + /* + * Request the device restart the response enabling us to recover from + * packet loss without another SPI transfer. + */ + PACKET_ID_V2_COMMAND_RESTART_RESPONSE = 4, + + /* First packet of USB SPI response with status code and read payload. */ + PACKET_ID_V2_RESPONSE = 5, + /* Additional packets containing read payload. */ + PACKET_ID_V2_RESPONSE_CONTINUE = 6, +}; + +typedef struct { + int16_t packet_id; +} __attribute__((packed)) usb_spi_command_get_configuration_v2_t; + +typedef struct { + int16_t packet_id; + uint16_t max_write_count; + uint16_t max_read_count; +} __attribute__((packed)) usb_spi_response_configuration_v2_t; + +typedef struct { + int16_t packet_id; + int16_t write_count; + /* -1 Indicates readback all on halfduplex compliant devices. */ + int16_t read_count; + uint8_t data[PAYLOAD_SIZE_V2_START]; +} __attribute__((packed)) usb_spi_command_v2_t; + +typedef struct { + int16_t packet_id; + uint16_t status_code; + uint8_t data[PAYLOAD_SIZE_V2_RESPONSE]; +} __attribute__((packed)) usb_spi_response_v2_t; + +typedef struct { + int16_t packet_id; + uint16_t data_index; + uint8_t data[PAYLOAD_SIZE_V2_CONTINUE]; +} __attribute__((packed)) usb_spi_continue_v2_t; + +typedef struct { + int16_t packet_id; +} __attribute__((packed)) usb_spi_command_restart_response_v2_t; + +typedef struct { + union { + int16_t packet_id; + usb_spi_command_get_configuration_v2_t command_get_config; + usb_spi_response_configuration_v2_t response_config; + usb_spi_command_restart_response_v2_t restart_response; + usb_spi_command_v2_t command; + usb_spi_response_v2_t response; + usb_spi_continue_v2_t command_continue; + usb_spi_continue_v2_t response_continue; + }; +} __attribute__((packed)) usb_spi_packet_v2_t; + typedef struct { union { uint8_t bytes[MAX_USB_PACKET_SIZE]; usb_spi_packet_v1_t packet_v1; + usb_spi_packet_v2_t packet_v2; }; /* * By storing the number of bytes in the header and knowing that the @@ -427,6 +702,177 @@ return status; }
+/* + * Version 2 Protocol + */ + +int get_spi_size_v2(struct raiden_debug_spi_data *ctx_data) +{ + int status; + usb_spi_packet_ctx_t response_config; + + usb_spi_packet_ctx_t command_get_config = { + .header_size = sizeof(usb_spi_command_get_configuration_v2_t), + .packet_size = sizeof(usb_spi_command_get_configuration_v2_t), + .packet_v2.packet_id = PACKET_ID_V2_COMMAND_GET_USB_SPI_CONFIG + }; + + for (int config_attempt = 0; config_attempt < GET_CONFIG_RETRY_ATTEMPTS; + config_attempt++) { + + status = transmit_packet(ctx_data, &command_get_config); + if (status) { + msg_perr("Raiden: Failed to transmit get config\n" + " config attempt = %d\n" + " status = %d\n", + config_attempt + 1, status); + programmer_delay(RETRY_INTERVAL_US); + continue; + } + + status = receive_packet(ctx_data, &response_config); + if (status) { + msg_perr("Raiden: Failed to receive packet\n" + " config attempt = %d\n" + " status = %d\n", + config_attempt + 1, status); + programmer_delay(RETRY_INTERVAL_US); + continue; + } + + /* + * Perform validation on the packet received to verify it is a valid + * configuration. If it is, we are ready to perform transfers. + */ + if ((response_config.packet_v2.packet_id == + PACKET_ID_V2_RESPONSE_USB_SPI_CONFIG) || + (response_config.packet_size == + sizeof(usb_spi_response_configuration_v2_t))) { + + /* Set the parameters from the configuration. */ + ctx_data->max_spi_write_count = + response_config.packet_v2.response_config.max_write_count; + ctx_data->max_spi_read_count = + response_config.packet_v2.response_config.max_read_count; + return status; + } + + msg_perr("Raiden: Packet is not a valid config\n" + " config attempt = %d\n" + " packet id = %d\n" + " packet size = %d\n", + config_attempt + 1, + response_config.packet_v2.packet_id, + response_config.packet_size); + programmer_delay(RETRY_INTERVAL_US); + } + return USB_SPI_HOST_INIT_FAILURE; +} + +int restart_response_v2(const struct raiden_debug_spi_data *ctx_data) +{ + int status; + + usb_spi_packet_ctx_t restart_response = { + .header_size = sizeof(usb_spi_command_restart_response_v2_t), + .packet_size = sizeof(usb_spi_command_restart_response_v2_t), + .packet_v2.packet_id = PACKET_ID_V2_COMMAND_RESTART_RESPONSE + }; + + status = transmit_packet(ctx_data, &restart_response); + return status; +} + + +int write_command_v2(const struct raiden_debug_spi_data * ctx_data, + usb_spi_transmit_ctx_t* write, + usb_spi_receive_ctx_t* read) +{ + int status; + usb_spi_packet_ctx_t continue_packet; + + usb_spi_packet_ctx_t start_usb_spi_packet = { + .header_size = offsetof(usb_spi_command_v2_t, data), + .packet_v2.command.packet_id = PACKET_ID_V2_COMMAND, + .packet_v2.command.write_count = write->transmit_size, + .packet_v2.command.read_count = read->receive_size + }; + + fill_usb_packet(&start_usb_spi_packet, write); + status = transmit_packet(ctx_data, &start_usb_spi_packet); + if (status) { + return status; + } + + while (write->transmit_index < write->transmit_size) { + /* Transmit any continue packets. */ + continue_packet.header_size = offsetof(usb_spi_continue_v2_t, data); + continue_packet.packet_v2.command_continue.packet_id = + PACKET_ID_V2_COMMAND_CONTINUE; + continue_packet.packet_v2.command_continue.data_index = + write->transmit_index; + + fill_usb_packet(&continue_packet, write); + + status = transmit_packet(ctx_data, &continue_packet); + if (status) { + return status; + } + } + return status; +} + +int read_response_v2(const struct raiden_debug_spi_data * ctx_data, + usb_spi_transmit_ctx_t* write, + usb_spi_receive_ctx_t* read) +{ + int status = -1; + usb_spi_packet_ctx_t response; + + /* Receive the payload to the servo micro. */ + while (read->receive_index < read->receive_size) { + + status = receive_packet(ctx_data, &response); + if (status) { + /* Return the transfer error. */ + return status; + } + if (response.packet_v2.packet_id == PACKET_ID_V2_RESPONSE) { + /* + * The host should only see this packet if an error occurs + * on the device or if it's the first response packet. + */ + if (response.packet_v2.response.status_code) { + return response.packet_v2.response.status_code; + } + if (read->receive_index) { + msg_perr("Raiden: Unexpected packet id = %d", + response.packet_v2.response.packet_id); + return USB_SPI_HOST_RX_UNEXPECTED_PACKET; + } + response.header_size = offsetof(usb_spi_response_v2_t, data); + } if (response.packet_v2.packet_id == + PACKET_ID_V2_RESPONSE_CONTINUE) { + + /* We validate that no packets were missed. */ + if (read->receive_index != + response.packet_v2.response_continue.data_index) { + return USB_SPI_HOST_RX_BAD_DATA_INDEX; + } + response.header_size = offsetof(usb_spi_continue_v2_t, data); + } else { + msg_perr("Raiden: Unexpected packet id = %d", + response.packet_v2.packet_id); + return USB_SPI_HOST_RX_UNEXPECTED_PACKET; + } + status = read_usb_packet(read, &response); + if (status) { + return status; + } + } + return status; +} + static int send_command(const struct flashctx *flash, unsigned int write_count, unsigned int read_count, @@ -464,6 +910,8 @@ write_ctx.transmit_index = 0; if (ctx_data->protocol_version == GOOGLE_RAIDEN_SPI_PROTOCOL_V1) { status = write_command_v1(ctx_data, &write_ctx, &read_ctx); + } else { + status = write_command_v2(ctx_data, &write_ctx, &read_ctx); }
if (status) { @@ -490,6 +938,8 @@ read_ctx.receive_index = 0; if (ctx_data->protocol_version == GOOGLE_RAIDEN_SPI_PROTOCOL_V1) { status = read_response_v1(ctx_data, &write_ctx, &read_ctx); + } else { + status = read_response_v2(ctx_data, &write_ctx, &read_ctx); }
if (status == 0) { @@ -513,6 +963,15 @@ /* Reattempting will not result in a recovery. */ return status; } + /* + * Protocol version 2 includes multi-packet messages, we can + * restart only the response operation without performing SPI + * transfer. + */ + if (ctx_data->protocol_version == + GOOGLE_RAIDEN_SPI_PROTOCOL_V2) { + restart_response_v2(ctx_data); + } programmer_delay(RETRY_INTERVAL_US); } else { /* We were successful at performing the SPI transfer. */ @@ -579,6 +1038,7 @@
static int configure_protocol(struct spi_master *ctx_spi) { + int status = 0; struct raiden_debug_spi_data *ctx_data = (struct raiden_debug_spi_data *)ctx_spi->data;
@@ -593,6 +1053,15 @@ ctx_data->max_spi_write_count= SPI_TRANSFER_V1_MAX; ctx_data->max_spi_read_count = SPI_TRANSFER_V1_MAX; break; + case GOOGLE_RAIDEN_SPI_PROTOCOL_V2: + /* + * Protocol V2 requires the host to query the device for + * it's maximum read and write sizes + */ + status = get_spi_size_v2(ctx_data); + if (status) { + return status; + } default: msg_pdbg("Raiden: Unknown USB SPI protocol version = %d", ctx_data->protocol_version); @@ -692,7 +1161,6 @@ usb_match_value_default(&match.vid, GOOGLE_VID); usb_match_value_default(&match.class, LIBUSB_CLASS_VENDOR_SPEC); usb_match_value_default(&match.subclass, GOOGLE_RAIDEN_SPI_SUBCLASS); - usb_match_value_default(&match.protocol, GOOGLE_RAIDEN_SPI_PROTOCOL_V1);
ret = LIBUSB(libusb_init(NULL)); if (ret != 0) {
Hello build bot (Jenkins), Brian Nemec,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#2).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 471 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/2
Edward O'Callaghan has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2:
(3 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@391 PS2, Line 391: alignment \t \s mixing.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@782 PS2, Line 782: status = return directly and drop the intermediate status var?
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@1063 PS2, Line 1063: indent has spaces not tab
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2: Code-Review+1
(6 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@720 PS2, Line 720: int This variable should be declared out of the loop, c.f. CB:38034
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@726 PS2, Line 726: Replace 8 spaces with a tab?
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@782 PS2, Line 782: status =
return directly and drop the intermediate status var?
Sounds good
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@855 PS2, Line 855: PACKET_ID_V2_RESPONSE_CONTINUE) { This fits on a single line, or is it very close to the limit?
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@913 PS2, Line 913: } else { How about "else if" here?
Actually, I think we should wrap these into functions and error out if the version is invalid
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@977 PS2, Line 977: /* We were successful at performing the SPI transfer. */ Refactoring note (not for this commit): This "else" could be moved to line 947 to drop one indentation level
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2:
(3 comments)
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG@7 PS2, Line 7: Adds Add
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG@9 PS2, Line 9: Adds Add
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@977 PS2, Line 977: /* We were successful at performing the SPI transfer. */
Refactoring note (not for this commit): This "else" could be moved to line 947 to drop one indentati […]
Commented on CB:41532
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2:
(7 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@391 PS2, Line 391:
alignment \t \s mixing.
Ack
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@720 PS2, Line 720: int
This variable should be declared out of the loop, c.f. […]
Ack
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@726 PS2, Line 726:
Replace 8 spaces with a tab?
I'm using spaces to align these multi-line function calls, especially the ones with mutli-line strings. They should have the same level of tabbed indentation.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@782 PS2, Line 782: status =
Sounds good
Ack
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@855 PS2, Line 855: PACKET_ID_V2_RESPONSE_CONTINUE) {
This fits on a single line, or is it very close to the limit?
I think it's 79 (w/ 4 tabs) characters, I'll switch it if it's still reasonable.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@913 PS2, Line 913: } else {
How about "else if" here? […]
I can add these as function pointers in 'struct raiden_debug_spi_data'.
These would then follow this template and no chains are needed.
if (ctx_data->write_command) { ctx_data->write_command(ctx_data, &write_ctx, &read_ctx); } else { /* Raise error */ msg(...) }
The same without the error else state can be done for the restart_response_v2(ctx_data) later on too. If a v3 protocol exists, it just fills in the fields that it uses.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@1063 PS2, Line 1063:
indent has spaces not tab
Ack
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2:
(4 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@854 PS2, Line 854: } if Um, missing an else?
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@855 PS2, Line 855: PACKET_ID_V2_RESPONSE_CONTINUE) {
I think it's 79 (w/ 4 tabs) characters, I'll switch it if it's still reasonable.
right, I have Gerrit configured as 96-character width (coreboot uses that). Not a big deal
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@864 PS2, Line 864: msg_perr("Raiden: Unexpected packet id = %d", Maybe you can swap the if/else branches to drop one indentation level on the currently-if block?
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@913 PS2, Line 913: } else {
I can add these as function pointers in 'struct raiden_debug_spi_data'. […]
Or even, make sure that those function pointers can never be null in the first place. If a programmer does not support an operation, one could have an error-returning stub there instead of a null that needs to be checked all the time
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 2:
(3 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@854 PS2, Line 854: } if
Um, missing an else?
Yup, that vanished somewhere.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@864 PS2, Line 864: msg_perr("Raiden: Unexpected packet id = %d",
Maybe you can swap the if/else branches to drop one indentation level on the currently-if block?
The indentation levels here correspond to a function, a loop, and a single level of conditions, I don't think you can cleanly beat that. There's some blocks above with 2 levels of conditionals, but I don't think it'll be cleaner combining those. I'll do another pass to see if this can be cleaned up during the next round of edits.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@913 PS2, Line 913: } else {
Or even, make sure that those function pointers can never be null in the first place. […]
That applies to the ctx_data->write_command but not supporting a 'restart_response_v2' response isn't an error, just a difference in the protocol. We didn't make the original protocol robust to the those types of USB errors so it never supported recovering in that state without redoing the SPI transfer.
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#3).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 588 insertions(+), 16 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/3
Edward O'Callaghan has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 3:
(2 comments)
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c@722 PS3, Line 722: nd_command_v1(co seems like a change for the previous patches
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c@1108 PS3, Line 1108: NULL, was this tested..? This would clearly break this spi master.
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 3:
(2 comments)
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c@722 PS3, Line 722: nd_command_v1(co
seems like a change for the previous patches
Ack
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c@1108 PS3, Line 1108: NULL,
was this tested..? This would clearly break this spi master.
Yes, it was tested on the version of flashrom in chromeos.
The null pointer is replaced during the initialization phase during the configure_protocol() function call and before we register the spi_master. This pointer will either be set to send_command_v1 or send_command_v2. It only remains a null pointer if initialization fails.
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#4).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 586 insertions(+), 16 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/4
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#5).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 700 insertions(+), 26 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/5
Edward O'Callaghan has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 5: Code-Review+1
(5 comments)
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1024 PS5, Line 1024: transmit no need for the status intermediate, just return transmit_packet() directly.
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1139 PS5, Line 1139: ; \n
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1221 PS5, Line 1221: } \n
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1227 PS5, Line 1227: if (!status) { : if (read_ctx.receive_size == read_ctx.receive_index) { : /* Successful transfer. */ : return status; : } else { : /* Report the error from the failed read. */ : status = USB_SPI_HOST_RX_READ_FAILURE; : } : } : : if (status) { Is this just equivalent to:
``` if (!status && (read_ctx.receive_size == read_ctx.receive_index)) return 0; /* Successful transfer. */
/* Report the error from the failed read. */ status = USB_SPI_HOST_RX_READ_FAILURE;
/* Read operation failed. */ msg_perr("Raiden: Read response failed\n" ... ```
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1257 PS5, Line 1257: } \n
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#6).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 694 insertions(+), 23 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/6
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#7).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 694 insertions(+), 24 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/7
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#8).
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Adds support for USB SPI protocol V2
Adds support for the USB SPI V2 protocol and documentation of it. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 693 insertions(+), 24 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/8
Edward O'Callaghan has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 8: Code-Review+2
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Adds support for USB SPI protocol V2 ......................................................................
Patch Set 10:
(8 comments)
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@7 PS10, Line 7: Adds Add
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@9 PS10, Line 9: Adds Add
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@9 PS10, Line 9: documentation of it its documentation
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@450 PS10, Line 450: #define PAYLOAD_SIZE_V2_START (58) : : #define PAYLOAD_SIZE_V2_RESPONSE (60) : : #define PAYLOAD_SIZE_V2_CONTINUE (60) : : #define PAYLOAD_SIZE_V2_ERROR (60) This is V2, maybe put it next to the other V2 definitions?
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@875 PS10, Line 875: " protocol = %u\n" This isn't aligned with the other definitions
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@930 PS10, Line 930: Double empty line
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@950 PS10, Line 950: unsigned int I'd rather declare loop variables outside of the loop body for compatibility purposes. See CB:38034 for the reasons.
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@1112 PS10, Line 1112: Two spaces
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#11).
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Add support for USB SPI protocol V2
Add support for the USB SPI V2 protocol and its documentation. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged, larger SPI transfers, and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 672 insertions(+), 12 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/11
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 11:
(7 comments)
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@7 PS10, Line 7: Adds
Add
Done
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@9 PS10, Line 9: Adds
Add
Done
https://review.coreboot.org/c/flashrom/+/41533/10//COMMIT_MSG@9 PS10, Line 9: documentation of it
its documentation
Done
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@875 PS10, Line 875: " protocol = %u\n"
This isn't aligned with the other definitions
Done
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@930 PS10, Line 930:
Double empty line
Done
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@950 PS10, Line 950: unsigned int
I'd rather declare loop variables outside of the loop body for compatibility purposes. […]
Done
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@1112 PS10, Line 1112:
Two spaces
Done
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 11:
(1 comment)
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/10/raiden_debug_spi.c@450 PS10, Line 450: #define PAYLOAD_SIZE_V2_START (58) : : #define PAYLOAD_SIZE_V2_RESPONSE (60) : : #define PAYLOAD_SIZE_V2_CONTINUE (60) : : #define PAYLOAD_SIZE_V2_ERROR (60)
This is V2, maybe put it next to the other V2 definitions?
Done
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 12:
(9 comments)
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG@7 PS2, Line 7: Adds
Add
Done
https://review.coreboot.org/c/flashrom/+/41533/2//COMMIT_MSG@9 PS2, Line 9: Adds
Add
Done
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@726 PS2, Line 726:
I'm using spaces to align these multi-line function calls, especially the ones with mutli-line strin […]
Ack.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@854 PS2, Line 854: } if
Yup, that vanished somewhere.
Done
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@864 PS2, Line 864: msg_perr("Raiden: Unexpected packet id = %d",
The indentation levels here correspond to a function, a loop, and a single level of conditions, I do […]
Ah, since the `else` was indeed missing, swapping the branches isn't really doable.
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@913 PS2, Line 913: } else {
That applies to the ctx_data->write_command but not supporting a 'restart_response_v2' response isn' […]
Ack
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/3/raiden_debug_spi.c@1108 PS3, Line 1108: NULL,
Yes, it was tested on the version of flashrom in chromeos. […]
Ack (I don't like null pointers, but we can handle it in a separate patch)
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1024 PS5, Line 1024: transmit
no need for the status intermediate, just return transmit_packet() directly.
Done
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1139 PS5, Line 1139: ;
\n
Done
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 12: Code-Review+1
(3 comments)
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1154 PS12, Line 1154: write_attempt = 0 I'd prefer to keep the initialization inside the loop head, but keep the declaration here:
unsigned int write_attempt;
Then:
for (write_attempt = 0; write_attempt < WRITE_RETRY_ATTEMPTS; write_attempt++) {
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1212 PS12, Line 1212: for (; read_attempt < READ_RETRY_ATTEMPTS; : read_attempt++) { Here you definitely want to initialize the variable in the loop head:
for (read_attempt = 0; read_attempt < READ_RETRY_ATTEMPTS; read_attempt++) {
Also add a newline before
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1338 PS12, Line 1338: it's nit: possessive `its`
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#13).
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Add support for USB SPI protocol V2
Add support for the USB SPI V2 protocol and its documentation. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged, larger SPI transfers, and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 672 insertions(+), 12 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/13
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 14:
(3 comments)
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/2/raiden_debug_spi.c@726 PS2, Line 726:
I'm using spaces to align these multi-line function calls, especially the ones with mutli-line strin […]
Ack
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1154 PS12, Line 1154: write_attempt = 0
I'd prefer to keep the initialization inside the loop head, but keep the declaration here: […]
Done
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1212 PS12, Line 1212: for (; read_attempt < READ_RETRY_ATTEMPTS; : read_attempt++) {
Here you definitely want to initialize the variable in the loop head: […]
Done
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 14: Code-Review+1
(2 comments)
Note that there's some unresolved comments in older patchsets. Would be good to revise them.
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1154 PS12, Line 1154: write_attempt = 0
I'd prefer to keep the initialization inside the loop head, but keep the declaration here: […]
Done
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1212 PS12, Line 1212: for (; read_attempt < READ_RETRY_ATTEMPTS; : read_attempt++) {
Here you definitely want to initialize the variable in the loop head: […]
Done
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#15).
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Add support for USB SPI protocol V2
Add support for the USB SPI V2 protocol and its documentation. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged, larger SPI transfers, and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 672 insertions(+), 12 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/15
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 15:
(4 comments)
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1221 PS5, Line 1221: }
\n
Done
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1227 PS5, Line 1227: if (!status) { : if (read_ctx.receive_size == read_ctx.receive_index) { : /* Successful transfer. */ : return status; : } else { : /* Report the error from the failed read. */ : status = USB_SPI_HOST_RX_READ_FAILURE; : } : } : : if (status) {
Is this just equivalent to: […]
Not quite, I only want to replace the status flag in the branch where no errors were reported.
https://review.coreboot.org/c/flashrom/+/41533/5/raiden_debug_spi.c@1257 PS5, Line 1257: }
\n
Done
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/12/raiden_debug_spi.c@1338 PS12, Line 1338: it's
nit: possessive `its`
Done
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 15: Code-Review+1
(2 comments)
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c@939 PS15, Line 939: ; nit: space after ;
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c@1089 PS15, Line 1089: its here, it's the contraction of "it is": it's
Hello build bot (Jenkins), Brian Nemec, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/41533
to look at the new patch set (#16).
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Add support for USB SPI protocol V2
Add support for the USB SPI V2 protocol and its documentation. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged, larger SPI transfers, and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec --- M raiden_debug_spi.c 1 file changed, 672 insertions(+), 12 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/33/41533/16
Brian Nemec has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 16:
(2 comments)
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c File raiden_debug_spi.c:
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c@939 PS15, Line 939: ;
nit: space after ;
Done
https://review.coreboot.org/c/flashrom/+/41533/15/raiden_debug_spi.c@1089 PS15, Line 1089: its
here, it's the contraction of "it is": it's
Done
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 16: Code-Review+2
Edward O'Callaghan has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
Patch Set 18: Code-Review+2
Edward O'Callaghan has submitted this change. ( https://review.coreboot.org/c/flashrom/+/41533 )
Change subject: raiden_debug_spi.c: Add support for USB SPI protocol V2 ......................................................................
raiden_debug_spi.c: Add support for USB SPI protocol V2
Add support for the USB SPI V2 protocol and its documentation. The protocol version number uses the bInterfaceProtocol field in USB to identify which device to use, this enables us to support both V1 and V2 with the same host.
The USB SPI V2 protocol adds the ability to perform multi-packet USB SPI transfers. This results in fewer USB messages exchanged, larger SPI transfers, and faster flashing speeds.
BUG=b:139058552 BRANCH=none TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V1 protocol device TEST=Manual testing of ServoMicro and Flashrom when performing reads, writes, and verification of the EC firmware on Nami with a USB SPI V2 protocol device TEST=Builds
Signed-off-by: Brian J. Nemec bnemec@chromium.com Change-Id: Ie356c63b521c0cc11a4946ffac128ec7139f0bec Reviewed-on: https://review.coreboot.org/c/flashrom/+/41533 Reviewed-by: Edward O'Callaghan quasisec@chromium.org Reviewed-by: Angel Pons th3fanbus@gmail.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M raiden_debug_spi.c 1 file changed, 672 insertions(+), 12 deletions(-)
Approvals: build bot (Jenkins): Verified Angel Pons: Looks good to me, approved Edward O'Callaghan: Looks good to me, approved
diff --git a/raiden_debug_spi.c b/raiden_debug_spi.c index d677384..b8e19fe 100644 --- a/raiden_debug_spi.c +++ b/raiden_debug_spi.c @@ -110,6 +110,222 @@ * of bytes unless this is the final packet. * * + * USB SPI Version 2: + * + * USB SPI version 2 adds support for larger SPI transfers and reduces the + * number of USB packets transferred. This improves performance when + * writing or reading large chunks of memory from a device. A packet ID + * field is used to distinguish the different packet types. Additional + * packets have been included to query the device for its configuration + * allowing the interface to be used on platforms with different SPI + * limitations. It includes validation and a packet to recover from the + * situations where USB packets are lost. + * + * The USB SPI hosts which support packet version 2 are backwards compatible + * and use the bInterfaceProtocol field to identify which type of target + * they are connected to. + * + * + * Example: USB SPI request with 128 byte write and 0 byte read. + * + * Packet #1 Host to Device: + * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START + * write count = 128 + * read count = 0 + * payload = First 58 bytes from the write buffer, + * starting at byte 0 in the buffer + * packet size = 64 bytes + * + * Packet #2 Host to Device: + * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE + * data index = 58 + * payload = Next 60 bytes from the write buffer, + * starting at byte 58 in the buffer + * packet size = 64 bytes + * + * Packet #3 Host to Device: + * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE + * data index = 118 + * payload = Next 10 bytes from the write buffer, + * starting at byte 118 in the buffer + * packet size = 14 bytes + * + * Packet #4 Device to Host: + * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START + * status code = status code from device + * payload = 0 bytes + * packet size = 4 bytes + * + * Example: USB SPI request with 2 byte write and 100 byte read. + * + * Packet #1 Host to Device: + * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START + * write count = 2 + * read count = 100 + * payload = The 2 byte write buffer + * packet size = 8 bytes + * + * Packet #2 Device to Host: + * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START + * status code = status code from device + * payload = First 60 bytes from the read buffer, + * starting at byte 0 in the buffer + * packet size = 64 bytes + * + * Packet #3 Device to Host: + * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE + * data index = 60 + * payload = Next 40 bytes from the read buffer, + * starting at byte 60 in the buffer + * packet size = 44 bytes + * + * + * Message Packets: + * + * Command Start Packet (Host to Device): + * + * Start of the USB SPI command, contains the number of bytes to write + * and read on SPI and up to the first 58 bytes of write payload. + * Longer writes will use the continue packets with packet id + * USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data. + * + * +----------------+------------------+-----------------+---------------+ + * | packet id : 2B | write count : 2B | read count : 2B | w.p. : <= 58B | + * +----------------+------------------+-----------------+---------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * Valid values packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START + * + * write count: 2 byte, zero based count of bytes to write + * + * read count: 2 byte, zero based count of bytes to read + * UINT16_MAX indicates full duplex mode with a read count + * equal to the write count. + * + * write payload: Up to 58 bytes of data to write to SPI, the total + * length of all TX packets must match write count. + * Due to data alignment constraints, this must be an + * even number of bytes unless this is the final packet. + * + * + * Response Start Packet (Device to Host): + * + * Start of the USB SPI response, contains the status code and up to + * the first 60 bytes of read payload. Longer reads will use the + * continue packets with packet id USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE + * to transmit the remaining data. + * + * +----------------+------------------+-----------------------+ + * | packet id : 2B | status code : 2B | read payload : <= 60B | + * +----------------+------------------+-----------------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * Valid values packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START + * + * status code: 2 byte status code + * 0x0000: Success + * 0x0001: SPI timeout + * 0x0002: Busy, try again + * This can happen if someone else has acquired the shared memory + * buffer that the SPI driver uses as /dev/null + * 0x0003: Write count invalid. The byte limit is platform specific + * and is set during the configure USB SPI response. + * 0x0004: Read count invalid. The byte limit is platform specific + * and is set during the configure USB SPI response. + * 0x0005: The SPI bridge is disabled. + * 0x0006: The RX continue packet's data index is invalid. This + * can indicate a USB transfer failure to the device. + * 0x0007: The RX endpoint has received more data than write count. + * This can indicate a USB transfer failure to the device. + * 0x0008: An unexpected packet arrived that the device could not + * process. + * 0x0009: The device does not support full duplex mode. + * 0x8000: Unknown error mask + * The bottom 15 bits will contain the bottom 15 bits from the EC + * error code. + * + * read payload: Up to 60 bytes of data read from SPI, the total + * length of all RX packets must match read count + * unless an error status was returned. Due to data + * alignment constraints, this must be a even number + * of bytes unless this is the final packet. + * + * + * Continue Packet (Bidirectional): + * + * Continuation packet for the writes and read buffers. Both packets + * follow the same format, a data index counts the number of bytes + * previously transferred in the USB SPI transfer and a payload of bytes. + * + * +----------------+-----------------+-------------------------------+ + * | packet id : 2B | data index : 2B | write / read payload : <= 60B | + * +----------------+-----------------+-------------------------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * The packet id has 2 values depending on direction: + * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE + * indicates the packet is being transmitted from the host + * to the device and contains SPI write payload. + * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE + * indicates the packet is being transmitted from the device + * to the host and contains SPI read payload. + * + * data index: The data index indicates the number of bytes in the + * read or write buffers that have already been transmitted. + * It is used to validate that no packets have been dropped + * and that the prior packets have been correctly decoded. + * This value corresponds to the offset bytes in the buffer + * to start copying the payload into. + * + * read and write payload: + * Contains up to 60 bytes of payload data to transfer to + * the SPI write buffer or from the SPI read buffer. + * + * + * Command Get Configuration Packet (Host to Device): + * + * Query the device to request its USB SPI configuration indicating + * the number of bytes it can write and read. + * + * +----------------+ + * | packet id : 2B | + * +----------------+ + * + * packet id: 2 byte enum USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG + * + * Response Configuration Packet (Device to Host): + * + * Response packet form the device to report the maximum write and + * read size supported by the device. + * + * +----------------+----------------+---------------+----------------+ + * | packet id : 2B | max write : 2B | max read : 2B | feature bitmap | + * +----------------+----------------+---------------+----------------+ + * + * packet id: 2 byte enum USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG + * + * max write count: 2 byte count of the maximum number of bytes + * the device can write to SPI in one transaction. + * + * max read count: 2 byte count of the maximum number of bytes + * the device can read from SPI in one transaction. + * + * feature bitmap: Bitmap of supported features. + * BIT(0): Full duplex SPI mode is supported + * BIT(1:15): Reserved for future use + * + * Command Restart Response Packet (Host to Device): + * + * Command to restart the response transfer from the device. This enables + * the host to recover from a lost packet when reading the response + * without restarting the SPI transfer. + * + * +----------------+ + * | packet id : 2B | + * +----------------+ + * + * packet id: 2 byte enum USB_SPI_PKT_ID_CMD_RESTART_RESPONSE + * * USB Error Codes: * * send_command return codes have the following format: @@ -171,6 +387,14 @@ USB_SPI_WRITE_COUNT_INVALID = 0x0003, USB_SPI_READ_COUNT_INVALID = 0x0004, USB_SPI_DISABLED = 0x0005, + /* The RX continue packet's data index is invalid. */ + USB_SPI_RX_BAD_DATA_INDEX = 0x0006, + /* The RX endpoint has received more data than write count. */ + USB_SPI_RX_DATA_OVERFLOW = 0x0007, + /* An unexpected packet arrived on the device. */ + USB_SPI_RX_UNEXPECTED_PACKET = 0x0008, + /* The device does not support full duplex mode. */ + USB_SPI_UNSUPPORTED_FULL_DUPLEX = 0x0009, USB_SPI_UNKNOWN_ERROR = 0x8000, };
@@ -181,20 +405,16 @@ RAIDEN_DEBUG_SPI_REQ_ENABLE_EC = 0x0003, };
-#define PACKET_HEADER_SIZE (2) -#define USB_MAX_PACKET_SIZE (64) -#define PAYLOAD_SIZE_V1 (USB_MAX_PACKET_SIZE - PACKET_HEADER_SIZE) -#define SPI_TRANSFER_V1_MAX (PAYLOAD_SIZE_V1) - /* * 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_RETRY_ATTEMPTS (3) -#define READ_RETRY_ATTEMPTS (3) -#define RETRY_INTERVAL_US (100 * 1000) +#define WRITE_RETRY_ATTEMPTS (3) +#define READ_RETRY_ATTEMPTS (3) +#define GET_CONFIG_RETRY_ATTEMPTS (3) +#define RETRY_INTERVAL_US (100 * 1000)
/* * This timeout is so large because the Raiden SPI timeout is 800ms. @@ -215,6 +435,18 @@ uint16_t max_spi_write_count; uint16_t max_spi_read_count; }; +/* + * USB permits a maximum bulk transfer of 64B. + */ +#define USB_MAX_PACKET_SIZE (64) +#define PACKET_HEADER_SIZE (2) + +/* + * All of the USB SPI packets have size equal to the max USB packet size of 64B + */ +#define PAYLOAD_SIZE_V1 (62) + +#define SPI_TRANSFER_V1_MAX (PAYLOAD_SIZE_V1)
/* * Version 1 protocol specific attributes @@ -237,10 +469,90 @@ struct usb_spi_response_v1 response; } __attribute__((packed));
+/* + * Version 2 protocol specific attributes + */ + +#define USB_SPI_FULL_DUPLEX_ENABLED_V2 (UINT16_MAX) + +#define USB_SPI_PAYLOAD_SIZE_V2_START (58) + +#define USB_SPI_PAYLOAD_SIZE_V2_RESPONSE (60) + +#define USB_SPI_PAYLOAD_SIZE_V2_CONTINUE (60) + +enum packet_id_type { + /* Request USB SPI configuration data from device. */ + USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG = 0, + /* USB SPI configuration data from device. */ + USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG = 1, + /* + * Start a USB SPI transfer specifying number of bytes to write, + * read and deliver first packet of data to write. + */ + USB_SPI_PKT_ID_CMD_TRANSFER_START = 2, + /* Additional packets containing write payload. */ + USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE = 3, + /* + * Request the device restart the response enabling us to recover + * from packet loss without another SPI transfer. + */ + USB_SPI_PKT_ID_CMD_RESTART_RESPONSE = 4, + /* + * First packet of USB SPI response with the status code + * and read payload if it was successful. + */ + USB_SPI_PKT_ID_RSP_TRANSFER_START = 5, + /* Additional packets containing read payload. */ + USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE = 6, +}; + +enum feature_bitmap { + /* Indicates the platform supports full duplex mode. */ + USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = 0x01 +}; + +struct usb_spi_response_configuration_v2 { + uint16_t packet_id; + uint16_t max_write_count; + uint16_t max_read_count; + uint16_t feature_bitmap; +} __attribute__((packed)); + +struct usb_spi_command_v2 { + uint16_t packet_id; + uint16_t write_count; + /* UINT16_MAX Indicates readback all on halfduplex compliant devices. */ + uint16_t read_count; + uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_START]; +} __attribute__((packed)); + +struct usb_spi_response_v2 { + uint16_t packet_id; + uint16_t status_code; + uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_RESPONSE]; +} __attribute__((packed)); + +struct usb_spi_continue_v2 { + uint16_t packet_id; + uint16_t data_index; + uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_CONTINUE]; +} __attribute__((packed)); + +union usb_spi_packet_v2 { + uint16_t packet_id; + struct usb_spi_command_v2 cmd_start; + struct usb_spi_continue_v2 cmd_continue; + struct usb_spi_response_configuration_v2 rsp_config; + struct usb_spi_response_v2 rsp_start; + struct usb_spi_continue_v2 rsp_continue; +} __attribute__((packed)); + struct usb_spi_packet_ctx { union { uint8_t bytes[USB_MAX_PACKET_SIZE]; union usb_spi_packet_v1 packet_v1; + union usb_spi_packet_v2 packet_v2; }; /* * By storing the number of bytes in the header and knowing that the @@ -549,12 +861,13 @@ if (status) { /* Write operation failed. */ msg_perr("Raiden: Write command failed\n" + " protocol = %u\n" " write count = %u\n" " read count = %u\n" " transmitted bytes = %zu\n" " write attempt = %u\n" " status = 0x%05x\n", - + ctx_data->protocol_version, write_count, read_count, write_ctx.transmit_index, write_attempt + 1, status); if (!retry_recovery(status)) { @@ -564,6 +877,7 @@ programmer_delay(RETRY_INTERVAL_US); continue; } + for (unsigned int read_attempt = 0; read_attempt < READ_RETRY_ATTEMPTS; read_attempt++) {
@@ -579,21 +893,356 @@ } }
+ /* Read operation failed. */ + msg_perr("Raiden: Read response failed\n" + " protocol = %u\n" + " write count = %u\n" + " read count = %u\n" + " received bytes = %zu\n" + " write attempt = %u\n" + " read attempt = %u\n" + " status = 0x%05x\n", + ctx_data->protocol_version, + write_count, read_count, read_ctx.receive_index, + write_attempt + 1, read_attempt + 1, status); + if (!retry_recovery(status)) { + /* Reattempting will not result in a recovery. */ + return status; + } + programmer_delay(RETRY_INTERVAL_US); + } + } + + return status; +} + +/* + * Get the USB SPI configuration with the maximum write and read counts, and + * any enabled features. + * + * @param ctx_data Raiden SPI config. + * + * @returns Returns status code with 0 on success. + */ +static int get_spi_config_v2(struct raiden_debug_spi_data *ctx_data) +{ + int status; + unsigned int config_attempt; + struct usb_spi_packet_ctx rsp_config; + + struct usb_spi_packet_ctx cmd_get_config = { + .header_size = PACKET_HEADER_SIZE, + .packet_size = PACKET_HEADER_SIZE, + .packet_v2.packet_id = USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG + }; + + for (config_attempt = 0; config_attempt < GET_CONFIG_RETRY_ATTEMPTS; config_attempt++) { + + status = transmit_packet(ctx_data, &cmd_get_config); + if (status) { + msg_perr("Raiden: Failed to transmit get config\n" + " config attempt = %d\n" + " status = 0x%05x\n", + config_attempt + 1, status); + programmer_delay(RETRY_INTERVAL_US); + continue; + } + + status = receive_packet(ctx_data, &rsp_config); + if (status) { + msg_perr("Raiden: Failed to receive packet\n" + " config attempt = %d\n" + " status = 0x%05x\n", + config_attempt + 1, status); + programmer_delay(RETRY_INTERVAL_US); + continue; + } + + /* + * Perform validation on the packet received to verify it is a valid + * configuration. If it is, we are ready to perform transfers. + */ + if ((rsp_config.packet_v2.packet_id == + USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG) || + (rsp_config.packet_size == + sizeof(struct usb_spi_response_configuration_v2))) { + + /* Set the parameters from the configuration. */ + ctx_data->max_spi_write_count = + rsp_config.packet_v2.rsp_config.max_write_count; + ctx_data->max_spi_read_count = + rsp_config.packet_v2.rsp_config.max_read_count; + return status; + } + + msg_perr("Raiden: Packet is not a valid config\n" + " config attempt = %d\n" + " packet id = %u\n" + " packet size = %zu\n", + config_attempt + 1, + rsp_config.packet_v2.packet_id, + rsp_config.packet_size); + programmer_delay(RETRY_INTERVAL_US); + } + return USB_SPI_HOST_INIT_FAILURE; +} + +/* + * Version 2 protocol restart the SPI response. This allows us to recover from + * USB packet errors without restarting the SPI transfer. + * + * @param ctx_data Raiden SPI config. + * + * @returns Returns status code with 0 on success. + */ +static int restart_response_v2(const struct raiden_debug_spi_data *ctx_data) +{ + struct usb_spi_packet_ctx restart_response = { + .header_size = PACKET_HEADER_SIZE, + .packet_size = PACKET_HEADER_SIZE, + .packet_v2.packet_id = USB_SPI_PKT_ID_CMD_RESTART_RESPONSE + }; + + return transmit_packet(ctx_data, &restart_response); +} + +/* + * Version 2 Protocol: command to start a USB SPI transfer and write the payload. + * + * @param ctx_data Raiden SPI config. + * @param write Write context of data to transmit and write payload. + * @param read Read context of data to receive and read buffer. + * + * @returns Returns status code with 0 on success. + */ +static int write_command_v2(const struct raiden_debug_spi_data *ctx_data, + struct usb_spi_transmit_ctx *write, + struct usb_spi_receive_ctx *read) +{ + int status; + struct usb_spi_packet_ctx continue_packet; + + struct usb_spi_packet_ctx start_usb_spi_packet = { + .header_size = offsetof(struct usb_spi_command_v2, data), + .packet_v2.cmd_start.packet_id = USB_SPI_PKT_ID_CMD_TRANSFER_START, + .packet_v2.cmd_start.write_count = write->transmit_size, + .packet_v2.cmd_start.read_count = read->receive_size + }; + + /* Reset the write context to the start. */ + write->transmit_index = 0; + + fill_usb_packet(&start_usb_spi_packet, write); + status = transmit_packet(ctx_data, &start_usb_spi_packet); + if (status) { + return status; + } + + while (write->transmit_index < write->transmit_size) { + /* Transmit any continue packets. */ + continue_packet.header_size = offsetof(struct usb_spi_continue_v2, data); + continue_packet.packet_v2.cmd_continue.packet_id = + USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE; + continue_packet.packet_v2.cmd_continue.data_index = + write->transmit_index; + + fill_usb_packet(&continue_packet, write); + + status = transmit_packet(ctx_data, &continue_packet); + if (status) { + return status; + } + } + + return status; +} + +/* + * Version 2 Protocol: Command to read a USB SPI transfer response and read the payload. + * + * @param ctx_data Raiden SPI config. + * @param write Write context of data to transmit and write payload. + * @param read Read context of data to receive and read buffer. + * + * @returns Returns status code with 0 on success. + */ +static int read_response_v2(const struct raiden_debug_spi_data *ctx_data, + struct usb_spi_transmit_ctx *write, + struct usb_spi_receive_ctx *read) +{ + int status = -1; + struct usb_spi_packet_ctx response; + + /* Reset the read context to the start. */ + read->receive_index = 0; + + /* Receive the payload to the servo micro. */ + do { + status = receive_packet(ctx_data, &response); + if (status) { + /* Return the transfer error. */ + return status; + } + if (response.packet_v2.packet_id == USB_SPI_PKT_ID_RSP_TRANSFER_START) { + /* + * The host should only see this packet if an error occurs + * on the device or if it's the first response packet. + */ + if (response.packet_v2.rsp_start.status_code) { + return response.packet_v2.rsp_start.status_code; + } + if (read->receive_index) { + msg_perr("Raiden: Unexpected start packet id = %u\n", + response.packet_v2.rsp_start.packet_id); + return USB_SPI_HOST_RX_UNEXPECTED_PACKET; + } + response.header_size = offsetof(struct usb_spi_response_v2, data); + } else if (response.packet_v2.packet_id == + USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE) { + + /* We validate that no packets were missed. */ + if (read->receive_index != + response.packet_v2.rsp_continue.data_index) { + msg_perr("Raiden: Bad Index = %u Expected = %zu\n", + response.packet_v2.rsp_continue.data_index, + read->receive_index); + return USB_SPI_HOST_RX_BAD_DATA_INDEX; + } + response.header_size = offsetof(struct usb_spi_continue_v2, data); + } else { + msg_perr("Raiden: Unexpected packet id = %u\n", + response.packet_v2.packet_id); + return USB_SPI_HOST_RX_UNEXPECTED_PACKET; + } + status = read_usb_packet(read, &response); + if (status) { + return status; + } + } while (read->receive_index < read->receive_size); + + return status; +} + +/* + * Version 2 Protocol: Sets up a USB SPI transfer, transmits data to the device, + * reads the status code and any payload from the device. This will also handle + * recovery if an error has occurred. + * + * In order to avoid having the v2 protocol held back by requiring + * backwards compatibility with v1 we are duplicating the send_command + * function. This will allow the 2 versions to diverge in the future + * so fixes in one do not need to be compatible with the legacy. + * + * @param flash Flash context storing SPI capabilities and USB device + * information. + * @param write_count Number of bytes to write + * @param read_count Number of bytes to read + * @param write_buffer Address of write buffer + * @param read_buffer Address of buffer to store read data + * + * @returns Returns status code with 0 on success. + */ +static int send_command_v2(const struct flashctx *flash, + unsigned int write_count, + unsigned int read_count, + const unsigned char *write_buffer, + unsigned char *read_buffer) +{ + const struct raiden_debug_spi_data *ctx_data = + get_raiden_data_from_context(flash); + int status = -1; + unsigned int write_attempt; + unsigned int read_attempt; + + struct usb_spi_transmit_ctx write_ctx = { + .buffer = write_buffer, + .transmit_size = write_count + }; + struct usb_spi_receive_ctx read_ctx = { + .buffer = read_buffer, + .receive_size = read_count + }; + + if (write_count > ctx_data->max_spi_write_count) { + msg_perr("Raiden: Invalid write count\n" + " write count = %u\n" + " max write = %u\n", + write_count, ctx_data->max_spi_write_count); + return SPI_INVALID_LENGTH; + } + + if (read_count > ctx_data->max_spi_read_count) { + msg_perr("Raiden: Invalid read count\n" + " read count = %u\n" + " max read = %u\n", + read_count, ctx_data->max_spi_read_count); + return SPI_INVALID_LENGTH; + } + + for (write_attempt = 0; write_attempt < WRITE_RETRY_ATTEMPTS; + write_attempt++) { + + status = write_command_v2(ctx_data, &write_ctx, &read_ctx); + + if (!status && + (write_ctx.transmit_index != write_ctx.transmit_size)) { + /* No errors were reported, but write is incomplete. */ + status = USB_SPI_HOST_TX_WRITE_FAILURE; + } + + if (status) { + /* Write operation failed. */ + msg_perr("Raiden: Write command failed\n" + " protocol = %u\n" + " write count = %u\n" + " read count = %u\n" + " transmitted bytes = %zu\n" + " write attempt = %u\n" + " status = 0x%05x\n", + ctx_data->protocol_version, + write_count, read_count, write_ctx.transmit_index, + write_attempt + 1, status); + if (!retry_recovery(status)) { + /* Reattempting will not result in a recovery. */ + return status; + } + programmer_delay(RETRY_INTERVAL_US); + continue; + } + for (read_attempt = 0; read_attempt < READ_RETRY_ATTEMPTS; + read_attempt++) { + + status = read_response_v2(ctx_data, &write_ctx, &read_ctx); + + if (!status) { + if (read_ctx.receive_size == read_ctx.receive_index) { + /* Successful transfer. */ + return status; + } else { + /* Report the error from the failed read. */ + status = USB_SPI_HOST_RX_READ_FAILURE; + } + } + if (status) { /* Read operation failed. */ msg_perr("Raiden: Read response failed\n" + " protocol = %u\n" " write count = %u\n" " read count = %u\n" " received bytes = %zu\n" " write attempt = %u\n" " read attempt = %u\n" " status = 0x%05x\n", + ctx_data->protocol_version, write_count, read_count, read_ctx.receive_index, write_attempt + 1, read_attempt + 1, status); if (!retry_recovery(status)) { /* Reattempting will not result in a recovery. */ return status; } + /* Device needs to reset its transmit index. */ + restart_response_v2(ctx_data); programmer_delay(RETRY_INTERVAL_US); } } @@ -666,6 +1315,7 @@ */ static int configure_protocol(struct spi_master *spi_config) { + int status = 0; struct raiden_debug_spi_data *ctx_data = (struct raiden_debug_spi_data *)spi_config->data;
@@ -682,9 +1332,20 @@ ctx_data->max_spi_write_count = SPI_TRANSFER_V1_MAX; ctx_data->max_spi_read_count = SPI_TRANSFER_V1_MAX; break; + case GOOGLE_RAIDEN_SPI_PROTOCOL_V2: + /* + * Protocol V2 requires the host to query the device for + * its maximum read and write sizes + */ + spi_config->command = send_command_v2; + status = get_spi_config_v2(ctx_data); + if (status) { + return status; + } + break; default: - msg_pdbg("Raiden: Unknown USB SPI protocol version = %d", - ctx_data->protocol_version); + msg_pdbg("Raiden: Unknown USB SPI protocol version = %u\n", + ctx_data->protocol_version); return USB_SPI_HOST_INIT_FAILURE; }
@@ -788,7 +1449,6 @@ usb_match_value_default(&match.vid, GOOGLE_VID); usb_match_value_default(&match.class, LIBUSB_CLASS_VENDOR_SPEC); usb_match_value_default(&match.subclass, GOOGLE_RAIDEN_SPI_SUBCLASS); - usb_match_value_default(&match.protocol, GOOGLE_RAIDEN_SPI_PROTOCOL_V1);
ret = LIBUSB(libusb_init(NULL)); if (ret != 0) {