diff options
Diffstat (limited to 'drivers/net/smc911x.c')
-rw-r--r-- | drivers/net/smc911x.c | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index fc605f276c00..c5871624f972 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -898,11 +898,11 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
898 | * We should not be called if phy_type is zero. | 898 | * We should not be called if phy_type is zero. |
899 | */ | 899 | */ |
900 | if (lp->phy_type == 0) | 900 | if (lp->phy_type == 0) |
901 | goto smc911x_phy_configure_exit_nolock; | 901 | return; |
902 | 902 | ||
903 | if (smc911x_phy_reset(dev, phyaddr)) { | 903 | if (smc911x_phy_reset(dev, phyaddr)) { |
904 | printk("%s: PHY reset timed out\n", dev->name); | 904 | printk("%s: PHY reset timed out\n", dev->name); |
905 | goto smc911x_phy_configure_exit_nolock; | 905 | return; |
906 | } | 906 | } |
907 | spin_lock_irqsave(&lp->lock, flags); | 907 | spin_lock_irqsave(&lp->lock, flags); |
908 | 908 | ||
@@ -971,8 +971,6 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
971 | 971 | ||
972 | smc911x_phy_configure_exit: | 972 | smc911x_phy_configure_exit: |
973 | spin_unlock_irqrestore(&lp->lock, flags); | 973 | spin_unlock_irqrestore(&lp->lock, flags); |
974 | smc911x_phy_configure_exit_nolock: | ||
975 | lp->work_pending = 0; | ||
976 | } | 974 | } |
977 | 975 | ||
978 | /* | 976 | /* |
@@ -1291,11 +1289,8 @@ static void smc911x_timeout(struct net_device *dev) | |||
1291 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() | 1289 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() |
1292 | * which calls schedule(). Hence we use a work queue. | 1290 | * which calls schedule(). Hence we use a work queue. |
1293 | */ | 1291 | */ |
1294 | if (lp->phy_type != 0) { | 1292 | if (lp->phy_type != 0) |
1295 | if (schedule_work(&lp->phy_configure)) { | 1293 | schedule_work(&lp->phy_configure); |
1296 | lp->work_pending = 1; | ||
1297 | } | ||
1298 | } | ||
1299 | 1294 | ||
1300 | /* We can accept TX packets again */ | 1295 | /* We can accept TX packets again */ |
1301 | dev->trans_start = jiffies; | 1296 | dev->trans_start = jiffies; |
@@ -1465,16 +1460,8 @@ static int smc911x_close(struct net_device *dev) | |||
1465 | if (lp->phy_type != 0) { | 1460 | if (lp->phy_type != 0) { |
1466 | /* We need to ensure that no calls to | 1461 | /* We need to ensure that no calls to |
1467 | * smc911x_phy_configure are pending. | 1462 | * smc911x_phy_configure are pending. |
1468 | |||
1469 | * flush_scheduled_work() cannot be called because we | ||
1470 | * are running with the netlink semaphore held (from | ||
1471 | * devinet_ioctl()) and the pending work queue | ||
1472 | * contains linkwatch_event() (scheduled by | ||
1473 | * netif_carrier_off() above). linkwatch_event() also | ||
1474 | * wants the netlink semaphore. | ||
1475 | */ | 1463 | */ |
1476 | while (lp->work_pending) | 1464 | cancel_work_sync(&lp->phy_configure); |
1477 | schedule(); | ||
1478 | smc911x_phy_powerdown(dev, lp->mii.phy_id); | 1465 | smc911x_phy_powerdown(dev, lp->mii.phy_id); |
1479 | } | 1466 | } |
1480 | 1467 | ||