Patchwork [net-next,24/34] xircom_cb: fix device probe error path.

login
register
mail settings
Submitter françois romieu
Date March 15, 2012, 1:57 p.m.
Message ID <c55334ebf0479837862671e84137f2ff3ef55279.1331814082.git.romieu@fr.zoreil.com>
Download mbox | patch
Permalink /patch/146993/
State Changes Requested
Delegated to: David Miller
Headers show

Comments

françois romieu - March 15, 2012, 1:57 p.m.
- unbalanced pci_disable_device
- PCI ressources were not released
- mismatching pci_alloc_.../kfree pairs are replaced by DMA alloc helpers.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Grant Grundler <grundler@parisc-linux.org>
---
 drivers/net/ethernet/dec/tulip/xircom_cb.c |   53 ++++++++++++++++++----------
 1 files changed, 34 insertions(+), 19 deletions(-)
Grant Grundler - April 4, 2012, 1:10 a.m.
On Thu, Mar 15, 2012 at 6:57 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
> - unbalanced pci_disable_device
> - PCI ressources were not released
> - mismatching pci_alloc_.../kfree pairs are replaced by DMA alloc helpers.
>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Grant Grundler <grundler@parisc-linux.org>

Francois,
Apologies for such a long delay to review. This looks good to me.

Acked-by: Grant Grundler <grundler@parisc-linux.org>

thanks,
grundler

> ---
>  drivers/net/ethernet/dec/tulip/xircom_cb.c |   53 ++++++++++++++++++----------
>  1 files changed, 34 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c
> index fdb329f..cbcc6d6 100644
> --- a/drivers/net/ethernet/dec/tulip/xircom_cb.c
> +++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c
> @@ -192,15 +192,18 @@ static const struct net_device_ops netdev_ops = {
>  */
>  static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
> +       struct device *d = &pdev->dev;
>        struct net_device *dev = NULL;
>        struct xircom_private *private;
>        unsigned long flags;
>        unsigned short tmp16;
> +       int rc;
>
>        /* First do the PCI initialisation */
>
> -       if (pci_enable_device(pdev))
> -               return -ENODEV;
> +       rc = pci_enable_device(pdev);
> +       if (rc < 0)
> +               goto out;
>
>        /* disable all powermanagement */
>        pci_write_config_dword(pdev, PCI_POWERMGMT, 0x0000);
> @@ -211,11 +214,13 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
>        pci_read_config_word (pdev,PCI_STATUS, &tmp16);
>        pci_write_config_word (pdev, PCI_STATUS,tmp16);
>
> -       if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {
> +       rc = pci_request_regions(pdev, "xircom_cb");
> +       if (rc < 0) {
>                pr_err("%s: failed to allocate io-region\n", __func__);
> -               return -ENODEV;
> +               goto err_disable;
>        }
>
> +       rc = -ENOMEM;
>        /*
>           Before changing the hardware, allocate the memory.
>           This way, we can fail gracefully if not enough memory
> @@ -223,17 +228,21 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
>         */
>        dev = alloc_etherdev(sizeof(struct xircom_private));
>        if (!dev)
> -               goto device_fail;
> +               goto err_release;
>
>        private = netdev_priv(dev);
>
>        /* Allocate the send/receive buffers */
> -       private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
> +       private->rx_buffer = dma_alloc_coherent(d, 8192,
> +                                               &private->rx_dma_handle,
> +                                               GFP_KERNEL);
>        if (private->rx_buffer == NULL) {
>                pr_err("%s: no memory for rx buffer\n", __func__);
>                goto rx_buf_fail;
>        }
> -       private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
> +       private->tx_buffer = dma_alloc_coherent(d, 8192,
> +                                               &private->tx_dma_handle,
> +                                               GFP_KERNEL);
>        if (private->tx_buffer == NULL) {
>                pr_err("%s: no memory for tx buffer\n", __func__);
>                goto tx_buf_fail;
> @@ -256,7 +265,8 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
>        dev->netdev_ops = &netdev_ops;
>        pci_set_drvdata(pdev, dev);
>
> -       if (register_netdev(dev)) {
> +       rc = register_netdev(dev);
> +       if (rc < 0) {
>                pr_err("%s: netdevice registration failed\n", __func__);
>                goto reg_fail;
>        }
> @@ -273,17 +283,21 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
>        spin_unlock_irqrestore(&private->lock,flags);
>
>        trigger_receive(private);
> -
> -       return 0;
> +out:
> +       return rc;
>
>  reg_fail:
> -       kfree(private->tx_buffer);
> +       pci_set_drvdata(pdev, NULL);
> +       dma_free_coherent(d, 8192, private->tx_buffer, private->tx_dma_handle);
>  tx_buf_fail:
> -       kfree(private->rx_buffer);
> +       dma_free_coherent(d, 8192, private->rx_buffer, private->rx_dma_handle);
>  rx_buf_fail:
>        free_netdev(dev);
> -device_fail:
> -       return -ENODEV;
> +err_release:
> +       pci_release_regions(pdev);
> +err_disable:
> +       pci_disable_device(pdev);
> +       goto out;
>  }
>
>
> @@ -297,14 +311,15 @@ static void __devexit xircom_remove(struct pci_dev *pdev)
>  {
>        struct net_device *dev = pci_get_drvdata(pdev);
>        struct xircom_private *card = netdev_priv(dev);
> +       struct device *d = &pdev->dev;
>
> -       pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
> -       pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
> -
> -       release_region(dev->base_addr, 128);
>        unregister_netdev(dev);
> -       free_netdev(dev);
>        pci_set_drvdata(pdev, NULL);
> +       dma_free_coherent(d, 8192, card->tx_buffer, card->tx_dma_handle);
> +       dma_free_coherent(d, 8192, card->rx_buffer, card->rx_dma_handle);
> +       free_netdev(dev);
> +       pci_release_regions(pdev);
> +       pci_disable_device(pdev);
>  }
>
>  static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
> --
> 1.7.7.6
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c
index fdb329f..cbcc6d6 100644
--- a/drivers/net/ethernet/dec/tulip/xircom_cb.c
+++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c
@@ -192,15 +192,18 @@  static const struct net_device_ops netdev_ops = {
  */
 static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+	struct device *d = &pdev->dev;
 	struct net_device *dev = NULL;
 	struct xircom_private *private;
 	unsigned long flags;
 	unsigned short tmp16;
+	int rc;
 
 	/* First do the PCI initialisation */
 
-	if (pci_enable_device(pdev))
-		return -ENODEV;
+	rc = pci_enable_device(pdev);
+	if (rc < 0)
+		goto out;
 
 	/* disable all powermanagement */
 	pci_write_config_dword(pdev, PCI_POWERMGMT, 0x0000);
@@ -211,11 +214,13 @@  static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 	pci_read_config_word (pdev,PCI_STATUS, &tmp16);
 	pci_write_config_word (pdev, PCI_STATUS,tmp16);
 
-	if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {
+	rc = pci_request_regions(pdev, "xircom_cb");
+	if (rc < 0) {
 		pr_err("%s: failed to allocate io-region\n", __func__);
-		return -ENODEV;
+		goto err_disable;
 	}
 
+	rc = -ENOMEM;
 	/*
 	   Before changing the hardware, allocate the memory.
 	   This way, we can fail gracefully if not enough memory
@@ -223,17 +228,21 @@  static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 	 */
 	dev = alloc_etherdev(sizeof(struct xircom_private));
 	if (!dev)
-		goto device_fail;
+		goto err_release;
 
 	private = netdev_priv(dev);
 
 	/* Allocate the send/receive buffers */
-	private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
+	private->rx_buffer = dma_alloc_coherent(d, 8192,
+						&private->rx_dma_handle,
+						GFP_KERNEL);
 	if (private->rx_buffer == NULL) {
 		pr_err("%s: no memory for rx buffer\n", __func__);
 		goto rx_buf_fail;
 	}
-	private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
+	private->tx_buffer = dma_alloc_coherent(d, 8192,
+						&private->tx_dma_handle,
+						GFP_KERNEL);
 	if (private->tx_buffer == NULL) {
 		pr_err("%s: no memory for tx buffer\n", __func__);
 		goto tx_buf_fail;
@@ -256,7 +265,8 @@  static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 	dev->netdev_ops = &netdev_ops;
 	pci_set_drvdata(pdev, dev);
 
-	if (register_netdev(dev)) {
+	rc = register_netdev(dev);
+	if (rc < 0) {
 		pr_err("%s: netdevice registration failed\n", __func__);
 		goto reg_fail;
 	}
@@ -273,17 +283,21 @@  static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 	spin_unlock_irqrestore(&private->lock,flags);
 
 	trigger_receive(private);
-
-	return 0;
+out:
+	return rc;
 
 reg_fail:
-	kfree(private->tx_buffer);
+	pci_set_drvdata(pdev, NULL);
+	dma_free_coherent(d, 8192, private->tx_buffer, private->tx_dma_handle);
 tx_buf_fail:
-	kfree(private->rx_buffer);
+	dma_free_coherent(d, 8192, private->rx_buffer, private->rx_dma_handle);
 rx_buf_fail:
 	free_netdev(dev);
-device_fail:
-	return -ENODEV;
+err_release:
+	pci_release_regions(pdev);
+err_disable:
+	pci_disable_device(pdev);
+	goto out;
 }
 
 
@@ -297,14 +311,15 @@  static void __devexit xircom_remove(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct xircom_private *card = netdev_priv(dev);
+	struct device *d = &pdev->dev;
 
-	pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
-	pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
-
-	release_region(dev->base_addr, 128);
 	unregister_netdev(dev);
-	free_netdev(dev);
 	pci_set_drvdata(pdev, NULL);
+	dma_free_coherent(d, 8192, card->tx_buffer, card->tx_dma_handle);
+	dma_free_coherent(d, 8192, card->rx_buffer, card->rx_dma_handle);
+	free_netdev(dev);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
 }
 
 static irqreturn_t xircom_interrupt(int irq, void *dev_instance)