| From: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> |
| Date: Tue, 12 Dec 2017 23:06:35 +0200 |
| Subject: net: ethernet: ti: cpdma: correct error handling for chan create |
| |
| commit 8a83c5d7969b8433584e3cf658a8d76c4dc37f4d upstream. |
| |
| It's not correct to return NULL when that is actually an error and |
| function returns errors in any other wrong case. In the same time, |
| the cpsw driver and davinci emac doesn't check error case while |
| creating channel and it can miss actual error. Also remove WARNs |
| replacing them on dev_err msgs. |
| |
| Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> |
| Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.16: |
| - Channel pointers are stored in different fields |
| - Adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/net/ethernet/ti/cpsw.c | 12 +++++++++--- |
| drivers/net/ethernet/ti/davinci_cpdma.c | 2 +- |
| drivers/net/ethernet/ti/davinci_emac.c | 11 +++++++++-- |
| 3 files changed, 19 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/ethernet/ti/cpsw.c |
| +++ b/drivers/net/ethernet/ti/cpsw.c |
| @@ -2216,12 +2216,17 @@ static int cpsw_probe(struct platform_de |
| |
| priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), |
| cpsw_tx_handler); |
| + if (IS_ERR(priv->txch)) { |
| + dev_err(priv->dev, "error initializing tx dma channel\n"); |
| + ret = PTR_ERR(priv->txch); |
| + goto clean_dma_ret; |
| + } |
| + |
| priv->rxch = cpdma_chan_create(priv->dma, rx_chan_num(0), |
| cpsw_rx_handler); |
| - |
| - if (WARN_ON(!priv->txch || !priv->rxch)) { |
| - dev_err(priv->dev, "error initializing dma channels\n"); |
| - ret = -ENOMEM; |
| + if (IS_ERR(priv->rxch)) { |
| + dev_err(priv->dev, "error initializing rx dma channel\n"); |
| + ret = PTR_ERR(priv->rxch); |
| goto clean_dma_ret; |
| } |
| |
| --- a/drivers/net/ethernet/ti/davinci_cpdma.c |
| +++ b/drivers/net/ethernet/ti/davinci_cpdma.c |
| @@ -503,7 +503,7 @@ struct cpdma_chan *cpdma_chan_create(str |
| unsigned long flags; |
| |
| if (__chan_linear(chan_num) >= ctlr->num_chan) |
| - return NULL; |
| + return ERR_PTR(-EINVAL); |
| |
| chan = devm_kzalloc(ctlr->dev, sizeof(*chan), GFP_KERNEL); |
| if (!chan) |
| --- a/drivers/net/ethernet/ti/davinci_emac.c |
| +++ b/drivers/net/ethernet/ti/davinci_emac.c |
| @@ -1951,10 +1951,17 @@ static int davinci_emac_probe(struct pla |
| |
| priv->txchan = cpdma_chan_create(priv->dma, tx_chan_num(EMAC_DEF_TX_CH), |
| emac_tx_handler); |
| + if (IS_ERR(priv->txchan)) { |
| + dev_err(&pdev->dev, "error initializing tx dma channel\n"); |
| + rc = PTR_ERR(priv->txchan); |
| + goto no_cpdma_chan; |
| + } |
| + |
| priv->rxchan = cpdma_chan_create(priv->dma, rx_chan_num(EMAC_DEF_RX_CH), |
| emac_rx_handler); |
| - if (WARN_ON(!priv->txchan || !priv->rxchan)) { |
| - rc = -ENOMEM; |
| + if (IS_ERR(priv->rxchan)) { |
| + dev_err(&pdev->dev, "error initializing rx dma channel\n"); |
| + rc = PTR_ERR(priv->rxchan); |
| goto no_cpdma_chan; |
| } |
| |