From: Jon Hunter <jonathanh@nvidia.com>
To: Laxman Dewangan <ldewangan@nvidia.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Jiri Slaby <jslaby@suse.cz>
Cc: <linux-serial@vger.kernel.org>, <linux-tegra@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, Jon Hunter <jonathanh@nvidia.com>
Subject: [PATCH 8/8] serial: tegra: Correct error handling on DMA setup
Date: Tue, 5 May 2015 15:17:59 +0100 [thread overview]
Message-ID: <1430835479-6613-9-git-send-email-jonathanh@nvidia.com> (raw)
In-Reply-To: <1430835479-6613-1-git-send-email-jonathanh@nvidia.com>
Function tegra_uart_dma_channel_allocate() does not check that
dma_map_single() mapped the DMA buffer correctly. Add a check for this
and appropriate error handling.
Furthermore, if dmaengine_slave_config() (called by
tegra_uart_dma_channel_allocate()) fails, then memory allocated/mapped
is not freed/unmapped. Therefore, call tegra_uart_dma_channel_free()
instead of just dma_release_channel() if dmaengine_slave_config() fails.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
drivers/tty/serial/serial-tegra.c | 51 +++++++++++++++++++++------------------
1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
index 96378da9aefc..3b63f103f0c9 100644
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -949,6 +949,28 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)
return 0;
}
+static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup,
+ bool dma_to_memory)
+{
+ if (dma_to_memory) {
+ dmaengine_terminate_all(tup->rx_dma_chan);
+ dma_release_channel(tup->rx_dma_chan);
+ dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE,
+ tup->rx_dma_buf_virt, tup->rx_dma_buf_phys);
+ tup->rx_dma_chan = NULL;
+ tup->rx_dma_buf_phys = 0;
+ tup->rx_dma_buf_virt = NULL;
+ } else {
+ dmaengine_terminate_all(tup->tx_dma_chan);
+ dma_release_channel(tup->tx_dma_chan);
+ dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys,
+ UART_XMIT_SIZE, DMA_TO_DEVICE);
+ tup->tx_dma_chan = NULL;
+ tup->tx_dma_buf_phys = 0;
+ tup->tx_dma_buf_virt = NULL;
+ }
+}
+
static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
bool dma_to_memory)
{
@@ -981,6 +1003,11 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
dma_phys = dma_map_single(tup->uport.dev,
tup->uport.state->xmit.buf, UART_XMIT_SIZE,
DMA_TO_DEVICE);
+ if (dma_mapping_error(tup->uport.dev, dma_phys)) {
+ dev_err(tup->uport.dev, "dma_map_single tx failed\n");
+ dma_release_channel(dma_chan);
+ return -ENOMEM;
+ }
dma_buf = tup->uport.state->xmit.buf;
}
@@ -1013,32 +1040,10 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
return 0;
scrub:
- dma_release_channel(dma_chan);
+ tegra_uart_dma_channel_free(tup, dma_to_memory);
return ret;
}
-static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup,
- bool dma_to_memory)
-{
- if (dma_to_memory) {
- dmaengine_terminate_all(tup->rx_dma_chan);
- dma_release_channel(tup->rx_dma_chan);
- dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE,
- tup->rx_dma_buf_virt, tup->rx_dma_buf_phys);
- tup->rx_dma_chan = NULL;
- tup->rx_dma_buf_phys = 0;
- tup->rx_dma_buf_virt = NULL;
- } else {
- dmaengine_terminate_all(tup->tx_dma_chan);
- dma_release_channel(tup->tx_dma_chan);
- dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys,
- UART_XMIT_SIZE, DMA_TO_DEVICE);
- tup->tx_dma_chan = NULL;
- tup->tx_dma_buf_phys = 0;
- tup->tx_dma_buf_virt = NULL;
- }
-}
-
static int tegra_uart_startup(struct uart_port *u)
{
struct tegra_uart_port *tup = to_tegra_uport(u);
--
1.9.1
next prev parent reply other threads:[~2015-05-05 16:06 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-05 14:17 [PATCH 0/8] serial: tegra: various fixes Jon Hunter
2015-05-05 14:17 ` [PATCH 1/8] serial: tegra: Correct delay after TX flush Jon Hunter
2015-05-05 14:17 ` [PATCH 2/8] serial: tegra: Add delay after enabling FIFO mode Jon Hunter
2015-05-05 14:17 ` [PATCH 3/8] serial: tegra: check the count and read if any from dma Jon Hunter
2015-05-05 14:17 ` [PATCH 4/8] serial: tegra: handle race condition on uart rx side Jon Hunter
2015-05-05 14:17 ` [PATCH 5/8] serial: tegra: Use unsigned types for RX and TX byte counts Jon Hunter
2015-05-05 14:17 ` [PATCH 6/8] serial: tegra: Fix cookie used by TX channel Jon Hunter
2015-05-05 14:17 ` [PATCH 7/8] serial: tegra: Correct shutdown of UARTs Jon Hunter
2015-05-05 14:17 ` Jon Hunter [this message]
2015-05-12 8:39 ` [PATCH 8/8] serial: tegra: Correct error handling on DMA setup Alexandre Courbot
2015-05-12 9:51 ` Jon Hunter
2015-05-13 4:56 ` Alexandre Courbot
2015-05-13 8:23 ` Jon Hunter
2015-05-20 3:57 ` Alexandre Courbot
2015-05-20 9:51 ` Jon Hunter
2015-05-20 12:12 ` Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1430835479-6613-9-git-send-email-jonathanh@nvidia.com \
--to=jonathanh@nvidia.com \
--cc=gregkh@linuxfoundation.org \
--cc=jslaby@suse.cz \
--cc=ldewangan@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).