spi: core: Validate length of the transfers in message
authorIvan T. Ivanov <iivanov@mm-sol.com>
Thu, 20 Feb 2014 10:02:08 +0000 (12:02 +0200)
committerMark Brown <broonie@linaro.org>
Sat, 22 Feb 2014 02:59:56 +0000 (11:59 +0900)
SPI transfer length should be multiple of SPI word size,
where SPI word size should be power-of-two multiple

Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/spi/spi.c

index bb660145d19ebe0099e2f4966d57d4e4951b28ee..1b53eee2cbcac6bfa7c5020fbb5278016b0a20a3 100644 (file)
@@ -1617,6 +1617,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 {
        struct spi_master *master = spi->master;
        struct spi_transfer *xfer;
+       int w_size, n_words;
 
        if (list_empty(&message->transfers))
                return -EINVAL;
@@ -1668,6 +1669,22 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
                                return -EINVAL;
                }
 
+               /*
+                * SPI transfer length should be multiple of SPI word size
+                * where SPI word size should be power-of-two multiple
+                */
+               if (xfer->bits_per_word <= 8)
+                       w_size = 1;
+               else if (xfer->bits_per_word <= 16)
+                       w_size = 2;
+               else
+                       w_size = 4;
+
+               n_words = xfer->len / w_size;
+               /* No partial transfers accepted */
+               if (!n_words || xfer->len % w_size)
+                       return -EINVAL;
+
                if (xfer->speed_hz && master->min_speed_hz &&
                    xfer->speed_hz < master->min_speed_hz)
                        return -EINVAL;