]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
spi: mpc8xx: Fix transfert when input or output buffer is NULL
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Tue, 9 Apr 2024 06:38:08 +0000 (08:38 +0200)
committerChristophe Leroy <christophe.leroy@csgroup.eu>
Thu, 18 Apr 2024 13:47:46 +0000 (15:47 +0200)
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 <christophe.leroy@csgroup.eu>
drivers/spi/mpc8xx_spi.c

index 5c8d760935141214fb73aed988c2ca86fcf940bf..2aa9c7d5df921b5773e38843d27e5c387ca7f0ea 100644 (file)
@@ -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 */