22 * QEMU OpenTitan SPI Device controller
33 *
44 * Copyright (c) 2023-2025 Rivos, Inc.
5+ * Copyright (c) 2025 lowRISC contributors.
56 *
67 * Author(s):
78 * Emmanuel Blot <[email protected] > @@ -366,6 +367,7 @@ typedef enum {
366367 SPI_BUS_FLASH ,
367368 SPI_BUS_DISCARD ,
368369 SPI_BUS_ERROR ,
370+ SPI_BUS_DISCARD_PACKET ,
369371} OtSpiBusState ;
370372
371373typedef enum {
@@ -601,6 +603,7 @@ static const char *BUS_STATE_NAMES[] = {
601603 STATE_NAME_ENTRY (SPI_BUS_FLASH ),
602604 STATE_NAME_ENTRY (SPI_BUS_DISCARD ),
603605 STATE_NAME_ENTRY (SPI_BUS_ERROR ),
606+ STATE_NAME_ENTRY (SPI_BUS_DISCARD_PACKET ),
604607};
605608
606609static const char * FLASH_STATE_NAMES [] = {
@@ -1924,6 +1927,12 @@ static void ot_spi_device_chr_handle_header(OtSPIDeviceState *s)
19241927 return ;
19251928 }
19261929
1930+ /* discard the packet if we're within a failed transaction */
1931+ if (s -> bus .state == SPI_BUS_DISCARD_PACKET ) {
1932+ BUS_CHANGE_STATE (s , DISCARD );
1933+ return ;
1934+ }
1935+
19271936 switch (ot_spi_device_get_mode (s )) {
19281937 case CTRL_MODE_FLASH :
19291938 BUS_CHANGE_STATE (s , FLASH );
@@ -1984,6 +1993,7 @@ static int ot_spi_device_chr_can_receive(void *opaque)
19841993 unsigned length ;
19851994
19861995 switch (bus -> state ) {
1996+ case SPI_BUS_DISCARD_PACKET :
19871997 case SPI_BUS_IDLE :
19881998 length = fifo8_num_free (& bus -> chr_fifo );
19891999 break ;
@@ -2013,6 +2023,7 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20132023
20142024 switch (bus -> state ) {
20152025 case SPI_BUS_IDLE :
2026+ case SPI_BUS_DISCARD_PACKET :
20162027 g_assert (size <= fifo8_num_free (& bus -> chr_fifo ));
20172028 while (size -- ) {
20182029 fifo8_push (& bus -> chr_fifo , * buf ++ );
@@ -2034,12 +2045,33 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20342045 break ;
20352046 }
20362047
2037- if (!bus -> byte_count ) {
2038- if (bus -> release ) {
2039- ot_spi_device_release (s );
2040- } else {
2041- BUS_CHANGE_STATE (s , IDLE );
2042- }
2048+ if (bus -> byte_count ) {
2049+ /* there is more to process in this state */
2050+ return ;
2051+ }
2052+
2053+ if (bus -> release ) {
2054+ /* final packet in transaction, release CS */
2055+ ot_spi_device_release (s );
2056+ return ;
2057+ }
2058+
2059+ /*
2060+ * more packets to process in transaction, prepare to receive another header
2061+ */
2062+ switch (bus -> state ) {
2063+ case SPI_BUS_IDLE :
2064+ case SPI_BUS_FLASH :
2065+ case SPI_BUS_DISCARD_PACKET :
2066+ BUS_CHANGE_STATE (s , IDLE );
2067+ break ;
2068+ case SPI_BUS_DISCARD :
2069+ case SPI_BUS_ERROR :
2070+ BUS_CHANGE_STATE (s , DISCARD_PACKET );
2071+ break ;
2072+ default :
2073+ g_assert_not_reached ();
2074+ break ;
20432075 }
20442076}
20452077
0 commit comments