spi: spi_write_then_read() bugfixes
PATCH 1/1 spi: spi_write_then_read() bugfixes
From: David Brownell <[email protected]>
The "simplify spi_write_then_read()" patch included two regressions from the 2.6.27 behaviors:
- The data it wrote out during the (full duplex) read side of the transfer was not zeroed.
- It fails completely on half duplex hardware, such as Microwire and most "3-wire" SPI variants.
So, revert that patch. A revised version should be submitted at some point, which can get the speedup on standard hardware (full duplex) without breaking on less-capable half-duplex stuff.
Signed-off-by David Brownell <[email protected]>
---
Fix should go into '28 and '29 stable kernels.
drivers/spi/spi.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
drivers/spi/spi.c +14 -8
@@ -658,7 +658,7 @@ int spi_write_then_read(struct spi_devicint status;struct spi_message message; -struct spi_transfer x; +struct spi_transfer x[2 ];u8 *local_buf;/* Use preallocated DMA-safe buffer. We can't avoid copying here,
@@ -669,9 +669,15 @@ int spi_write_then_read(struct spi_devicreturn -EINVAL ;spi_message_init (&message); -memset (&x,0 ,sizeof x); - x.len = n_tx + n_rx; -spi_message_add_tail (&x, &message); +memset (x,0 ,sizeof x); +if (n_tx) { + x[0 ].len = n_tx; +spi_message_add_tail (&x[0 ], &message); + } +if (n_rx) { + x[1 ].len = n_rx; +spi_message_add_tail (&x[1 ], &message); + }/* ... unless someone else is using the pre-allocated buffer */ if (!mutex_trylock (&lock)) {
@@ -682,15 +688,15 @@ int spi_write_then_read(struct spi_devic local_buf = buf;memcpy (local_buf, txbuf, n_tx); - x.tx_buf = local_buf; - x.rx_buf = local_buf; + x[0 ].tx_buf = local_buf; + x[1 ].rx_buf = local_buf + n_tx;/* do the i/o */ status =spi_sync (spi, &message);if (status ==0 ) -memcpy (rxbuf, x.rx_buf + n_tx, n_rx); +memcpy (rxbuf, x[1 ].rx_buf, n_rx); -if (x.tx_buf == buf) +if (x[0 ].tx_buf == buf)mutex_unlock (&lock);else kfree (local_buf);
------------------------------------------------------------------------------