blob: 92779fc5f8469be3d99aed23c61637bfc129bb01 [file] [log] [blame]
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright 2014, Google Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following disclaimer
15 * in the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Google Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Alternatively, this software may be distributed under the terms of the
34 * GNU General Public License ("GPL") version 2 as published by the Free
35 * Software Foundation.
36 */
37
38/*
39 * This SPI flash programming interface is designed to talk to a Chromium OS
40 * device over a Raiden USB connection. The USB connection is routed to a
41 * microcontroller running an image compiled from:
42 *
43 * https://chromium.googlesource.com/chromiumos/platform/ec
44 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070045 * The protocol for the USB-SPI bridge is implemented in the following files
46 * in that repository:
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110047 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070048 * chip/stm32/usb_spi.h
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110049 * chip/stm32/usb_spi.c
50 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070051 * bInterfaceProtocol determines which protocol is used by the USB SPI device.
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110052 *
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110053 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070054 * USB SPI Version 1:
55 *
56 * SPI transactions of up to 62B in each direction with every command having
57 * a response. The initial packet from host contains a 2B header indicating
58 * write and read counts with an optional payload length equal to the write
59 * count. The device will respond with a message that reports the 2B status
60 * code and an optional payload response length equal to read count.
61 *
62 *
63 * Message Packets:
64 *
65 * Command First Packet (Host to Device):
66 *
67 * USB SPI command, containing the number of bytes to write and read
68 * and a payload of bytes to write.
69 *
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110070 * +------------------+-----------------+------------------------+
71 * | write count : 1B | read count : 1B | write payload : <= 62B |
72 * +------------------+-----------------+------------------------+
73 *
74 * write count: 1 byte, zero based count of bytes to write
75 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070076 * read count: 1 byte, zero based count of bytes to read. Full duplex
77 * mode is enabled with UINT8_MAX
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110078 *
79 * write payload: Up to 62 bytes of data to write to SPI, the total
80 * length of all TX packets must match write count.
81 * Due to data alignment constraints, this must be an
82 * even number of bytes unless this is the final packet.
83 *
Brian J. Nemec7a887802020-07-17 11:20:33 -070084 * Response Packet (Device to Host):
85 *
86 * USB SPI response, containing the status code and any bytes of the
87 * read payload.
88 *
Edward O'Callaghanad08aef2020-03-02 18:16:14 +110089 * +-------------+-----------------------+
90 * | status : 2B | read payload : <= 62B |
91 * +-------------+-----------------------+
92 *
93 * status: 2 byte status
94 * 0x0000: Success
95 * 0x0001: SPI timeout
96 * 0x0002: Busy, try again
97 * This can happen if someone else has acquired the shared memory
98 * buffer that the SPI driver uses as /dev/null
Brian J. Nemec7a887802020-07-17 11:20:33 -070099 * 0x0003: Write count invalid (over 62 bytes)
100 * 0x0004: Read count invalid (over 62 bytes)
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100101 * 0x0005: The SPI bridge is disabled.
102 * 0x8000: Unknown error mask
103 * The bottom 15 bits will contain the bottom 15 bits from the EC
104 * error code.
105 *
106 * read payload: Up to 62 bytes of data read from SPI, the total
107 * length of all RX packets must match read count
108 * unless an error status was returned. Due to data
109 * alignment constraints, this must be a even number
110 * of bytes unless this is the final packet.
111 *
Brian J. Nemec7a887802020-07-17 11:20:33 -0700112 *
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700113 * USB SPI Version 2:
114 *
115 * USB SPI version 2 adds support for larger SPI transfers and reduces the
116 * number of USB packets transferred. This improves performance when
117 * writing or reading large chunks of memory from a device. A packet ID
118 * field is used to distinguish the different packet types. Additional
119 * packets have been included to query the device for its configuration
120 * allowing the interface to be used on platforms with different SPI
121 * limitations. It includes validation and a packet to recover from the
122 * situations where USB packets are lost.
123 *
124 * The USB SPI hosts which support packet version 2 are backwards compatible
125 * and use the bInterfaceProtocol field to identify which type of target
126 * they are connected to.
127 *
128 *
129 * Example: USB SPI request with 128 byte write and 0 byte read.
130 *
131 * Packet #1 Host to Device:
132 * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START
133 * write count = 128
134 * read count = 0
135 * payload = First 58 bytes from the write buffer,
136 * starting at byte 0 in the buffer
137 * packet size = 64 bytes
138 *
139 * Packet #2 Host to Device:
140 * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
141 * data index = 58
142 * payload = Next 60 bytes from the write buffer,
143 * starting at byte 58 in the buffer
144 * packet size = 64 bytes
145 *
146 * Packet #3 Host to Device:
147 * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
148 * data index = 118
149 * payload = Next 10 bytes from the write buffer,
150 * starting at byte 118 in the buffer
151 * packet size = 14 bytes
152 *
153 * Packet #4 Device to Host:
154 * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START
155 * status code = status code from device
156 * payload = 0 bytes
157 * packet size = 4 bytes
158 *
159 * Example: USB SPI request with 2 byte write and 100 byte read.
160 *
161 * Packet #1 Host to Device:
162 * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START
163 * write count = 2
164 * read count = 100
165 * payload = The 2 byte write buffer
166 * packet size = 8 bytes
167 *
168 * Packet #2 Device to Host:
169 * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START
170 * status code = status code from device
171 * payload = First 60 bytes from the read buffer,
172 * starting at byte 0 in the buffer
173 * packet size = 64 bytes
174 *
175 * Packet #3 Device to Host:
176 * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
177 * data index = 60
178 * payload = Next 40 bytes from the read buffer,
179 * starting at byte 60 in the buffer
180 * packet size = 44 bytes
181 *
182 *
183 * Message Packets:
184 *
185 * Command Start Packet (Host to Device):
186 *
187 * Start of the USB SPI command, contains the number of bytes to write
188 * and read on SPI and up to the first 58 bytes of write payload.
189 * Longer writes will use the continue packets with packet id
190 * USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data.
191 *
192 * +----------------+------------------+-----------------+---------------+
193 * | packet id : 2B | write count : 2B | read count : 2B | w.p. : <= 58B |
194 * +----------------+------------------+-----------------+---------------+
195 *
196 * packet id: 2 byte enum defined by packet_id_type
197 * Valid values packet id = USB_SPI_PKT_ID_CMD_TRANSFER_START
198 *
199 * write count: 2 byte, zero based count of bytes to write
200 *
201 * read count: 2 byte, zero based count of bytes to read
202 * UINT16_MAX indicates full duplex mode with a read count
203 * equal to the write count.
204 *
205 * write payload: Up to 58 bytes of data to write to SPI, the total
206 * length of all TX packets must match write count.
207 * Due to data alignment constraints, this must be an
208 * even number of bytes unless this is the final packet.
209 *
210 *
211 * Response Start Packet (Device to Host):
212 *
213 * Start of the USB SPI response, contains the status code and up to
214 * the first 60 bytes of read payload. Longer reads will use the
215 * continue packets with packet id USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
216 * to transmit the remaining data.
217 *
218 * +----------------+------------------+-----------------------+
219 * | packet id : 2B | status code : 2B | read payload : <= 60B |
220 * +----------------+------------------+-----------------------+
221 *
222 * packet id: 2 byte enum defined by packet_id_type
223 * Valid values packet id = USB_SPI_PKT_ID_RSP_TRANSFER_START
224 *
225 * status code: 2 byte status code
226 * 0x0000: Success
227 * 0x0001: SPI timeout
228 * 0x0002: Busy, try again
229 * This can happen if someone else has acquired the shared memory
230 * buffer that the SPI driver uses as /dev/null
231 * 0x0003: Write count invalid. The byte limit is platform specific
232 * and is set during the configure USB SPI response.
233 * 0x0004: Read count invalid. The byte limit is platform specific
234 * and is set during the configure USB SPI response.
235 * 0x0005: The SPI bridge is disabled.
236 * 0x0006: The RX continue packet's data index is invalid. This
237 * can indicate a USB transfer failure to the device.
238 * 0x0007: The RX endpoint has received more data than write count.
239 * This can indicate a USB transfer failure to the device.
240 * 0x0008: An unexpected packet arrived that the device could not
241 * process.
242 * 0x0009: The device does not support full duplex mode.
243 * 0x8000: Unknown error mask
244 * The bottom 15 bits will contain the bottom 15 bits from the EC
245 * error code.
246 *
247 * read payload: Up to 60 bytes of data read from SPI, the total
248 * length of all RX packets must match read count
249 * unless an error status was returned. Due to data
250 * alignment constraints, this must be a even number
251 * of bytes unless this is the final packet.
252 *
253 *
254 * Continue Packet (Bidirectional):
255 *
256 * Continuation packet for the writes and read buffers. Both packets
257 * follow the same format, a data index counts the number of bytes
258 * previously transferred in the USB SPI transfer and a payload of bytes.
259 *
260 * +----------------+-----------------+-------------------------------+
261 * | packet id : 2B | data index : 2B | write / read payload : <= 60B |
262 * +----------------+-----------------+-------------------------------+
263 *
264 * packet id: 2 byte enum defined by packet_id_type
265 * The packet id has 2 values depending on direction:
266 * packet id = USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE
267 * indicates the packet is being transmitted from the host
268 * to the device and contains SPI write payload.
269 * packet id = USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE
270 * indicates the packet is being transmitted from the device
271 * to the host and contains SPI read payload.
272 *
273 * data index: The data index indicates the number of bytes in the
274 * read or write buffers that have already been transmitted.
275 * It is used to validate that no packets have been dropped
276 * and that the prior packets have been correctly decoded.
277 * This value corresponds to the offset bytes in the buffer
278 * to start copying the payload into.
279 *
280 * read and write payload:
281 * Contains up to 60 bytes of payload data to transfer to
282 * the SPI write buffer or from the SPI read buffer.
283 *
284 *
285 * Command Get Configuration Packet (Host to Device):
286 *
287 * Query the device to request its USB SPI configuration indicating
288 * the number of bytes it can write and read.
289 *
290 * +----------------+
291 * | packet id : 2B |
292 * +----------------+
293 *
294 * packet id: 2 byte enum USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG
295 *
296 * Response Configuration Packet (Device to Host):
297 *
298 * Response packet form the device to report the maximum write and
299 * read size supported by the device.
300 *
301 * +----------------+----------------+---------------+----------------+
302 * | packet id : 2B | max write : 2B | max read : 2B | feature bitmap |
303 * +----------------+----------------+---------------+----------------+
304 *
305 * packet id: 2 byte enum USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG
306 *
307 * max write count: 2 byte count of the maximum number of bytes
308 * the device can write to SPI in one transaction.
309 *
310 * max read count: 2 byte count of the maximum number of bytes
311 * the device can read from SPI in one transaction.
312 *
313 * feature bitmap: Bitmap of supported features.
314 * BIT(0): Full duplex SPI mode is supported
315 * BIT(1:15): Reserved for future use
316 *
317 * Command Restart Response Packet (Host to Device):
318 *
319 * Command to restart the response transfer from the device. This enables
320 * the host to recover from a lost packet when reading the response
321 * without restarting the SPI transfer.
322 *
323 * +----------------+
324 * | packet id : 2B |
325 * +----------------+
326 *
327 * packet id: 2 byte enum USB_SPI_PKT_ID_CMD_RESTART_RESPONSE
328 *
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100329 * USB Error Codes:
330 *
331 * send_command return codes have the following format:
332 *
333 * 0x00000: Status code success.
334 * 0x00001-0x0FFFF: Error code returned by the USB SPI device.
Brian J. Nemec7a887802020-07-17 11:20:33 -0700335 * 0x10001-0x1FFFF: Error code returned by the USB SPI host.
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100336 * 0x20001-0x20063 Lower bits store the positive value representation
337 * of the libusb_error enum. See the libusb documentation:
338 * http://libusb.sourceforge.net/api-1.0/group__misc.html
339 */
340
341#include "programmer.h"
342#include "spi.h"
343#include "usb_device.h"
344
345#include <libusb.h>
346#include <stdio.h>
347#include <stdlib.h>
348#include <string.h>
349#include <unistd.h>
350
Angel Pons6c8bd912020-03-25 13:35:45 +0100351/* FIXME: Add some programmer IDs here */
Thomas Heijligen4f5169d2021-05-04 15:32:17 +0200352static const struct dev_entry devs_raiden[] = {
Angel Pons6c8bd912020-03-25 13:35:45 +0100353 {0},
354};
355
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100356#define GOOGLE_VID (0x18D1)
357#define GOOGLE_RAIDEN_SPI_SUBCLASS (0x51)
Brian J. Nemecbd9b4b62020-05-20 16:08:22 -0700358
359enum {
360 GOOGLE_RAIDEN_SPI_PROTOCOL_V1 = 0x01,
361 GOOGLE_RAIDEN_SPI_PROTOCOL_V2 = 0x02,
362};
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100363
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700364enum {
365 /* The host failed to transfer the data with no libusb error. */
366 USB_SPI_HOST_TX_BAD_TRANSFER = 0x10001,
367 /* The number of bytes written did not match expected. */
368 USB_SPI_HOST_TX_WRITE_FAILURE = 0x10002,
369
370 /* We did not receive the expected USB packet. */
371 USB_SPI_HOST_RX_UNEXPECTED_PACKET = 0x11001,
372 /* We received a continue packet with an invalid data index. */
373 USB_SPI_HOST_RX_BAD_DATA_INDEX = 0x11002,
374 /* We received too much data. */
375 USB_SPI_HOST_RX_DATA_OVERFLOW = 0x11003,
376 /* The number of bytes read did not match expected. */
377 USB_SPI_HOST_RX_READ_FAILURE = 0x11004,
378
379 /* We were unable to configure the device. */
380 USB_SPI_HOST_INIT_FAILURE = 0x12001,
381};
382
Edward O'Callaghan8b191f52020-03-05 15:06:57 +1100383enum usb_spi_error {
Brian J. Nemec7a887802020-07-17 11:20:33 -0700384 USB_SPI_SUCCESS = 0x0000,
385 USB_SPI_TIMEOUT = 0x0001,
386 USB_SPI_BUSY = 0x0002,
387 USB_SPI_WRITE_COUNT_INVALID = 0x0003,
388 USB_SPI_READ_COUNT_INVALID = 0x0004,
389 USB_SPI_DISABLED = 0x0005,
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700390 /* The RX continue packet's data index is invalid. */
391 USB_SPI_RX_BAD_DATA_INDEX = 0x0006,
392 /* The RX endpoint has received more data than write count. */
393 USB_SPI_RX_DATA_OVERFLOW = 0x0007,
394 /* An unexpected packet arrived on the device. */
395 USB_SPI_RX_UNEXPECTED_PACKET = 0x0008,
396 /* The device does not support full duplex mode. */
397 USB_SPI_UNSUPPORTED_FULL_DUPLEX = 0x0009,
Brian J. Nemec7a887802020-07-17 11:20:33 -0700398 USB_SPI_UNKNOWN_ERROR = 0x8000,
Edward O'Callaghan8b191f52020-03-05 15:06:57 +1100399};
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100400
401enum raiden_debug_spi_request {
Mary Ruthvenc66d5f82020-07-16 12:03:20 -0700402 RAIDEN_DEBUG_SPI_REQ_ENABLE = 0x0000,
403 RAIDEN_DEBUG_SPI_REQ_DISABLE = 0x0001,
404 RAIDEN_DEBUG_SPI_REQ_ENABLE_AP = 0x0002,
405 RAIDEN_DEBUG_SPI_REQ_ENABLE_EC = 0x0003,
406 RAIDEN_DEBUG_SPI_REQ_ENABLE_H1 = 0x0004,
407 RAIDEN_DEBUG_SPI_REQ_RESET = 0x0005,
408 RAIDEN_DEBUG_SPI_REQ_BOOT_CFG = 0x0006,
409 RAIDEN_DEBUG_SPI_REQ_SOCKET = 0x0007,
410 RAIDEN_DEBUG_SPI_REQ_SIGNING_START = 0x0008,
411 RAIDEN_DEBUG_SPI_REQ_SIGNING_SIGN = 0x0009,
412 RAIDEN_DEBUG_SPI_REQ_ENABLE_AP_CUSTOM = 0x000a,
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100413};
414
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100415/*
Edward O'Callaghan21412502020-03-05 14:56:47 +1100416 * Servo Micro has an error where it is capable of acknowledging USB packets
417 * without loading it into the USB endpoint buffers or triggering interrupts.
418 * See crbug.com/952494. Retry mechanisms have been implemented to recover
419 * from these rare failures allowing the process to continue.
420 */
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700421#define WRITE_RETRY_ATTEMPTS (3)
422#define READ_RETRY_ATTEMPTS (3)
423#define GET_CONFIG_RETRY_ATTEMPTS (3)
424#define RETRY_INTERVAL_US (100 * 1000)
Edward O'Callaghan21412502020-03-05 14:56:47 +1100425
426/*
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100427 * This timeout is so large because the Raiden SPI timeout is 800ms.
428 */
429#define TRANSFER_TIMEOUT_MS (200 + 800)
430
Edward O'Callaghan757e8922020-04-03 12:52:32 +1100431struct raiden_debug_spi_data {
432 struct usb_device *dev;
433 uint8_t in_ep;
434 uint8_t out_ep;
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700435 uint8_t protocol_version;
436 /*
437 * Note: Due to bugs, flashrom does not always treat the max_data_write
438 * and max_data_read counts as the maximum packet size. As a result, we
439 * have to store a local copy of the actual max packet sizes and validate
440 * against it when performing transfers.
441 */
442 uint16_t max_spi_write_count;
443 uint16_t max_spi_read_count;
Edward O'Callaghan757e8922020-04-03 12:52:32 +1100444};
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700445/*
446 * USB permits a maximum bulk transfer of 64B.
447 */
448#define USB_MAX_PACKET_SIZE (64)
449#define PACKET_HEADER_SIZE (2)
450
451/*
452 * All of the USB SPI packets have size equal to the max USB packet size of 64B
453 */
454#define PAYLOAD_SIZE_V1 (62)
455
456#define SPI_TRANSFER_V1_MAX (PAYLOAD_SIZE_V1)
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100457
Brian J. Nemec7a887802020-07-17 11:20:33 -0700458/*
459 * Version 1 protocol specific attributes
460 */
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100461
Brian J. Nemec7a887802020-07-17 11:20:33 -0700462struct usb_spi_command_v1 {
463 uint8_t write_count;
464 /* UINT8_MAX indicates full duplex mode on compliant devices. */
465 uint8_t read_count;
466 uint8_t data[PAYLOAD_SIZE_V1];
467} __attribute__((packed));
468
469struct usb_spi_response_v1 {
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100470 uint16_t status_code;
Brian J. Nemecbd9b4b62020-05-20 16:08:22 -0700471 uint8_t data[PAYLOAD_SIZE_V1];
Brian J. Nemec7a887802020-07-17 11:20:33 -0700472} __attribute__((packed));
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100473
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700474union usb_spi_packet_v1 {
475 struct usb_spi_command_v1 command;
476 struct usb_spi_response_v1 response;
477} __attribute__((packed));
478
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700479/*
480 * Version 2 protocol specific attributes
481 */
482
483#define USB_SPI_FULL_DUPLEX_ENABLED_V2 (UINT16_MAX)
484
485#define USB_SPI_PAYLOAD_SIZE_V2_START (58)
486
487#define USB_SPI_PAYLOAD_SIZE_V2_RESPONSE (60)
488
489#define USB_SPI_PAYLOAD_SIZE_V2_CONTINUE (60)
490
491enum packet_id_type {
492 /* Request USB SPI configuration data from device. */
493 USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG = 0,
494 /* USB SPI configuration data from device. */
495 USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG = 1,
496 /*
497 * Start a USB SPI transfer specifying number of bytes to write,
498 * read and deliver first packet of data to write.
499 */
500 USB_SPI_PKT_ID_CMD_TRANSFER_START = 2,
501 /* Additional packets containing write payload. */
502 USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE = 3,
503 /*
504 * Request the device restart the response enabling us to recover
505 * from packet loss without another SPI transfer.
506 */
507 USB_SPI_PKT_ID_CMD_RESTART_RESPONSE = 4,
508 /*
509 * First packet of USB SPI response with the status code
510 * and read payload if it was successful.
511 */
512 USB_SPI_PKT_ID_RSP_TRANSFER_START = 5,
513 /* Additional packets containing read payload. */
514 USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE = 6,
515};
516
517enum feature_bitmap {
518 /* Indicates the platform supports full duplex mode. */
519 USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = 0x01
520};
521
522struct usb_spi_response_configuration_v2 {
523 uint16_t packet_id;
524 uint16_t max_write_count;
525 uint16_t max_read_count;
526 uint16_t feature_bitmap;
527} __attribute__((packed));
528
529struct usb_spi_command_v2 {
530 uint16_t packet_id;
531 uint16_t write_count;
532 /* UINT16_MAX Indicates readback all on halfduplex compliant devices. */
533 uint16_t read_count;
534 uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_START];
535} __attribute__((packed));
536
537struct usb_spi_response_v2 {
538 uint16_t packet_id;
539 uint16_t status_code;
540 uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_RESPONSE];
541} __attribute__((packed));
542
543struct usb_spi_continue_v2 {
544 uint16_t packet_id;
545 uint16_t data_index;
546 uint8_t data[USB_SPI_PAYLOAD_SIZE_V2_CONTINUE];
547} __attribute__((packed));
548
549union usb_spi_packet_v2 {
550 uint16_t packet_id;
551 struct usb_spi_command_v2 cmd_start;
552 struct usb_spi_continue_v2 cmd_continue;
553 struct usb_spi_response_configuration_v2 rsp_config;
554 struct usb_spi_response_v2 rsp_start;
555 struct usb_spi_continue_v2 rsp_continue;
556} __attribute__((packed));
557
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700558struct usb_spi_packet_ctx {
559 union {
560 uint8_t bytes[USB_MAX_PACKET_SIZE];
561 union usb_spi_packet_v1 packet_v1;
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700562 union usb_spi_packet_v2 packet_v2;
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700563 };
564 /*
565 * By storing the number of bytes in the header and knowing that the
566 * USB data packets are all 64B long, we are able to use the header
567 * size to store the offset of the buffer and it's size without
568 * duplicating variables that can go out of sync.
569 */
570 size_t header_size;
571 /* Number of bytes in the packet */
572 size_t packet_size;
573};
574
Brian J. Nemecce80d182020-07-17 02:00:15 -0700575struct usb_spi_transmit_ctx {
576 /* Buffer we are reading data from. */
577 const uint8_t *buffer;
578 /* Number of bytes in the transfer. */
579 size_t transmit_size;
580 /* Number of bytes transferred. */
581 size_t transmit_index;
582};
583
584struct usb_spi_receive_ctx {
585 /* Buffer we are writing data into. */
586 uint8_t *buffer;
587 /* Number of bytes in the transfer. */
588 size_t receive_size;
589 /* Number of bytes transferred. */
590 size_t receive_index;
591};
592
Edward O'Callaghan8b191f52020-03-05 15:06:57 +1100593/*
594 * This function will return true when an error code can potentially recover
595 * if we attempt to write SPI data to the device or read from it. We know
596 * that some conditions are not recoverable in the current state so allows us
597 * to bypass the retry logic and terminate early.
598 */
599static bool retry_recovery(int error_code)
600{
601 if (error_code < 0x10000) {
Brian J. Nemec93bfafc2020-05-06 15:25:58 -0700602 /*
603 * Handle error codes returned from the device. USB_SPI_TIMEOUT,
604 * USB_SPI_BUSY, and USB_SPI_WRITE_COUNT_INVALID have been observed
605 * during transfer errors to the device and can be recovered.
606 */
607 if (USB_SPI_READ_COUNT_INVALID <= error_code &&
608 error_code <= USB_SPI_DISABLED) {
Edward O'Callaghan8b191f52020-03-05 15:06:57 +1100609 return false;
610 }
611 } else if (usb_device_is_libusb_error(error_code)) {
612 /* Handle error codes returned from libusb. */
613 if (error_code == LIBUSB_ERROR(LIBUSB_ERROR_NO_DEVICE)) {
614 return false;
615 }
616 }
617 return true;
618}
619
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700620static struct raiden_debug_spi_data *
Edward O'Callaghan757e8922020-04-03 12:52:32 +1100621 get_raiden_data_from_context(const struct flashctx *flash)
622{
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700623 return (struct raiden_debug_spi_data *)flash->mst->spi.data;
Edward O'Callaghan757e8922020-04-03 12:52:32 +1100624}
625
Brian J. Nemec7a887802020-07-17 11:20:33 -0700626/*
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700627 * Read data into the receive buffer.
Brian J. Nemec7a887802020-07-17 11:20:33 -0700628 *
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700629 * @param dst Destination receive context we are writing data to.
630 * @param src Source packet context we are reading data from.
631 *
632 * @returns status code 0 on success.
633 * USB_SPI_HOST_RX_DATA_OVERFLOW if the source packet is too
634 * large to fit in read buffer.
635 */
636static int read_usb_packet(struct usb_spi_receive_ctx *dst,
637 const struct usb_spi_packet_ctx *src)
638{
639 size_t max_read_length = dst->receive_size - dst->receive_index;
640 size_t bytes_in_buffer = src->packet_size - src->header_size;
641 const uint8_t *packet_buffer = src->bytes + src->header_size;
642
643 if (bytes_in_buffer > max_read_length) {
644 /*
645 * An error occurred, we should not receive more data than
646 * the buffer can support.
647 */
648 msg_perr("Raiden: Receive packet overflowed\n"
649 " bytes_in_buffer = %zu\n"
650 " max_read_length = %zu\n"
651 " receive_index = %zu\n"
652 " receive_size = %zu\n",
653 bytes_in_buffer, max_read_length,
654 dst->receive_size, dst->receive_index);
655 return USB_SPI_HOST_RX_DATA_OVERFLOW;
656 }
657 memcpy(dst->buffer + dst->receive_index, packet_buffer,
658 bytes_in_buffer);
659
660 dst->receive_index += bytes_in_buffer;
661 return 0;
662}
663
664/*
665 * Fill the USB packet with data from the transmit buffer.
666 *
667 * @param dst Destination packet context we are writing data to.
668 * @param src Source transmit context we are reading data from.
669 */
670static void fill_usb_packet(struct usb_spi_packet_ctx *dst,
671 struct usb_spi_transmit_ctx *src)
672{
673 size_t transmit_size = src->transmit_size - src->transmit_index;
674 size_t max_buffer_size = USB_MAX_PACKET_SIZE - dst->header_size;
675 uint8_t *packet_buffer = dst->bytes + dst->header_size;
676
677 if (transmit_size > max_buffer_size)
678 transmit_size = max_buffer_size;
679
680 memcpy(packet_buffer, src->buffer + src->transmit_index, transmit_size);
681
682 dst->packet_size = dst->header_size + transmit_size;
683 src->transmit_index += transmit_size;
684}
685
686/*
687 * Receive the data from the device USB endpoint and store in the packet.
688 *
689 * @param ctx_data Raiden SPI config.
690 * @param packet Destination packet used to store the endpoint data.
691 *
692 * @returns Returns status code with 0 on success.
693 */
694static int receive_packet(const struct raiden_debug_spi_data *ctx_data,
695 struct usb_spi_packet_ctx *packet)
696{
697 int received;
698 int status = LIBUSB(libusb_bulk_transfer(ctx_data->dev->handle,
699 ctx_data->in_ep,
700 packet->bytes,
701 USB_MAX_PACKET_SIZE,
702 &received,
703 TRANSFER_TIMEOUT_MS));
704 packet->packet_size = received;
705 if (status) {
706 msg_perr("Raiden: IN transfer failed\n"
707 " received = %d\n"
708 " status = 0x%05x\n",
709 received, status);
710 }
711 return status;
712}
713
714/*
715 * Transmit data from the packet to the device's USB endpoint.
716 *
717 * @param ctx_data Raiden SPI config.
718 * @param packet Source packet we will write to the endpoint data.
719 *
720 * @returns Returns status code with 0 on success.
721 */
722static int transmit_packet(const struct raiden_debug_spi_data *ctx_data,
723 struct usb_spi_packet_ctx *packet)
724{
725 int transferred;
726 int status = LIBUSB(libusb_bulk_transfer(ctx_data->dev->handle,
727 ctx_data->out_ep,
728 packet->bytes,
729 packet->packet_size,
730 &transferred,
731 TRANSFER_TIMEOUT_MS));
732 if (status || (size_t)transferred != packet->packet_size) {
733 if (!status) {
734 /* No error was reported, but we didn't transmit the data expected. */
735 status = USB_SPI_HOST_TX_BAD_TRANSFER;
736 }
737 msg_perr("Raiden: OUT transfer failed\n"
738 " transferred = %d\n"
739 " packet_size = %zu\n"
740 " status = 0x%05x\n",
741 transferred, packet->packet_size, status);
742
743 }
744 return status;
745}
746
747/*
748 * Version 1 protocol command to start a USB SPI transfer and write the payload.
749 *
750 * @param ctx_data Raiden SPI config.
Brian J. Nemecce80d182020-07-17 02:00:15 -0700751 * @param write Write context of data to transmit and write payload.
752 * @param read Read context of data to receive and read buffer.
753 *
Brian J. Nemec7a887802020-07-17 11:20:33 -0700754 * @returns Returns status code with 0 on success.
755 */
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700756static int write_command_v1(const struct raiden_debug_spi_data *ctx_data,
Brian J. Nemecce80d182020-07-17 02:00:15 -0700757 struct usb_spi_transmit_ctx *write,
758 struct usb_spi_receive_ctx *read)
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100759{
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700760 struct usb_spi_packet_ctx command = {
761 .header_size = offsetof(struct usb_spi_command_v1, data),
762 .packet_v1.command.write_count = write->transmit_size,
763 .packet_v1.command.read_count = read->receive_size
764 };
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100765
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700766 /* Reset the write context to the start. */
767 write->transmit_index = 0;
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100768
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700769 fill_usb_packet(&command, write);
770 return transmit_packet(ctx_data, &command);
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100771}
772
Brian J. Nemec7a887802020-07-17 11:20:33 -0700773/*
774 * Version 1 Protocol: Responsible for reading the response of the USB SPI
775 * transfer. Status codes from the transfer and any read payload are copied
776 * to the read_buffer.
777 *
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700778 * @param ctx_data Raiden SPI config.
Brian J. Nemecce80d182020-07-17 02:00:15 -0700779 * @param write Write context of data to transmit and write payload.
780 * @param read Read context of data to receive and read buffer.
781 *
Brian J. Nemec7a887802020-07-17 11:20:33 -0700782 * @returns Returns status code with 0 on success.
783 */
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700784static int read_response_v1(const struct raiden_debug_spi_data *ctx_data,
Brian J. Nemecce80d182020-07-17 02:00:15 -0700785 struct usb_spi_transmit_ctx *write,
786 struct usb_spi_receive_ctx *read)
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100787{
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700788 int status;
789 struct usb_spi_packet_ctx response;
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100790
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700791 /* Reset the read context to the start. */
792 read->receive_index = 0;
793
794 status = receive_packet(ctx_data, &response);
795 if (status) {
796 /* Return the transfer error since the status_code is unreliable */
797 return status;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100798 }
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700799 if (response.packet_v1.response.status_code) {
800 return response.packet_v1.response.status_code;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100801 }
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700802 response.header_size = offsetof(struct usb_spi_response_v1, data);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +1100803
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700804 status = read_usb_packet(read, &response);
805 return status;
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100806}
807
Brian J. Nemec7a887802020-07-17 11:20:33 -0700808/*
809 * Version 1 Protocol: Sets up a USB SPI transfer, transmits data to the device,
810 * reads the status code and any payload from the device. This will also handle
811 * recovery if an error has occurred.
812 *
813 * @param flash Flash context storing SPI capabilities and USB device
814 * information.
815 * @param write_count Number of bytes to write
816 * @param read_count Number of bytes to read
817 * @param write_buffer Address of write buffer
818 * @param read_buffer Address of buffer to store read data
819 *
820 * @returns Returns status code with 0 on success.
821 */
822static int send_command_v1(const struct flashctx *flash,
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100823 unsigned int write_count,
824 unsigned int read_count,
825 const unsigned char *write_buffer,
826 unsigned char *read_buffer)
827{
828 int status = -1;
829
Brian J. Nemecce80d182020-07-17 02:00:15 -0700830 struct usb_spi_transmit_ctx write_ctx = {
831 .buffer = write_buffer,
832 .transmit_size = write_count
833 };
834 struct usb_spi_receive_ctx read_ctx = {
835 .buffer = read_buffer,
836 .receive_size = read_count
837 };
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700838 const struct raiden_debug_spi_data *ctx_data = get_raiden_data_from_context(flash);
Brian J. Nemecce80d182020-07-17 02:00:15 -0700839
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700840 if (write_count > ctx_data->max_spi_write_count) {
Brian J. Nemec7a887802020-07-17 11:20:33 -0700841 msg_perr("Raiden: Invalid write count\n"
842 " write count = %u\n"
843 " max write = %d\n",
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700844 write_count, ctx_data->max_spi_write_count);
Brian J. Nemec7a887802020-07-17 11:20:33 -0700845 return SPI_INVALID_LENGTH;
846 }
847
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700848 if (read_count > ctx_data->max_spi_read_count) {
Brian J. Nemec7a887802020-07-17 11:20:33 -0700849 msg_perr("Raiden: Invalid read count\n"
850 " read count = %d\n"
851 " max read = %d\n",
Brian J. Nemeca7b526d2020-07-19 13:37:42 -0700852 read_count, ctx_data->max_spi_read_count);
Brian J. Nemec7a887802020-07-17 11:20:33 -0700853 return SPI_INVALID_LENGTH;
854 }
855
856 for (unsigned int write_attempt = 0; write_attempt < WRITE_RETRY_ATTEMPTS;
Edward O'Callaghan21412502020-03-05 14:56:47 +1100857 write_attempt++) {
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +1100858
Brian J. Nemecce80d182020-07-17 02:00:15 -0700859
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700860 status = write_command_v1(ctx_data, &write_ctx, &read_ctx);
861
862 if (!status &&
863 (write_ctx.transmit_index != write_ctx.transmit_size)) {
864 /* No errors were reported, but write is incomplete. */
865 status = USB_SPI_HOST_TX_WRITE_FAILURE;
866 }
Edward O'Callaghan21412502020-03-05 14:56:47 +1100867
868 if (status) {
869 /* Write operation failed. */
870 msg_perr("Raiden: Write command failed\n"
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700871 " protocol = %u\n"
Brian J. Nemec7a887802020-07-17 11:20:33 -0700872 " write count = %u\n"
873 " read count = %u\n"
Brian J. Nemecce80d182020-07-17 02:00:15 -0700874 " transmitted bytes = %zu\n"
Brian J. Nemec7a887802020-07-17 11:20:33 -0700875 " write attempt = %u\n"
876 " status = 0x%05x\n",
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700877 ctx_data->protocol_version,
Brian J. Nemecce80d182020-07-17 02:00:15 -0700878 write_count, read_count, write_ctx.transmit_index,
Brian J. Nemec7a887802020-07-17 11:20:33 -0700879 write_attempt + 1, status);
Edward O'Callaghan8b191f52020-03-05 15:06:57 +1100880 if (!retry_recovery(status)) {
881 /* Reattempting will not result in a recovery. */
882 return status;
883 }
Brian J. Nemec7a887802020-07-17 11:20:33 -0700884 programmer_delay(RETRY_INTERVAL_US);
Edward O'Callaghan21412502020-03-05 14:56:47 +1100885 continue;
886 }
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700887
Brian J. Nemec7a887802020-07-17 11:20:33 -0700888 for (unsigned int read_attempt = 0; read_attempt < READ_RETRY_ATTEMPTS;
889 read_attempt++) {
Edward O'Callaghan21412502020-03-05 14:56:47 +1100890
Brian J. Nemec7ac57c72020-07-17 11:46:33 -0700891 status = read_response_v1(ctx_data, &write_ctx, &read_ctx);
892
893 if (!status) {
894 if (read_ctx.receive_size == read_ctx.receive_index) {
895 /* Successful transfer. */
896 return status;
897 } else {
898 /* Report the error from the failed read. */
899 status = USB_SPI_HOST_RX_READ_FAILURE;
900 }
901 }
Edward O'Callaghan21412502020-03-05 14:56:47 +1100902
Brian J. Nemec2cb1f332020-07-20 10:32:21 -0700903 /* Read operation failed. */
904 msg_perr("Raiden: Read response failed\n"
905 " protocol = %u\n"
906 " write count = %u\n"
907 " read count = %u\n"
908 " received bytes = %zu\n"
909 " write attempt = %u\n"
910 " read attempt = %u\n"
911 " status = 0x%05x\n",
912 ctx_data->protocol_version,
913 write_count, read_count, read_ctx.receive_index,
914 write_attempt + 1, read_attempt + 1, status);
915 if (!retry_recovery(status)) {
916 /* Reattempting will not result in a recovery. */
917 return status;
918 }
919 programmer_delay(RETRY_INTERVAL_US);
920 }
921 }
922
923 return status;
924}
925
926/*
927 * Get the USB SPI configuration with the maximum write and read counts, and
928 * any enabled features.
929 *
930 * @param ctx_data Raiden SPI config.
931 *
932 * @returns Returns status code with 0 on success.
933 */
934static int get_spi_config_v2(struct raiden_debug_spi_data *ctx_data)
935{
936 int status;
937 unsigned int config_attempt;
938 struct usb_spi_packet_ctx rsp_config;
939
940 struct usb_spi_packet_ctx cmd_get_config = {
941 .header_size = PACKET_HEADER_SIZE,
942 .packet_size = PACKET_HEADER_SIZE,
943 .packet_v2.packet_id = USB_SPI_PKT_ID_CMD_GET_USB_SPI_CONFIG
944 };
945
946 for (config_attempt = 0; config_attempt < GET_CONFIG_RETRY_ATTEMPTS; config_attempt++) {
947
948 status = transmit_packet(ctx_data, &cmd_get_config);
949 if (status) {
950 msg_perr("Raiden: Failed to transmit get config\n"
951 " config attempt = %d\n"
952 " status = 0x%05x\n",
953 config_attempt + 1, status);
954 programmer_delay(RETRY_INTERVAL_US);
955 continue;
956 }
957
958 status = receive_packet(ctx_data, &rsp_config);
959 if (status) {
960 msg_perr("Raiden: Failed to receive packet\n"
961 " config attempt = %d\n"
962 " status = 0x%05x\n",
963 config_attempt + 1, status);
964 programmer_delay(RETRY_INTERVAL_US);
965 continue;
966 }
967
968 /*
969 * Perform validation on the packet received to verify it is a valid
970 * configuration. If it is, we are ready to perform transfers.
971 */
972 if ((rsp_config.packet_v2.packet_id ==
973 USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG) ||
974 (rsp_config.packet_size ==
975 sizeof(struct usb_spi_response_configuration_v2))) {
976
977 /* Set the parameters from the configuration. */
978 ctx_data->max_spi_write_count =
979 rsp_config.packet_v2.rsp_config.max_write_count;
980 ctx_data->max_spi_read_count =
981 rsp_config.packet_v2.rsp_config.max_read_count;
982 return status;
983 }
984
985 msg_perr("Raiden: Packet is not a valid config\n"
986 " config attempt = %d\n"
987 " packet id = %u\n"
988 " packet size = %zu\n",
989 config_attempt + 1,
990 rsp_config.packet_v2.packet_id,
991 rsp_config.packet_size);
992 programmer_delay(RETRY_INTERVAL_US);
993 }
994 return USB_SPI_HOST_INIT_FAILURE;
995}
996
997/*
998 * Version 2 protocol restart the SPI response. This allows us to recover from
999 * USB packet errors without restarting the SPI transfer.
1000 *
1001 * @param ctx_data Raiden SPI config.
1002 *
1003 * @returns Returns status code with 0 on success.
1004 */
1005static int restart_response_v2(const struct raiden_debug_spi_data *ctx_data)
1006{
1007 struct usb_spi_packet_ctx restart_response = {
1008 .header_size = PACKET_HEADER_SIZE,
1009 .packet_size = PACKET_HEADER_SIZE,
1010 .packet_v2.packet_id = USB_SPI_PKT_ID_CMD_RESTART_RESPONSE
1011 };
1012
1013 return transmit_packet(ctx_data, &restart_response);
1014}
1015
1016/*
1017 * Version 2 Protocol: command to start a USB SPI transfer and write the payload.
1018 *
1019 * @param ctx_data Raiden SPI config.
1020 * @param write Write context of data to transmit and write payload.
1021 * @param read Read context of data to receive and read buffer.
1022 *
1023 * @returns Returns status code with 0 on success.
1024 */
1025static int write_command_v2(const struct raiden_debug_spi_data *ctx_data,
1026 struct usb_spi_transmit_ctx *write,
1027 struct usb_spi_receive_ctx *read)
1028{
1029 int status;
1030 struct usb_spi_packet_ctx continue_packet;
1031
1032 struct usb_spi_packet_ctx start_usb_spi_packet = {
1033 .header_size = offsetof(struct usb_spi_command_v2, data),
1034 .packet_v2.cmd_start.packet_id = USB_SPI_PKT_ID_CMD_TRANSFER_START,
1035 .packet_v2.cmd_start.write_count = write->transmit_size,
1036 .packet_v2.cmd_start.read_count = read->receive_size
1037 };
1038
1039 /* Reset the write context to the start. */
1040 write->transmit_index = 0;
1041
1042 fill_usb_packet(&start_usb_spi_packet, write);
1043 status = transmit_packet(ctx_data, &start_usb_spi_packet);
1044 if (status) {
1045 return status;
1046 }
1047
1048 while (write->transmit_index < write->transmit_size) {
1049 /* Transmit any continue packets. */
1050 continue_packet.header_size = offsetof(struct usb_spi_continue_v2, data);
1051 continue_packet.packet_v2.cmd_continue.packet_id =
1052 USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE;
1053 continue_packet.packet_v2.cmd_continue.data_index =
1054 write->transmit_index;
1055
1056 fill_usb_packet(&continue_packet, write);
1057
1058 status = transmit_packet(ctx_data, &continue_packet);
1059 if (status) {
1060 return status;
1061 }
1062 }
1063
1064 return status;
1065}
1066
1067/*
1068 * Version 2 Protocol: Command to read a USB SPI transfer response and read the payload.
1069 *
1070 * @param ctx_data Raiden SPI config.
1071 * @param write Write context of data to transmit and write payload.
1072 * @param read Read context of data to receive and read buffer.
1073 *
1074 * @returns Returns status code with 0 on success.
1075 */
1076static int read_response_v2(const struct raiden_debug_spi_data *ctx_data,
1077 struct usb_spi_transmit_ctx *write,
1078 struct usb_spi_receive_ctx *read)
1079{
1080 int status = -1;
1081 struct usb_spi_packet_ctx response;
1082
1083 /* Reset the read context to the start. */
1084 read->receive_index = 0;
1085
1086 /* Receive the payload to the servo micro. */
1087 do {
1088 status = receive_packet(ctx_data, &response);
1089 if (status) {
1090 /* Return the transfer error. */
1091 return status;
1092 }
1093 if (response.packet_v2.packet_id == USB_SPI_PKT_ID_RSP_TRANSFER_START) {
1094 /*
1095 * The host should only see this packet if an error occurs
1096 * on the device or if it's the first response packet.
1097 */
1098 if (response.packet_v2.rsp_start.status_code) {
1099 return response.packet_v2.rsp_start.status_code;
1100 }
1101 if (read->receive_index) {
1102 msg_perr("Raiden: Unexpected start packet id = %u\n",
1103 response.packet_v2.rsp_start.packet_id);
1104 return USB_SPI_HOST_RX_UNEXPECTED_PACKET;
1105 }
1106 response.header_size = offsetof(struct usb_spi_response_v2, data);
1107 } else if (response.packet_v2.packet_id ==
1108 USB_SPI_PKT_ID_RSP_TRANSFER_CONTINUE) {
1109
1110 /* We validate that no packets were missed. */
1111 if (read->receive_index !=
1112 response.packet_v2.rsp_continue.data_index) {
1113 msg_perr("Raiden: Bad Index = %u Expected = %zu\n",
1114 response.packet_v2.rsp_continue.data_index,
1115 read->receive_index);
1116 return USB_SPI_HOST_RX_BAD_DATA_INDEX;
1117 }
1118 response.header_size = offsetof(struct usb_spi_continue_v2, data);
1119 } else {
1120 msg_perr("Raiden: Unexpected packet id = %u\n",
1121 response.packet_v2.packet_id);
1122 return USB_SPI_HOST_RX_UNEXPECTED_PACKET;
1123 }
1124 status = read_usb_packet(read, &response);
1125 if (status) {
1126 return status;
1127 }
1128 } while (read->receive_index < read->receive_size);
1129
1130 return status;
1131}
1132
1133/*
1134 * Version 2 Protocol: Sets up a USB SPI transfer, transmits data to the device,
1135 * reads the status code and any payload from the device. This will also handle
1136 * recovery if an error has occurred.
1137 *
1138 * In order to avoid having the v2 protocol held back by requiring
1139 * backwards compatibility with v1 we are duplicating the send_command
1140 * function. This will allow the 2 versions to diverge in the future
1141 * so fixes in one do not need to be compatible with the legacy.
1142 *
1143 * @param flash Flash context storing SPI capabilities and USB device
1144 * information.
1145 * @param write_count Number of bytes to write
1146 * @param read_count Number of bytes to read
1147 * @param write_buffer Address of write buffer
1148 * @param read_buffer Address of buffer to store read data
1149 *
1150 * @returns Returns status code with 0 on success.
1151 */
1152static int send_command_v2(const struct flashctx *flash,
1153 unsigned int write_count,
1154 unsigned int read_count,
1155 const unsigned char *write_buffer,
1156 unsigned char *read_buffer)
1157{
1158 const struct raiden_debug_spi_data *ctx_data =
1159 get_raiden_data_from_context(flash);
1160 int status = -1;
1161 unsigned int write_attempt;
1162 unsigned int read_attempt;
1163
1164 struct usb_spi_transmit_ctx write_ctx = {
1165 .buffer = write_buffer,
1166 .transmit_size = write_count
1167 };
1168 struct usb_spi_receive_ctx read_ctx = {
1169 .buffer = read_buffer,
1170 .receive_size = read_count
1171 };
1172
1173 if (write_count > ctx_data->max_spi_write_count) {
1174 msg_perr("Raiden: Invalid write count\n"
1175 " write count = %u\n"
1176 " max write = %u\n",
1177 write_count, ctx_data->max_spi_write_count);
1178 return SPI_INVALID_LENGTH;
1179 }
1180
1181 if (read_count > ctx_data->max_spi_read_count) {
1182 msg_perr("Raiden: Invalid read count\n"
1183 " read count = %u\n"
1184 " max read = %u\n",
1185 read_count, ctx_data->max_spi_read_count);
1186 return SPI_INVALID_LENGTH;
1187 }
1188
1189 for (write_attempt = 0; write_attempt < WRITE_RETRY_ATTEMPTS;
1190 write_attempt++) {
1191
1192 status = write_command_v2(ctx_data, &write_ctx, &read_ctx);
1193
1194 if (!status &&
1195 (write_ctx.transmit_index != write_ctx.transmit_size)) {
1196 /* No errors were reported, but write is incomplete. */
1197 status = USB_SPI_HOST_TX_WRITE_FAILURE;
1198 }
1199
1200 if (status) {
1201 /* Write operation failed. */
1202 msg_perr("Raiden: Write command failed\n"
1203 " protocol = %u\n"
1204 " write count = %u\n"
1205 " read count = %u\n"
1206 " transmitted bytes = %zu\n"
1207 " write attempt = %u\n"
1208 " status = 0x%05x\n",
1209 ctx_data->protocol_version,
1210 write_count, read_count, write_ctx.transmit_index,
1211 write_attempt + 1, status);
1212 if (!retry_recovery(status)) {
1213 /* Reattempting will not result in a recovery. */
1214 return status;
1215 }
1216 programmer_delay(RETRY_INTERVAL_US);
1217 continue;
1218 }
1219 for (read_attempt = 0; read_attempt < READ_RETRY_ATTEMPTS;
1220 read_attempt++) {
1221
1222 status = read_response_v2(ctx_data, &write_ctx, &read_ctx);
1223
1224 if (!status) {
1225 if (read_ctx.receive_size == read_ctx.receive_index) {
1226 /* Successful transfer. */
1227 return status;
1228 } else {
1229 /* Report the error from the failed read. */
1230 status = USB_SPI_HOST_RX_READ_FAILURE;
1231 }
1232 }
1233
Brian J. Nemec7a887802020-07-17 11:20:33 -07001234 if (status) {
Edward O'Callaghan21412502020-03-05 14:56:47 +11001235 /* Read operation failed. */
1236 msg_perr("Raiden: Read response failed\n"
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001237 " protocol = %u\n"
Brian J. Nemec7a887802020-07-17 11:20:33 -07001238 " write count = %u\n"
1239 " read count = %u\n"
Brian J. Nemecce80d182020-07-17 02:00:15 -07001240 " received bytes = %zu\n"
Brian J. Nemec7a887802020-07-17 11:20:33 -07001241 " write attempt = %u\n"
1242 " read attempt = %u\n"
1243 " status = 0x%05x\n",
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001244 ctx_data->protocol_version,
Brian J. Nemecce80d182020-07-17 02:00:15 -07001245 write_count, read_count, read_ctx.receive_index,
Brian J. Nemec7a887802020-07-17 11:20:33 -07001246 write_attempt + 1, read_attempt + 1, status);
Edward O'Callaghan8b191f52020-03-05 15:06:57 +11001247 if (!retry_recovery(status)) {
1248 /* Reattempting will not result in a recovery. */
1249 return status;
1250 }
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001251 /* Device needs to reset its transmit index. */
1252 restart_response_v2(ctx_data);
Brian J. Nemec7a887802020-07-17 11:20:33 -07001253 programmer_delay(RETRY_INTERVAL_US);
Edward O'Callaghan21412502020-03-05 14:56:47 +11001254 }
1255 }
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +11001256 }
Edward O'Callaghane8c0ee72020-03-05 14:51:36 +11001257 return status;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001258}
1259
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001260static const struct spi_master spi_master_raiden_debug = {
Brian J. Nemecbd9b4b62020-05-20 16:08:22 -07001261 .features = SPI_MASTER_4BA,
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001262 .max_data_read = 0,
1263 .max_data_write = 0,
1264 .command = NULL,
Brian J. Nemecbd9b4b62020-05-20 16:08:22 -07001265 .multicommand = default_spi_send_multicommand,
1266 .read = default_spi_read,
1267 .write_256 = default_spi_write_256,
1268 .write_aai = default_spi_write_aai,
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001269};
1270
1271static int match_endpoint(struct libusb_endpoint_descriptor const *descriptor,
1272 enum libusb_endpoint_direction direction)
1273{
1274 return (((descriptor->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
1275 direction) &&
1276 ((descriptor->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
1277 LIBUSB_TRANSFER_TYPE_BULK));
1278}
1279
1280static int find_endpoints(struct usb_device *dev, uint8_t *in_ep, uint8_t *out_ep)
1281{
1282 int i;
1283 int in_count = 0;
1284 int out_count = 0;
1285
1286 for (i = 0; i < dev->interface_descriptor->bNumEndpoints; i++) {
1287 struct libusb_endpoint_descriptor const *endpoint =
1288 &dev->interface_descriptor->endpoint[i];
1289
1290 if (match_endpoint(endpoint, LIBUSB_ENDPOINT_IN)) {
1291 in_count++;
1292 *in_ep = endpoint->bEndpointAddress;
1293 } else if (match_endpoint(endpoint, LIBUSB_ENDPOINT_OUT)) {
1294 out_count++;
1295 *out_ep = endpoint->bEndpointAddress;
1296 }
1297 }
1298
1299 if (in_count != 1 || out_count != 1) {
1300 msg_perr("Raiden: Failed to find one IN and one OUT endpoint\n"
1301 " found %d IN and %d OUT endpoints\n",
1302 in_count,
1303 out_count);
1304 return 1;
1305 }
1306
1307 msg_pdbg("Raiden: Found IN endpoint = 0x%02x\n", *in_ep);
1308 msg_pdbg("Raiden: Found OUT endpoint = 0x%02x\n", *out_ep);
1309
1310 return 0;
1311}
1312
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001313/*
1314 * Configure the USB SPI master based on the device we are connected to.
1315 * It will use the device's bInterfaceProtocol to identify which protocol
1316 * is being used by the device USB SPI interface and if needed query the
1317 * device for its capabilities.
1318 *
1319 * @param spi_config Raiden SPI config which will be modified.
1320 *
1321 * @returns Returns status code with 0 on success.
1322 */
1323static int configure_protocol(struct spi_master *spi_config)
1324{
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001325 int status = 0;
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001326 struct raiden_debug_spi_data *ctx_data =
1327 (struct raiden_debug_spi_data *)spi_config->data;
1328
1329 ctx_data->protocol_version =
1330 ctx_data->dev->interface_descriptor->bInterfaceProtocol;
1331
1332 switch (ctx_data->protocol_version) {
1333 case GOOGLE_RAIDEN_SPI_PROTOCOL_V1:
1334 /*
1335 * Protocol V1 is supported by adjusting the max data
1336 * read and write sizes which results in no continue packets.
1337 */
1338 spi_config->command = send_command_v1;
1339 ctx_data->max_spi_write_count = SPI_TRANSFER_V1_MAX;
1340 ctx_data->max_spi_read_count = SPI_TRANSFER_V1_MAX;
1341 break;
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001342 case GOOGLE_RAIDEN_SPI_PROTOCOL_V2:
1343 /*
1344 * Protocol V2 requires the host to query the device for
1345 * its maximum read and write sizes
1346 */
1347 spi_config->command = send_command_v2;
1348 status = get_spi_config_v2(ctx_data);
1349 if (status) {
1350 return status;
1351 }
1352 break;
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001353 default:
Brian J. Nemec2cb1f332020-07-20 10:32:21 -07001354 msg_pdbg("Raiden: Unknown USB SPI protocol version = %u\n",
1355 ctx_data->protocol_version);
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001356 return USB_SPI_HOST_INIT_FAILURE;
1357 }
1358
1359 /*
1360 * Unfortunately there doesn't seem to be a way to specify the maximum number
1361 * of bytes that your SPI device can read/write, these values are the maximum
1362 * data chunk size that flashrom will package up with an additional five bytes
1363 * of command for the flash device.
1364 *
1365 * The largest command that flashrom generates is the byte program command, so
1366 * we use that command header maximum size here. If we didn't include the
1367 * offset, flashrom may request a SPI transfer that is too large for the SPI
1368 * device to support.
1369 */
1370 spi_config->max_data_write = ctx_data->max_spi_write_count -
1371 JEDEC_BYTE_PROGRAM_OUTSIZE;
1372 spi_config->max_data_read = ctx_data->max_spi_read_count -
1373 JEDEC_BYTE_PROGRAM_OUTSIZE;
1374
1375 return 0;
1376}
1377
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001378static int raiden_debug_spi_shutdown(void * data)
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001379{
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001380 struct spi_master *spi_config = data;
1381 struct raiden_debug_spi_data *ctx_data =
1382 (struct raiden_debug_spi_data *)spi_config->data;
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001383
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001384 int ret = LIBUSB(libusb_control_transfer(
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001385 ctx_data->dev->handle,
Edward O'Callaghan48474962020-03-05 14:50:46 +11001386 LIBUSB_ENDPOINT_OUT |
1387 LIBUSB_REQUEST_TYPE_VENDOR |
1388 LIBUSB_RECIPIENT_INTERFACE,
1389 RAIDEN_DEBUG_SPI_REQ_DISABLE,
1390 0,
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001391 ctx_data->dev->interface_descriptor->bInterfaceNumber,
Edward O'Callaghan48474962020-03-05 14:50:46 +11001392 NULL,
1393 0,
1394 TRANSFER_TIMEOUT_MS));
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001395 if (ret != 0) {
1396 msg_perr("Raiden: Failed to disable SPI bridge\n");
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001397 free(ctx_data);
1398 free(spi_config);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001399 return ret;
1400 }
1401
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001402 usb_device_free(ctx_data->dev);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001403 libusb_exit(NULL);
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001404 free(ctx_data);
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001405 free(spi_config);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001406
1407 return 0;
1408}
1409
Mary Ruthvenc66d5f82020-07-16 12:03:20 -07001410static int get_ap_request_type(void)
1411{
1412 int ap_request = RAIDEN_DEBUG_SPI_REQ_ENABLE_AP;
1413 char *custom_rst_str = extract_programmer_param("custom_rst");
1414 if (custom_rst_str) {
1415 if (!strcasecmp(custom_rst_str, "true"))
1416 ap_request = RAIDEN_DEBUG_SPI_REQ_ENABLE_AP_CUSTOM;
1417 else {
1418 msg_perr("Invalid custom rst param: %s\n",
1419 custom_rst_str);
1420 ap_request = -1;
1421 }
1422 }
1423 free(custom_rst_str);
1424 return ap_request;
1425}
1426
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001427static int get_target(void)
1428{
1429 int request_enable = RAIDEN_DEBUG_SPI_REQ_ENABLE;
1430
1431 char *target_str = extract_programmer_param("target");
1432 if (target_str) {
1433 if (!strcasecmp(target_str, "ap"))
Mary Ruthvenc66d5f82020-07-16 12:03:20 -07001434 request_enable = get_ap_request_type();
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001435 else if (!strcasecmp(target_str, "ec"))
1436 request_enable = RAIDEN_DEBUG_SPI_REQ_ENABLE_EC;
1437 else {
1438 msg_perr("Invalid target: %s\n", target_str);
1439 request_enable = -1;
1440 }
1441 }
1442 free(target_str);
Mary Ruthvenc66d5f82020-07-16 12:03:20 -07001443 msg_pinfo("Raiden target: %d\n", request_enable);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001444
1445 return request_enable;
1446}
1447
1448static void free_dev_list(struct usb_device **dev_lst)
1449{
1450 struct usb_device *dev = *dev_lst;
1451 /* free devices we don't care about */
1452 dev = dev->next;
1453 while (dev)
1454 dev = usb_device_free(dev);
1455}
1456
Thomas Heijligen4f5169d2021-05-04 15:32:17 +02001457static int raiden_debug_spi_init(void)
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001458{
1459 struct usb_match match;
1460 char *serial = extract_programmer_param("serial");
1461 struct usb_device *current;
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001462 struct usb_device *device = NULL;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001463 int found = 0;
1464 int ret;
1465
1466 int request_enable = get_target();
Patrick Georgiba6003f2020-04-23 09:26:12 +02001467 if (request_enable < 0) {
1468 free(serial);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001469 return 1;
Patrick Georgiba6003f2020-04-23 09:26:12 +02001470 }
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001471
1472 usb_match_init(&match);
1473
1474 usb_match_value_default(&match.vid, GOOGLE_VID);
1475 usb_match_value_default(&match.class, LIBUSB_CLASS_VENDOR_SPEC);
1476 usb_match_value_default(&match.subclass, GOOGLE_RAIDEN_SPI_SUBCLASS);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001477
1478 ret = LIBUSB(libusb_init(NULL));
1479 if (ret != 0) {
1480 msg_perr("Raiden: libusb_init failed\n");
Patrick Georgi1cef9362020-04-23 09:26:12 +02001481 free(serial);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001482 return ret;
1483 }
1484
1485 ret = usb_device_find(&match, &current);
1486 if (ret != 0) {
1487 msg_perr("Raiden: Failed to find devices\n");
Patrick Georgi1cef9362020-04-23 09:26:12 +02001488 free(serial);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001489 return ret;
1490 }
1491
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001492 uint8_t in_endpoint = 0;
1493 uint8_t out_endpoint = 0;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001494 while (current) {
1495 device = current;
1496
1497 if (find_endpoints(device, &in_endpoint, &out_endpoint)) {
Edward O'Callaghan48474962020-03-05 14:50:46 +11001498 msg_pdbg("Raiden: Failed to find valid endpoints on device");
1499 usb_device_show(" ", current);
1500 goto loop_end;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001501 }
1502
1503 if (usb_device_claim(device)) {
Edward O'Callaghan48474962020-03-05 14:50:46 +11001504 msg_pdbg("Raiden: Failed to claim USB device");
1505 usb_device_show(" ", current);
1506 goto loop_end;
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001507 }
1508
1509 if (!serial) {
1510 found = 1;
1511 goto loop_end;
1512 } else {
Angel Ponsf41d2482021-06-07 13:29:13 +02001513 unsigned char dev_serial[32] = { 0 };
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001514 struct libusb_device_descriptor descriptor;
1515 int rc;
1516
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001517 if (libusb_get_device_descriptor(device->device, &descriptor)) {
1518 msg_pdbg("USB: Failed to get device descriptor.\n");
1519 goto loop_end;
1520 }
1521
1522 rc = libusb_get_string_descriptor_ascii(device->handle,
Edward O'Callaghan48474962020-03-05 14:50:46 +11001523 descriptor.iSerialNumber,
1524 dev_serial,
1525 sizeof(dev_serial));
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001526 if (rc < 0) {
1527 LIBUSB(rc);
1528 } else {
1529 if (strcmp(serial, (char *)dev_serial)) {
1530 msg_pdbg("Raiden: Serial number %s did not match device", serial);
1531 usb_device_show(" ", current);
1532 } else {
1533 msg_pinfo("Raiden: Serial number %s matched device", serial);
1534 usb_device_show(" ", current);
1535 found = 1;
1536 }
1537 }
1538 }
1539
1540loop_end:
1541 if (found)
1542 break;
1543 else
1544 current = usb_device_free(current);
1545 }
1546
1547 if (!device || !found) {
1548 msg_perr("Raiden: No usable device found.\n");
Patrick Georgi1cef9362020-04-23 09:26:12 +02001549 free(serial);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001550 return 1;
1551 }
1552
1553 free_dev_list(&current);
1554
1555 ret = LIBUSB(libusb_control_transfer(
Edward O'Callaghan48474962020-03-05 14:50:46 +11001556 device->handle,
1557 LIBUSB_ENDPOINT_OUT |
1558 LIBUSB_REQUEST_TYPE_VENDOR |
1559 LIBUSB_RECIPIENT_INTERFACE,
1560 request_enable,
1561 0,
1562 device->interface_descriptor->bInterfaceNumber,
1563 NULL,
1564 0,
1565 TRANSFER_TIMEOUT_MS));
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001566 if (ret != 0) {
1567 msg_perr("Raiden: Failed to enable SPI bridge\n");
1568 return ret;
1569 }
1570
Edward O'Callaghan3e67cb72020-03-05 15:12:29 +11001571 /*
1572 * Allow for power to settle on the AP and EC flash devices.
1573 * Load switches can have a 1-3 ms turn on time, and SPI flash devices
1574 * can require up to 10 ms from power on to the first write.
1575 */
1576 if ((request_enable == RAIDEN_DEBUG_SPI_REQ_ENABLE_AP) ||
1577 (request_enable == RAIDEN_DEBUG_SPI_REQ_ENABLE_EC))
1578 usleep(50 * 1000);
1579
Angel Pons3bd47522021-06-07 12:33:53 +02001580 struct spi_master *spi_config = calloc(1, sizeof(*spi_config));
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001581 if (!spi_config) {
1582 msg_perr("Unable to allocate space for SPI master.\n");
1583 return SPI_GENERIC_ERROR;
1584 }
Angel Pons3bd47522021-06-07 12:33:53 +02001585 struct raiden_debug_spi_data *data = calloc(1, sizeof(*data));
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001586 if (!data) {
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001587 free(spi_config);
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001588 msg_perr("Unable to allocate space for extra SPI master data.\n");
1589 return SPI_GENERIC_ERROR;
1590 }
1591
Angel Ponsf41d2482021-06-07 13:29:13 +02001592 *spi_config = spi_master_raiden_debug;
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001593
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001594 data->dev = device;
1595 data->in_ep = in_endpoint;
1596 data->out_ep = out_endpoint;
1597
Anastasia Klimchuk45e0a072021-05-25 13:53:25 +10001598 spi_config->data = data; /* data is needed to configure protocol below */
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001599 /*
1600 * The SPI master needs to be configured based on the device connected.
1601 * Using the device protocol interrogation, we will set the limits on
1602 * the write and read sizes and switch command functions.
1603 */
1604 ret = configure_protocol(spi_config);
1605 if (ret) {
1606 msg_perr("Raiden: Error configuring protocol\n"
1607 " protocol = %u\n"
1608 " status = 0x%05x\n",
1609 data->dev->interface_descriptor->bInterfaceProtocol, ret);
1610 free(data);
1611 free(spi_config);
1612 return SPI_GENERIC_ERROR;
1613 }
Edward O'Callaghan757e8922020-04-03 12:52:32 +11001614
Anastasia Klimchuk45e0a072021-05-25 13:53:25 +10001615 register_spi_master(spi_config, data);
Brian J. Nemeca7b526d2020-07-19 13:37:42 -07001616 register_shutdown(raiden_debug_spi_shutdown, spi_config);
Edward O'Callaghanad08aef2020-03-02 18:16:14 +11001617
1618 return 0;
1619}
Thomas Heijligen4f5169d2021-05-04 15:32:17 +02001620
1621const struct programmer_entry programmer_raiden_debug_spi = {
1622 .name = "raiden_debug_spi",
1623 .type = USB,
1624 .devs.dev = devs_raiden,
1625 .init = raiden_debug_spi_init,
1626 .map_flash_region = fallback_map,
1627 .unmap_flash_region = fallback_unmap,
1628 .delay = internal_delay,
1629};