Skip to content

Commit 3354aca

Browse files
committed
[ot] hw/opentitan: spi_device: discard all packets in failed transaction
If one packet in a transaction triggers an error and needs discarding, we must continue discarding the remaining packets until CS is released. Signed-off-by: James Wainwright <[email protected]>
1 parent 61c4166 commit 3354aca

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

hw/opentitan/ot_spi_device.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ typedef enum {
366366
SPI_BUS_FLASH,
367367
SPI_BUS_DISCARD,
368368
SPI_BUS_ERROR,
369+
SPI_BUS_DISCARD_PACKET,
369370
} OtSpiBusState;
370371

371372
typedef enum {
@@ -601,6 +602,7 @@ static const char *BUS_STATE_NAMES[] = {
601602
STATE_NAME_ENTRY(SPI_BUS_FLASH),
602603
STATE_NAME_ENTRY(SPI_BUS_DISCARD),
603604
STATE_NAME_ENTRY(SPI_BUS_ERROR),
605+
STATE_NAME_ENTRY(SPI_BUS_DISCARD_PACKET),
604606
};
605607

606608
static const char *FLASH_STATE_NAMES[] = {
@@ -1924,6 +1926,12 @@ static void ot_spi_device_chr_handle_header(OtSPIDeviceState *s)
19241926
return;
19251927
}
19261928

1929+
/* discard the packet if we're within a failed transaction */
1930+
if (s->bus.state == SPI_BUS_DISCARD_PACKET) {
1931+
BUS_CHANGE_STATE(s, DISCARD);
1932+
return;
1933+
}
1934+
19271935
switch (ot_spi_device_get_mode(s)) {
19281936
case CTRL_MODE_FLASH:
19291937
BUS_CHANGE_STATE(s, FLASH);
@@ -1984,6 +1992,7 @@ static int ot_spi_device_chr_can_receive(void *opaque)
19841992
unsigned length;
19851993

19861994
switch (bus->state) {
1995+
case SPI_BUS_DISCARD_PACKET:
19871996
case SPI_BUS_IDLE:
19881997
length = fifo8_num_free(&bus->chr_fifo);
19891998
break;
@@ -2013,6 +2022,7 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20132022

20142023
switch (bus->state) {
20152024
case SPI_BUS_IDLE:
2025+
case SPI_BUS_DISCARD_PACKET:
20162026
g_assert(size <= fifo8_num_free(&bus->chr_fifo));
20172027
while (size--) {
20182028
fifo8_push(&bus->chr_fifo, *buf++);
@@ -2034,12 +2044,31 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20342044
break;
20352045
}
20362046

2037-
if (!bus->byte_count) {
2038-
if (bus->release) {
2039-
ot_spi_device_release(s);
2040-
} else {
2047+
if (bus->byte_count) {
2048+
/* there is more to process in this state */
2049+
return;
2050+
}
2051+
2052+
if (bus->release) {
2053+
/* final packet in transaction, release CS */
2054+
ot_spi_device_release(s);
2055+
return;
2056+
}
2057+
2058+
/* more packets to process in transaction, prepare to receive another header */
2059+
switch (bus->state) {
2060+
case SPI_BUS_IDLE:
2061+
case SPI_BUS_FLASH:
2062+
case SPI_BUS_DISCARD_PACKET:
20412063
BUS_CHANGE_STATE(s, IDLE);
2042-
}
2064+
break;
2065+
case SPI_BUS_DISCARD:
2066+
case SPI_BUS_ERROR:
2067+
BUS_CHANGE_STATE(s, DISCARD_PACKET);
2068+
break;
2069+
default:
2070+
g_assert_not_reached();
2071+
break;
20432072
}
20442073
}
20452074

0 commit comments

Comments
 (0)