From e7b4a53c42f2bc6cc439638963da29cbb6c90216 Mon Sep 17 00:00:00 2001
From: Peter Korsgaard <jacmet@sunsite.dk>
Date: Wed, 10 Sep 2008 11:07:56 +0200
Subject: [PATCH] spi_mpc83xx: handle odd transfer sizes

Make spi_mpc83xx more robust against odd transfer sizes:
- Error out on transfer length != multiple of bytes per word
- Fix crash on transfer length = 0 (1 word was always sent and
  length decremented before check against 0).

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
 drivers/spi/spi_mpc83xx.c |   33 ++++++++++++++++++++++-----------
 1 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 070c621..35067a5 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -315,24 +315,35 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	if (t->bits_per_word)
 		bits_per_word = t->bits_per_word;
 	len = t->len;
-	if (bits_per_word > 8)
+	if (bits_per_word > 8) {
+		/* invalid length? */
+		if (len & 1)
+			return len;
 		len /= 2;
-	if (bits_per_word > 16)
+	}
+	if (bits_per_word > 16) {
+		/* invalid length? */
+		if (len & 1)
+			return len;
 		len /= 2;
+	}
 	mpc83xx_spi->count = len;
-	INIT_COMPLETION(mpc83xx_spi->done);
 
-	/* enable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+	if (len) {
+		INIT_COMPLETION(mpc83xx_spi->done);
+
+		/* enable rx ints */
+		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
 
-	/* transmit word */
-	word = mpc83xx_spi->get_tx(mpc83xx_spi);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+		/* transmit word */
+		word = mpc83xx_spi->get_tx(mpc83xx_spi);
+		mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
 
-	wait_for_completion(&mpc83xx_spi->done);
+		wait_for_completion(&mpc83xx_spi->done);
 
-	/* disable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+		/* disable rx ints */
+		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+	}
 
 	return mpc83xx_spi->count;
 }
-- 
1.5.6.3

