* [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden @ 2016-04-12 11:56 Ben Hutchings [not found] ` <1460462185.32355.7.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 0 siblings, 1 reply; 7+ messages in thread From: Ben Hutchings @ 2016-04-12 11:56 UTC (permalink / raw) To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel Each transfer can specify 8, 16 or 32 bits per word independently of the default for the device being addressed. However, currently we calculate the number of words in the frame assuming that the word size is the device default. If multiple transfers in the same message have differing bits_per_word, we bitwise-or the different values in the WLEN register field. Fix both of these. Also rename 'frame_length' to 'frame_len_words' to make clear that it's not a byte count like spi_message::frame_length. Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Signed-off-by: Ben Hutchings <ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> --- v2: Rename frame_length to frame_len_words; improve commit message. drivers/spi/spi-ti-qspi.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 64318fcfacf2..2137f2112804 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -94,6 +94,7 @@ struct ti_qspi { #define QSPI_FLEN(n) ((n - 1) << 0) #define QSPI_WLEN_MAX_BITS 128 #define QSPI_WLEN_MAX_BYTES 16 +#define QSPI_WLEN_MASK QSPI_WLEN(QSPI_WLEN_MAX_BITS) /* STATUS REGISTER */ #define BUSY 0x01 @@ -373,7 +374,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, struct spi_device *spi = m->spi; struct spi_transfer *t; int status = 0, ret; - int frame_length; + unsigned int frame_len_words; /* setup device control reg */ qspi->dc = 0; @@ -385,21 +386,23 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, if (spi->mode & SPI_CS_HIGH) qspi->dc |= QSPI_CSPOL(spi->chip_select); - frame_length = (m->frame_length << 3) / spi->bits_per_word; - - frame_length = clamp(frame_length, 0, QSPI_FRAME); + frame_len_words = 0; + list_for_each_entry(t, &m->transfers, transfer_list) + frame_len_words += t->len / (t->bits_per_word >> 3); + frame_len_words = min_t(unsigned int, frame_len_words, QSPI_FRAME); /* setup command reg */ qspi->cmd = 0; qspi->cmd |= QSPI_EN_CS(spi->chip_select); - qspi->cmd |= QSPI_FLEN(frame_length); + qspi->cmd |= QSPI_FLEN(frame_len_words); ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); mutex_lock(&qspi->list_lock); list_for_each_entry(t, &m->transfers, transfer_list) { - qspi->cmd |= QSPI_WLEN(t->bits_per_word); + qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) | + QSPI_WLEN(t->bits_per_word)); ret = qspi_transfer_msg(qspi, t); if (ret) { -- 2.8.0.rc3 -- Ben Hutchings Software Developer, Codethink Ltd. -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 7+ messages in thread
[parent not found: <1460462185.32355.7.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>]
* [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly [not found] ` <1460462185.32355.7.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> @ 2016-04-12 11:58 ` Ben Hutchings [not found] ` <1460462294.32355.9.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-13 7:11 ` [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden Mark Brown 1 sibling, 1 reply; 7+ messages in thread From: Ben Hutchings @ 2016-04-12 11:58 UTC (permalink / raw) To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel We clamp frame_len_words to a maximum of 4096, but do not actually limit the number of words written or read through the DATA registers or the length added to spi_message::actual_length. This results in silent data corruption for commands longer than this maximum. Recalculate the length of each transfer, taking frame_len_words into account. Use this length in qspi_{read,write}_msg(), and to increment spi_message::actual_length. Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Signed-off-by: Ben Hutchings <ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> --- v2: Rebase; rename transfer_length to tranfer_len_words; improve commit message drivers/spi/spi-ti-qspi.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 2137f2112804..5044c6198332 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -225,16 +225,16 @@ static inline int ti_qspi_poll_wc(struct ti_qspi *qspi) return -ETIMEDOUT; } -static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { - int wlen, count, xfer_len; + int wlen, xfer_len; unsigned int cmd; const u8 *txbuf; u32 data; txbuf = t->tx_buf; cmd = qspi->cmd | QSPI_WR_SNGL; - count = t->len; wlen = t->bits_per_word >> 3; /* in bytes */ xfer_len = wlen; @@ -294,9 +294,10 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) return 0; } -static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { - int wlen, count; + int wlen; unsigned int cmd; u8 *rxbuf; @@ -313,7 +314,6 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) cmd |= QSPI_RD_SNGL; break; } - count = t->len; wlen = t->bits_per_word >> 3; /* in bytes */ while (count) { @@ -344,12 +344,13 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) return 0; } -static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { int ret; if (t->tx_buf) { - ret = qspi_write_msg(qspi, t); + ret = qspi_write_msg(qspi, t, count); if (ret) { dev_dbg(qspi->dev, "Error while writing\n"); return ret; @@ -357,7 +358,7 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) } if (t->rx_buf) { - ret = qspi_read_msg(qspi, t); + ret = qspi_read_msg(qspi, t, count); if (ret) { dev_dbg(qspi->dev, "Error while reading\n"); return ret; @@ -374,7 +375,8 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, struct spi_device *spi = m->spi; struct spi_transfer *t; int status = 0, ret; - unsigned int frame_len_words; + unsigned int frame_len_words, transfer_len_words; + int wlen; /* setup device control reg */ qspi->dc = 0; @@ -404,14 +406,20 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) | QSPI_WLEN(t->bits_per_word)); - ret = qspi_transfer_msg(qspi, t); + wlen = t->bits_per_word >> 3; + transfer_len_words = min(t->len / wlen, frame_len_words); + + ret = qspi_transfer_msg(qspi, t, transfer_len_words * wlen); if (ret) { dev_dbg(qspi->dev, "transfer message failed\n"); mutex_unlock(&qspi->list_lock); return -EINVAL; } - m->actual_length += t->len; + m->actual_length += transfer_len_words * wlen; + frame_len_words -= transfer_len_words; + if (frame_len_words == 0) + break; } mutex_unlock(&qspi->list_lock); -- 2.8.0.rc3 -- Ben Hutchings Software Developer, Codethink Ltd. -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 7+ messages in thread
[parent not found: <1460462294.32355.9.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>]
* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly [not found] ` <1460462294.32355.9.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> @ 2016-04-13 7:13 ` Mark Brown [not found] ` <20160413071324.GP14664-GFdadSzt00ze9xe1eoZjHA@public.gmane.org> 2016-04-13 7:13 ` Applied "spi: spi-ti-qspi: Handle truncated frames properly" to the spi tree Mark Brown 1 sibling, 1 reply; 7+ messages in thread From: Mark Brown @ 2016-04-13 7:13 UTC (permalink / raw) To: Ben Hutchings; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel [-- Attachment #1: Type: text/plain, Size: 202 bytes --] On Tue, Apr 12, 2016 at 12:58:14PM +0100, Ben Hutchings wrote: > - ret = qspi_transfer_msg(qspi, t); > + wlen = t->bits_per_word >> 3; I did ask you to fix this to just / 8 so it's more readable :/ [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <20160413071324.GP14664-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>]
* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly [not found] ` <20160413071324.GP14664-GFdadSzt00ze9xe1eoZjHA@public.gmane.org> @ 2016-04-13 9:31 ` Ben Hutchings [not found] ` <1460539893.32355.19.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 0 siblings, 1 reply; 7+ messages in thread From: Ben Hutchings @ 2016-04-13 9:31 UTC (permalink / raw) To: Mark Brown; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel On Wed, 2016-04-13 at 08:13 +0100, Mark Brown wrote: > On Tue, Apr 12, 2016 at 12:58:14PM +0100, Ben Hutchings wrote: > > > - ret = qspi_transfer_msg(qspi, t); > > + wlen = t->bits_per_word >> 3; > > I did ask you to fix this to just / 8 so it's more readable :/ Not explicitly. And that would be inconsistent with every other place this driver bits_per_word to a byte count. Ben. -- Ben Hutchings Software Developer, Codethink Ltd. -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <1460539893.32355.19.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>]
* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly [not found] ` <1460539893.32355.19.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> @ 2016-04-13 13:12 ` Mark Brown 0 siblings, 0 replies; 7+ messages in thread From: Mark Brown @ 2016-04-13 13:12 UTC (permalink / raw) To: Ben Hutchings; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel [-- Attachment #1: Type: text/plain, Size: 775 bytes --] On Wed, Apr 13, 2016 at 10:31:33AM +0100, Ben Hutchings wrote: > On Wed, 2016-04-13 at 08:13 +0100, Mark Brown wrote: > > On Tue, Apr 12, 2016 at 12:58:14PM +0100, Ben Hutchings wrote: > > > - ret = qspi_transfer_msg(qspi, t); > > > + wlen = t->bits_per_word >> 3; > > I did ask you to fix this to just / 8 so it's more readable :/ > Not explicitly. And that would be inconsistent with every other place > this driver bits_per_word to a byte count. If someone is reviewing code and showing a different way of doing things it is reasonable to interpret that as a request to change things. It's best to engage with rather than completely ignore the feedback, what I'd have said would have been that it is better to have clear code than be consistent with unclear code. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Applied "spi: spi-ti-qspi: Handle truncated frames properly" to the spi tree [not found] ` <1460462294.32355.9.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-13 7:13 ` Mark Brown @ 2016-04-13 7:13 ` Mark Brown 1 sibling, 0 replies; 7+ messages in thread From: Mark Brown @ 2016-04-13 7:13 UTC (permalink / raw) To: Ben Hutchings Cc: Mark Brown, stable-u79uwXL29TY76Z2rM5mHXA, Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel The patch spi: spi-ti-qspi: Handle truncated frames properly has been applied to the spi tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 1ff7760ff66b98ef244bf0e5e2bd5310651205ad Mon Sep 17 00:00:00 2001 From: Ben Hutchings <ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> Date: Tue, 12 Apr 2016 12:58:14 +0100 Subject: [PATCH] spi: spi-ti-qspi: Handle truncated frames properly We clamp frame_len_words to a maximum of 4096, but do not actually limit the number of words written or read through the DATA registers or the length added to spi_message::actual_length. This results in silent data corruption for commands longer than this maximum. Recalculate the length of each transfer, taking frame_len_words into account. Use this length in qspi_{read,write}_msg(), and to increment spi_message::actual_length. Signed-off-by: Ben Hutchings <ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org --- drivers/spi/spi-ti-qspi.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 0ee4139dec48..443f664534e1 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -236,16 +236,16 @@ static inline int ti_qspi_poll_wc(struct ti_qspi *qspi) return -ETIMEDOUT; } -static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { - int wlen, count, xfer_len; + int wlen, xfer_len; unsigned int cmd; const u8 *txbuf; u32 data; txbuf = t->tx_buf; cmd = qspi->cmd | QSPI_WR_SNGL; - count = t->len; wlen = t->bits_per_word >> 3; /* in bytes */ xfer_len = wlen; @@ -305,9 +305,10 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) return 0; } -static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { - int wlen, count; + int wlen; unsigned int cmd; u8 *rxbuf; @@ -324,7 +325,6 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) cmd |= QSPI_RD_SNGL; break; } - count = t->len; wlen = t->bits_per_word >> 3; /* in bytes */ while (count) { @@ -355,12 +355,13 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) return 0; } -static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) +static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t, + int count) { int ret; if (t->tx_buf) { - ret = qspi_write_msg(qspi, t); + ret = qspi_write_msg(qspi, t, count); if (ret) { dev_dbg(qspi->dev, "Error while writing\n"); return ret; @@ -368,7 +369,7 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) } if (t->rx_buf) { - ret = qspi_read_msg(qspi, t); + ret = qspi_read_msg(qspi, t, count); if (ret) { dev_dbg(qspi->dev, "Error while reading\n"); return ret; @@ -451,7 +452,8 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, struct spi_device *spi = m->spi; struct spi_transfer *t; int status = 0, ret; - unsigned int frame_len_words; + unsigned int frame_len_words, transfer_len_words; + int wlen; /* setup device control reg */ qspi->dc = 0; @@ -484,14 +486,20 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) | QSPI_WLEN(t->bits_per_word)); - ret = qspi_transfer_msg(qspi, t); + wlen = t->bits_per_word >> 3; + transfer_len_words = min(t->len / wlen, frame_len_words); + + ret = qspi_transfer_msg(qspi, t, transfer_len_words * wlen); if (ret) { dev_dbg(qspi->dev, "transfer message failed\n"); mutex_unlock(&qspi->list_lock); return -EINVAL; } - m->actual_length += t->len; + m->actual_length += transfer_len_words * wlen; + frame_len_words -= transfer_len_words; + if (frame_len_words == 0) + break; } mutex_unlock(&qspi->list_lock); -- 2.8.0.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden [not found] ` <1460462185.32355.7.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-12 11:58 ` [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly Ben Hutchings @ 2016-04-13 7:11 ` Mark Brown 1 sibling, 0 replies; 7+ messages in thread From: Mark Brown @ 2016-04-13 7:11 UTC (permalink / raw) To: Ben Hutchings; +Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, CT kernel [-- Attachment #1: Type: text/plain, Size: 409 bytes --] On Tue, Apr 12, 2016 at 12:56:25PM +0100, Ben Hutchings wrote: > Each transfer can specify 8, 16 or 32 bits per word independently of > the default for the device being addressed. However, currently we > calculate the number of words in the frame assuming that the word size > is the device default. I've applied this but it required some defuzzing, it appears to have been generated against an old kernel. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-04-13 13:12 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-12 11:56 [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden Ben Hutchings [not found] ` <1460462185.32355.7.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-12 11:58 ` [PATCH v2 2/2] spi: spi-ti-qspi: Handle truncated frames properly Ben Hutchings [not found] ` <1460462294.32355.9.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-13 7:13 ` Mark Brown [not found] ` <20160413071324.GP14664-GFdadSzt00ze9xe1eoZjHA@public.gmane.org> 2016-04-13 9:31 ` Ben Hutchings [not found] ` <1460539893.32355.19.camel-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org> 2016-04-13 13:12 ` Mark Brown 2016-04-13 7:13 ` Applied "spi: spi-ti-qspi: Handle truncated frames properly" to the spi tree Mark Brown 2016-04-13 7:11 ` [PATCH v2 1/2] spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden Mark Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).