|
@@ -1545,12 +1545,18 @@ int spi_write_then_read(struct spi_device *spi,
|
|
|
struct spi_transfer x[2];
|
|
|
u8 *local_buf;
|
|
|
|
|
|
- /* Use preallocated DMA-safe buffer. We can't avoid copying here,
|
|
|
- * (as a pure convenience thing), but we can keep heap costs
|
|
|
- * out of the hot path ...
|
|
|
+ /* Use preallocated DMA-safe buffer if we can. We can't avoid
|
|
|
+ * copying here, (as a pure convenience thing), but we can
|
|
|
+ * keep heap costs out of the hot path unless someone else is
|
|
|
+ * using the pre-allocated buffer or the transfer is too large.
|
|
|
*/
|
|
|
- if ((n_tx + n_rx) > SPI_BUFSIZ)
|
|
|
- return -EINVAL;
|
|
|
+ if ((n_tx + n_rx) > SPI_BUFSIZ || !mutex_trylock(&lock)) {
|
|
|
+ local_buf = kmalloc(max(SPI_BUFSIZ, n_tx + n_rx), GFP_KERNEL);
|
|
|
+ if (!local_buf)
|
|
|
+ return -ENOMEM;
|
|
|
+ } else {
|
|
|
+ local_buf = buf;
|
|
|
+ }
|
|
|
|
|
|
spi_message_init(&message);
|
|
|
memset(x, 0, sizeof x);
|
|
@@ -1563,14 +1569,6 @@ int spi_write_then_read(struct spi_device *spi,
|
|
|
spi_message_add_tail(&x[1], &message);
|
|
|
}
|
|
|
|
|
|
- /* ... unless someone else is using the pre-allocated buffer */
|
|
|
- if (!mutex_trylock(&lock)) {
|
|
|
- local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
|
|
|
- if (!local_buf)
|
|
|
- return -ENOMEM;
|
|
|
- } else
|
|
|
- local_buf = buf;
|
|
|
-
|
|
|
memcpy(local_buf, txbuf, n_tx);
|
|
|
x[0].tx_buf = local_buf;
|
|
|
x[1].rx_buf = local_buf + n_tx;
|