spi: spi_mpc8xxx.c: fix potential memory corruption.
diff mbox

Message ID OF224832EB.3B3694C0-ONC1257722.00574009-C1257722.00577791@transmode.se
State Superseded
Headers show

Commit Message

Joakim Tjernlund May 13, 2010, 3:55 p.m. UTC
None

Patch
diff mbox

diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index c312d0e..c995aa5 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -315,41 +315,51 @@  int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 	if (!hz)
 		hz = spi->max_speed_hz;

-	cs->rx_shift = 0;
-	cs->tx_shift = 0;
-	if (bits_per_word <= 8) {
-		cs->get_rx = mpc8xxx_spi_rx_buf_u8;
-		cs->get_tx = mpc8xxx_spi_tx_buf_u8;
-		if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
-			cs->rx_shift = 16;
-			cs->tx_shift = 24;
-		}
-	} else if (bits_per_word <= 16) {
-		cs->get_rx = mpc8xxx_spi_rx_buf_u16;
-		cs->get_tx = mpc8xxx_spi_tx_buf_u16;
-		if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
-			cs->rx_shift = 16;
-			cs->tx_shift = 16;
+	if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
+		cs->rx_shift = 0;
+		cs->tx_shift = 0;
+		if (bits_per_word <= 8) {
+			cs->get_rx = mpc8xxx_spi_rx_buf_u8;
+			cs->get_tx = mpc8xxx_spi_tx_buf_u8;
+			if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
+				cs->rx_shift = 16;
+				cs->tx_shift = 24;
+			}
+		} else if (bits_per_word <= 16) {
+			cs->get_rx = mpc8xxx_spi_rx_buf_u16;
+			cs->get_tx = mpc8xxx_spi_tx_buf_u16;
+			if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) {
+				cs->rx_shift = 16;
+				cs->tx_shift = 16;
+			}
+		} else if (bits_per_word <= 32) {
+			cs->get_rx = mpc8xxx_spi_rx_buf_u32;
+			cs->get_tx = mpc8xxx_spi_tx_buf_u32;
+		} else
+			return -EINVAL;
+
+		if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE &&
+		    spi->mode & SPI_LSB_FIRST) {
+			cs->tx_shift = 0;
+			if (bits_per_word <= 8)
+				cs->rx_shift = 8;
+			else
+				cs->rx_shift = 0;
 		}
-	} else if (bits_per_word <= 32) {
-		cs->get_rx = mpc8xxx_spi_rx_buf_u32;
-		cs->get_tx = mpc8xxx_spi_tx_buf_u32;
-	} else
-		return -EINVAL;

-	if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE &&
-			spi->mode & SPI_LSB_FIRST) {
-		cs->tx_shift = 0;
-		if (bits_per_word <= 8)
-			cs->rx_shift = 8;
-		else
-			cs->rx_shift = 0;
-	}
+		mpc8xxx_spi->rx_shift = cs->rx_shift;
+		mpc8xxx_spi->tx_shift = cs->tx_shift;
+		mpc8xxx_spi->get_rx = cs->get_rx;
+		mpc8xxx_spi->get_tx = cs->get_tx;

-	mpc8xxx_spi->rx_shift = cs->rx_shift;
-	mpc8xxx_spi->tx_shift = cs->tx_shift;
-	mpc8xxx_spi->get_rx = cs->get_rx;
-	mpc8xxx_spi->get_tx = cs->get_tx;
+	} else if (mpc8xxx_spi->flags & SPI_QE) {
+		/* Note: 32 bits word, LSB works iff
+		 *  tfcr/rfcr is set to CPMFCR_GBL */
+		if (spi->mode & SPI_LSB_FIRST &&
+			bits_per_word != 8)
+			return -EINVAL;
+		bits_per_word = 8;
+	}

 	if (bits_per_word == 32)
 		bits_per_word = 0;