aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/stmmac/stmmac_main.c
diff options
context:
space:
mode:
authorDan Carpenter <error27@gmail.com>2010-12-20 16:34:56 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-21 13:53:19 -0500
commit34a52f363ab6bcf6d50a65c153dec03f3fb32653 (patch)
tree62a84a17730b64c692ac788354cb1ae6913087b3 /drivers/net/stmmac/stmmac_main.c
parent4b97f8e10893e2c8f64a2795901bdb447a3308f4 (diff)
stmmac: unwind properly in stmmac_dvr_probe()
The original code had a several problems: *) It had potential null dereferences of "priv" and "res". *) It released the memory region before it was aquired. *) It didn't free "ndev" after it was allocated. *) It didn't call unregister_netdev() after calling stmmac_probe(). Signed-off-by: Dan Carpenter <error27@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/stmmac/stmmac_main.c')
-rw-r--r--drivers/net/stmmac/stmmac_main.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 20f803df868..34a0af3837f 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -1647,10 +1647,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1647 1647
1648 pr_info("STMMAC driver:\n\tplatform registration... "); 1648 pr_info("STMMAC driver:\n\tplatform registration... ");
1649 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1649 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1650 if (!res) { 1650 if (!res)
1651 ret = -ENODEV; 1651 return -ENODEV;
1652 goto out;
1653 }
1654 pr_info("\tdone!\n"); 1652 pr_info("\tdone!\n");
1655 1653
1656 if (!request_mem_region(res->start, resource_size(res), 1654 if (!request_mem_region(res->start, resource_size(res),
@@ -1658,22 +1656,21 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1658 pr_err("%s: ERROR: memory allocation failed" 1656 pr_err("%s: ERROR: memory allocation failed"
1659 "cannot get the I/O addr 0x%x\n", 1657 "cannot get the I/O addr 0x%x\n",
1660 __func__, (unsigned int)res->start); 1658 __func__, (unsigned int)res->start);
1661 ret = -EBUSY; 1659 return -EBUSY;
1662 goto out;
1663 } 1660 }
1664 1661
1665 addr = ioremap(res->start, resource_size(res)); 1662 addr = ioremap(res->start, resource_size(res));
1666 if (!addr) { 1663 if (!addr) {
1667 pr_err("%s: ERROR: memory mapping failed\n", __func__); 1664 pr_err("%s: ERROR: memory mapping failed\n", __func__);
1668 ret = -ENOMEM; 1665 ret = -ENOMEM;
1669 goto out; 1666 goto out_release_region;
1670 } 1667 }
1671 1668
1672 ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 1669 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1673 if (!ndev) { 1670 if (!ndev) {
1674 pr_err("%s: ERROR: allocating the device\n", __func__); 1671 pr_err("%s: ERROR: allocating the device\n", __func__);
1675 ret = -ENOMEM; 1672 ret = -ENOMEM;
1676 goto out; 1673 goto out_unmap;
1677 } 1674 }
1678 1675
1679 SET_NETDEV_DEV(ndev, &pdev->dev); 1676 SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -1683,8 +1680,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1683 if (ndev->irq == -ENXIO) { 1680 if (ndev->irq == -ENXIO) {
1684 pr_err("%s: ERROR: MAC IRQ configuration " 1681 pr_err("%s: ERROR: MAC IRQ configuration "
1685 "information not found\n", __func__); 1682 "information not found\n", __func__);
1686 ret = -ENODEV; 1683 ret = -ENXIO;
1687 goto out; 1684 goto out_free_ndev;
1688 } 1685 }
1689 1686
1690 priv = netdev_priv(ndev); 1687 priv = netdev_priv(ndev);
@@ -1711,18 +1708,18 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1711 if (priv->plat->init) { 1708 if (priv->plat->init) {
1712 ret = priv->plat->init(pdev); 1709 ret = priv->plat->init(pdev);
1713 if (unlikely(ret)) 1710 if (unlikely(ret))
1714 goto out; 1711 goto out_free_ndev;
1715 } 1712 }
1716 1713
1717 /* MAC HW revice detection */ 1714 /* MAC HW revice detection */
1718 ret = stmmac_mac_device_setup(ndev); 1715 ret = stmmac_mac_device_setup(ndev);
1719 if (ret < 0) 1716 if (ret < 0)
1720 goto out; 1717 goto out_plat_exit;
1721 1718
1722 /* Network Device Registration */ 1719 /* Network Device Registration */
1723 ret = stmmac_probe(ndev); 1720 ret = stmmac_probe(ndev);
1724 if (ret < 0) 1721 if (ret < 0)
1725 goto out; 1722 goto out_plat_exit;
1726 1723
1727 /* associate a PHY - it is provided by another platform bus */ 1724 /* associate a PHY - it is provided by another platform bus */
1728 if (!driver_for_each_device 1725 if (!driver_for_each_device
@@ -1730,7 +1727,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1730 stmmac_associate_phy)) { 1727 stmmac_associate_phy)) {
1731 pr_err("No PHY device is associated with this MAC!\n"); 1728 pr_err("No PHY device is associated with this MAC!\n");
1732 ret = -ENODEV; 1729 ret = -ENODEV;
1733 goto out; 1730 goto out_unregister;
1734 } 1731 }
1735 1732
1736 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" 1733 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
@@ -1741,19 +1738,22 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1741 pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id); 1738 pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
1742 ret = stmmac_mdio_register(ndev); 1739 ret = stmmac_mdio_register(ndev);
1743 if (ret < 0) 1740 if (ret < 0)
1744 goto out; 1741 goto out_unregister;
1745 pr_debug("registered!\n"); 1742 pr_debug("registered!\n");
1743 return 0;
1746 1744
1747out: 1745out_unregister:
1748 if (ret < 0) { 1746 unregister_netdev(ndev);
1749 if (priv->plat->exit) 1747out_plat_exit:
1750 priv->plat->exit(pdev); 1748 if (priv->plat->exit)
1751 1749 priv->plat->exit(pdev);
1752 platform_set_drvdata(pdev, NULL); 1750out_free_ndev:
1753 release_mem_region(res->start, resource_size(res)); 1751 free_netdev(ndev);
1754 if (addr != NULL) 1752 platform_set_drvdata(pdev, NULL);
1755 iounmap(addr); 1753out_unmap:
1756 } 1754 iounmap(addr);
1755out_release_region:
1756 release_mem_region(res->start, resource_size(res));
1757 1757
1758 return ret; 1758 return ret;
1759} 1759}