lkml.org 
[lkml]   [2009]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 37/88] spi: spi_write_then_read() bugfixes
    2.6.28-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: David Brownell <dbrownell@users.sourceforge.net>

    upstream commit: bdff549ebeff92b1a6952e5501caf16a6f8898c8

    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 <dbrownell@users.sourceforge.net>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Chris Wright <chrisw@sous-sol.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
    ---
    drivers/spi/spi.c | 22 ++++++++++++++--------
    1 file changed, 14 insertions(+), 8 deletions(-)

    --- a/drivers/spi/spi.c
    +++ b/drivers/spi/spi.c
    @@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_devic

    int 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,
    @@ -671,9 +671,15 @@ int spi_write_then_read(struct spi_devic
    return -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)) {
    @@ -684,15 +690,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);



    \
     
     \ /
      Last update: 2009-04-30 19:27    [W:4.103 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site