diff options
author | Ivan T. Ivanov <iivanov@mm-sol.com> | 2014-02-20 05:02:08 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-21 21:59:56 -0500 |
commit | 4d94bd21b333c695eba97746b615e2efb30240cc (patch) | |
tree | 597abf7c2ef1da1d45724223f852f007424731f4 | |
parent | aec35f4ee6eefba616065547e6882c084cc7f5cb (diff) |
spi: core: Validate length of the transfers in message
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>
-rw-r--r-- | drivers/spi/spi.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index bb660145d19e..1b53eee2cbca 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -1617,6 +1617,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
1617 | { | 1617 | { |
1618 | struct spi_master *master = spi->master; | 1618 | struct spi_master *master = spi->master; |
1619 | struct spi_transfer *xfer; | 1619 | struct spi_transfer *xfer; |
1620 | int w_size, n_words; | ||
1620 | 1621 | ||
1621 | if (list_empty(&message->transfers)) | 1622 | if (list_empty(&message->transfers)) |
1622 | return -EINVAL; | 1623 | return -EINVAL; |
@@ -1668,6 +1669,22 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
1668 | return -EINVAL; | 1669 | return -EINVAL; |
1669 | } | 1670 | } |
1670 | 1671 | ||
1672 | /* | ||
1673 | * SPI transfer length should be multiple of SPI word size | ||
1674 | * where SPI word size should be power-of-two multiple | ||
1675 | */ | ||
1676 | if (xfer->bits_per_word <= 8) | ||
1677 | w_size = 1; | ||
1678 | else if (xfer->bits_per_word <= 16) | ||
1679 | w_size = 2; | ||
1680 | else | ||
1681 | w_size = 4; | ||
1682 | |||
1683 | n_words = xfer->len / w_size; | ||
1684 | /* No partial transfers accepted */ | ||
1685 | if (!n_words || xfer->len % w_size) | ||
1686 | return -EINVAL; | ||
1687 | |||
1671 | if (xfer->speed_hz && master->min_speed_hz && | 1688 | if (xfer->speed_hz && master->min_speed_hz && |
1672 | xfer->speed_hz < master->min_speed_hz) | 1689 | xfer->speed_hz < master->min_speed_hz) |
1673 | return -EINVAL; | 1690 | return -EINVAL; |