mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-29 04:09:39 +00:00
dmaengine: ti: k3-udma-glue: Fix an error handling path in 'k3_udma_glue_cfg_rx_flow()'
All but one error handling paths in the 'k3_udma_glue_cfg_rx_flow()'
function 'goto err' and call 'k3_udma_glue_release_rx_flow()'.
This not correct because this function has a 'channel->flows_ready--;' at
the end, but 'flows_ready' has not been incremented here, when we branch to
the error handling path.
In order to keep a correct value in 'flows_ready', un-roll
'k3_udma_glue_release_rx_flow()', simplify it, add some labels and branch
at the correct places when an error is detected.
Doing so, we also NULLify 'flow->udma_rflow' in a path that was lacking it.
Fixes: d702419134
("dmaengine: ti: k3-udma: Add glue layer for non DMAengine user")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Link: https://lore.kernel.org/r/20200318191209.1267-1-christophe.jaillet@wanadoo.fr
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
01c4df39a2
commit
018af9be3d
1 changed files with 19 additions and 10 deletions
|
@ -564,12 +564,12 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
|
|||
if (IS_ERR(flow->udma_rflow)) {
|
||||
ret = PTR_ERR(flow->udma_rflow);
|
||||
dev_err(dev, "UDMAX rflow get err %d\n", ret);
|
||||
goto err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) {
|
||||
xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto err_rflow_put;
|
||||
}
|
||||
|
||||
/* request and cfg rings */
|
||||
|
@ -578,7 +578,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
|
|||
if (!flow->ringrx) {
|
||||
ret = -ENODEV;
|
||||
dev_err(dev, "Failed to get RX ring\n");
|
||||
goto err;
|
||||
goto err_rflow_put;
|
||||
}
|
||||
|
||||
flow->ringrxfdq = k3_ringacc_request_ring(rx_chn->common.ringacc,
|
||||
|
@ -586,19 +586,19 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
|
|||
if (!flow->ringrxfdq) {
|
||||
ret = -ENODEV;
|
||||
dev_err(dev, "Failed to get RXFDQ ring\n");
|
||||
goto err;
|
||||
goto err_ringrx_free;
|
||||
}
|
||||
|
||||
ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to cfg ringrx %d\n", ret);
|
||||
goto err;
|
||||
goto err_ringrxfdq_free;
|
||||
}
|
||||
|
||||
ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret);
|
||||
goto err;
|
||||
goto err_ringrxfdq_free;
|
||||
}
|
||||
|
||||
if (rx_chn->remote) {
|
||||
|
@ -648,7 +648,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
|
|||
if (ret) {
|
||||
dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id,
|
||||
ret);
|
||||
goto err;
|
||||
goto err_ringrxfdq_free;
|
||||
}
|
||||
|
||||
rx_chn->flows_ready++;
|
||||
|
@ -656,8 +656,17 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn,
|
|||
flow->udma_rflow_id, rx_chn->flows_ready);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
k3_udma_glue_release_rx_flow(rx_chn, flow_idx);
|
||||
|
||||
err_ringrxfdq_free:
|
||||
k3_ringacc_ring_free(flow->ringrxfdq);
|
||||
|
||||
err_ringrx_free:
|
||||
k3_ringacc_ring_free(flow->ringrx);
|
||||
|
||||
err_rflow_put:
|
||||
xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow);
|
||||
flow->udma_rflow = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue