aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2008-12-18 03:23:29 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-19 01:50:50 -0500
commit67c2fb8ff0eda3cee95954a1dd245c3ce1a10486 (patch)
treee25dc49e42338225f25bb999aff0bebae8cb78a9 /drivers/net/ucc_geth.c
parent1762a29ae5ebdd974eb2ba0c36b56ab6f7a9c16d (diff)
ucc_geth: Fix IRQ freeing code in ucc_geth_open()
open() routine calls stop() in case of errors, the function will try to free the requested IRQ. But we don't know if it was actually requested, so the code might issue bogus free_irq(0, dev) call. Fix this by rearranging the code so that now request_irq() is the last call in the open() routine, and move free_irq() into the close(). Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 6ebefe951b95..3d1966c34d29 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2300,8 +2300,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2300 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); 2300 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
2301 out_be32(&ug_regs->maccfg1, tempval); 2301 out_be32(&ug_regs->maccfg1, tempval);
2302 2302
2303 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
2304
2305 ucc_geth_memclean(ugeth); 2303 ucc_geth_memclean(ugeth);
2306} 2304}
2307 2305
@@ -3759,21 +3757,20 @@ static int ucc_geth_open(struct net_device *dev)
3759 3757
3760 phy_start(ugeth->phydev); 3758 phy_start(ugeth->phydev);
3761 3759
3762 err = 3760 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
3763 request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
3764 "UCC Geth", dev);
3765 if (err) { 3761 if (err) {
3766 if (netif_msg_ifup(ugeth)) 3762 if (netif_msg_ifup(ugeth))
3767 ugeth_err("%s: Cannot get IRQ for net device, aborting.", 3763 ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
3768 dev->name);
3769 ucc_geth_stop(ugeth); 3764 ucc_geth_stop(ugeth);
3770 goto out_err; 3765 goto out_err;
3771 } 3766 }
3772 3767
3773 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); 3768 err = request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler,
3769 0, "UCC Geth", dev);
3774 if (err) { 3770 if (err) {
3775 if (netif_msg_ifup(ugeth)) 3771 if (netif_msg_ifup(ugeth))
3776 ugeth_err("%s: Cannot enable net device, aborting.", dev->name); 3772 ugeth_err("%s: Cannot get IRQ for net device, aborting.",
3773 dev->name);
3777 ucc_geth_stop(ugeth); 3774 ucc_geth_stop(ugeth);
3778 goto out_err; 3775 goto out_err;
3779 } 3776 }
@@ -3799,6 +3796,8 @@ static int ucc_geth_close(struct net_device *dev)
3799 3796
3800 ucc_geth_stop(ugeth); 3797 ucc_geth_stop(ugeth);
3801 3798
3799 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
3800
3802 phy_disconnect(ugeth->phydev); 3801 phy_disconnect(ugeth->phydev);
3803 ugeth->phydev = NULL; 3802 ugeth->phydev = NULL;
3804 3803