| From 05845fa312df22c1f0e728f89c212ba7dedce1ae Mon Sep 17 00:00:00 2001 |
| From: Peng Fan <peng.fan@nxp.com> |
| Date: Wed, 13 Nov 2019 05:37:42 +0000 |
| Subject: [PATCH] tty: serial: pch_uart: correct usage of dma_unmap_sg |
| |
| commit 74887542fdcc92ad06a48c0cca17cdf09fc8aa00 upstream. |
| |
| Per Documentation/DMA-API-HOWTO.txt, |
| To unmap a scatterlist, just call: |
| dma_unmap_sg(dev, sglist, nents, direction); |
| |
| .. note:: |
| |
| The 'nents' argument to the dma_unmap_sg call must be |
| the _same_ one you passed into the dma_map_sg call, |
| it should _NOT_ be the 'count' value _returned_ from the |
| dma_map_sg call. |
| |
| However in the driver, priv->nent is directly assigned with value |
| returned from dma_map_sg, and dma_unmap_sg use priv->nent for unmap, |
| this breaks the API usage. |
| |
| So introduce a new entry orig_nent to remember 'nents'. |
| |
| Fixes: da3564ee027e ("pch_uart: add multi-scatter processing") |
| Signed-off-by: Peng Fan <peng.fan@nxp.com> |
| Link: https://lore.kernel.org/r/1573623259-6339-1-git-send-email-peng.fan@nxp.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c |
| index 6157213a8359..c16234bca78f 100644 |
| --- a/drivers/tty/serial/pch_uart.c |
| +++ b/drivers/tty/serial/pch_uart.c |
| @@ -233,6 +233,7 @@ struct eg20t_port { |
| struct dma_chan *chan_rx; |
| struct scatterlist *sg_tx_p; |
| int nent; |
| + int orig_nent; |
| struct scatterlist sg_rx; |
| int tx_dma_use; |
| void *rx_buf_virt; |
| @@ -787,9 +788,10 @@ static void pch_dma_tx_complete(void *arg) |
| } |
| xmit->tail &= UART_XMIT_SIZE - 1; |
| async_tx_ack(priv->desc_tx); |
| - dma_unmap_sg(port->dev, sg, priv->nent, DMA_TO_DEVICE); |
| + dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE); |
| priv->tx_dma_use = 0; |
| priv->nent = 0; |
| + priv->orig_nent = 0; |
| kfree(priv->sg_tx_p); |
| pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); |
| } |
| @@ -1010,6 +1012,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) |
| dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__); |
| return 0; |
| } |
| + priv->orig_nent = num; |
| priv->nent = nent; |
| |
| for (i = 0; i < nent; i++, sg++) { |
| -- |
| 2.7.4 |
| |