From: Christophe Leroy Date: Tue, 9 Apr 2024 06:38:08 +0000 (+0200) Subject: spi: mpc8xx: Fix transfert when input or output buffer is NULL X-Git-Url: http://git.dujemihanovic.xyz/%22http:/www.sics.se/static/%7B%7B%20%24style.Permalink%20%7D%7D?a=commitdiff_plain;h=ea208201a12913e7a5b7b4b38624942effa44c05;p=u-boot.git spi: mpc8xx: Fix transfert when input or output buffer is NULL xfer ops can be passed a NULL input or output buffer. At the time being the driver ignores it and overwrites memory at 0. Define a dummy buffer and use it when either input or output buffer is NULL. Bail out when both are NULL as it shouldn't. Also increase MAX_BUFFER len to 32k as the current is pretty low. Signed-off-by: Christophe Leroy --- diff --git a/drivers/spi/mpc8xx_spi.c b/drivers/spi/mpc8xx_spi.c index 5c8d760935..2aa9c7d5df 100644 --- a/drivers/spi/mpc8xx_spi.c +++ b/drivers/spi/mpc8xx_spi.c @@ -29,7 +29,7 @@ #define CPM_SPI_BASE_RX CPM_SPI_BASE #define CPM_SPI_BASE_TX (CPM_SPI_BASE + sizeof(cbd_t)) -#define MAX_BUFFER 0x104 +#define MAX_BUFFER 0x8000 /* Max possible is 0xffff. We want power of 2 */ struct mpc8xx_priv { spi_t __iomem *spi; @@ -37,6 +37,8 @@ struct mpc8xx_priv { int max_cs; }; +static char dummy_buffer[MAX_BUFFER]; + static int mpc8xx_spi_set_mode(struct udevice *dev, uint mod) { return 0; @@ -154,6 +156,8 @@ static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen, int tm; size_t count = (bitlen + 7) / 8; + if (!din && !dout) + return -EINVAL; if (count > MAX_BUFFER) return -EINVAL; @@ -165,12 +169,12 @@ static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen, mpc8xx_spi_cs_activate(dev); /* Setting tx bd status and data length */ - out_be32(&tbdf->cbd_bufaddr, (ulong)dout); + out_be32(&tbdf->cbd_bufaddr, dout ? (ulong)dout : (ulong)dummy_buffer); out_be16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_LAST | BD_SC_WRAP); out_be16(&tbdf->cbd_datlen, count); /* Setting rx bd status and data length */ - out_be32(&rbdf->cbd_bufaddr, (ulong)din); + out_be32(&rbdf->cbd_bufaddr, din ? (ulong)din : (ulong)dummy_buffer); out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_WRAP); out_be16(&rbdf->cbd_datlen, 0); /* rx length has no significance */