aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-10-31 07:59:37 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-10-31 07:59:37 -0500
commita15e0384dd22ee08f56d62761ce9d770488f6f4e (patch)
tree28c9fb9ad86295ca87f9bc6df6042727ddaf68c9 /drivers
parente2f2e58e7968f8446b1078a20a18bf8ea12b4fbc (diff)
[netdrvr 8139too] replace hand-crafted kernel thread with workqueue
Gone are the days when 8139too was a shining example of how to use kernel threads. Delayed workqueues are easier, and map precisely to our task: running code from a kernel thread, after a periodic sleep.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/8139too.c87
1 files changed, 33 insertions, 54 deletions
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 30bee11c48bd..9de58e249bc3 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -590,12 +590,12 @@ struct rtl8139_private {
590 spinlock_t lock; 590 spinlock_t lock;
591 spinlock_t rx_lock; 591 spinlock_t rx_lock;
592 chip_t chipset; 592 chip_t chipset;
593 pid_t thr_pid;
594 wait_queue_head_t thr_wait;
595 struct completion thr_exited;
596 u32 rx_config; 593 u32 rx_config;
597 struct rtl_extra_stats xstats; 594 struct rtl_extra_stats xstats;
598 int time_to_die; 595
596 struct work_struct thread;
597 long time_to_die; /* -1 no thr, 0 thr active, 1 thr cancel */
598
599 struct mii_if_info mii; 599 struct mii_if_info mii;
600 unsigned int regs_len; 600 unsigned int regs_len;
601 unsigned long fifo_copy_timeout; 601 unsigned long fifo_copy_timeout;
@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev);
620static int mdio_read (struct net_device *dev, int phy_id, int location); 620static int mdio_read (struct net_device *dev, int phy_id, int location);
621static void mdio_write (struct net_device *dev, int phy_id, int location, 621static void mdio_write (struct net_device *dev, int phy_id, int location,
622 int val); 622 int val);
623static void rtl8139_start_thread(struct net_device *dev); 623static void rtl8139_start_thread(struct rtl8139_private *tp);
624static void rtl8139_tx_timeout (struct net_device *dev); 624static void rtl8139_tx_timeout (struct net_device *dev);
625static void rtl8139_init_ring (struct net_device *dev); 625static void rtl8139_init_ring (struct net_device *dev);
626static int rtl8139_start_xmit (struct sk_buff *skb, 626static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -637,6 +637,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
637static void rtl8139_set_rx_mode (struct net_device *dev); 637static void rtl8139_set_rx_mode (struct net_device *dev);
638static void __set_rx_mode (struct net_device *dev); 638static void __set_rx_mode (struct net_device *dev);
639static void rtl8139_hw_start (struct net_device *dev); 639static void rtl8139_hw_start (struct net_device *dev);
640static void rtl8139_thread (void *_data);
640static struct ethtool_ops rtl8139_ethtool_ops; 641static struct ethtool_ops rtl8139_ethtool_ops;
641 642
642/* write MMIO register, with flush */ 643/* write MMIO register, with flush */
@@ -1007,8 +1008,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
1007 (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); 1008 (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
1008 spin_lock_init (&tp->lock); 1009 spin_lock_init (&tp->lock);
1009 spin_lock_init (&tp->rx_lock); 1010 spin_lock_init (&tp->rx_lock);
1010 init_waitqueue_head (&tp->thr_wait); 1011 INIT_WORK(&tp->thread, rtl8139_thread, dev);
1011 init_completion (&tp->thr_exited);
1012 tp->mii.dev = dev; 1012 tp->mii.dev = dev;
1013 tp->mii.mdio_read = mdio_read; 1013 tp->mii.mdio_read = mdio_read;
1014 tp->mii.mdio_write = mdio_write; 1014 tp->mii.mdio_write = mdio_write;
@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev)
1345 dev->irq, RTL_R8 (MediaStatus), 1345 dev->irq, RTL_R8 (MediaStatus),
1346 tp->mii.full_duplex ? "full" : "half"); 1346 tp->mii.full_duplex ? "full" : "half");
1347 1347
1348 rtl8139_start_thread(dev); 1348 rtl8139_start_thread(tp);
1349 1349
1350 return 0; 1350 return 0;
1351} 1351}
@@ -1594,56 +1594,45 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
1594 RTL_R8 (Config1)); 1594 RTL_R8 (Config1));
1595} 1595}
1596 1596
1597static int rtl8139_thread (void *data) 1597static void rtl8139_thread (void *_data)
1598{ 1598{
1599 struct net_device *dev = data; 1599 struct net_device *dev = _data;
1600 struct rtl8139_private *tp = netdev_priv(dev); 1600 struct rtl8139_private *tp = netdev_priv(dev);
1601 unsigned long timeout;
1602
1603 daemonize("%s", dev->name);
1604 allow_signal(SIGTERM);
1605
1606 while (1) {
1607 timeout = next_tick;
1608 do {
1609 timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
1610 /* make swsusp happy with our thread */
1611 try_to_freeze();
1612 } while (!signal_pending (current) && (timeout > 0));
1613 1601
1614 if (signal_pending (current)) { 1602 if ((tp->time_to_die == 0) &&
1615 flush_signals(current); 1603 (rtnl_lock_interruptible() == 0)) {
1616 }
1617
1618 if (tp->time_to_die)
1619 break;
1620
1621 if (rtnl_lock_interruptible ())
1622 break;
1623 rtl8139_thread_iter (dev, tp, tp->mmio_addr); 1604 rtl8139_thread_iter (dev, tp, tp->mmio_addr);
1624 rtnl_unlock (); 1605 rtnl_unlock ();
1625 } 1606 }
1626 1607
1627 complete_and_exit (&tp->thr_exited, 0); 1608 if (tp->time_to_die == 0)
1609 schedule_delayed_work(&tp->thread, next_tick);
1628} 1610}
1629 1611
1630static void rtl8139_start_thread(struct net_device *dev) 1612static void rtl8139_start_thread(struct rtl8139_private *tp)
1631{ 1613{
1632 struct rtl8139_private *tp = netdev_priv(dev);
1633
1634 tp->thr_pid = -1;
1635 tp->twistie = 0; 1614 tp->twistie = 0;
1636 tp->time_to_die = 0; 1615 tp->time_to_die = -1;
1637 if (tp->chipset == CH_8139_K) 1616 if (tp->chipset == CH_8139_K)
1638 tp->twistie = 1; 1617 tp->twistie = 1;
1639 else if (tp->drv_flags & HAS_LNK_CHNG) 1618 else if (tp->drv_flags & HAS_LNK_CHNG)
1640 return; 1619 return;
1641 1620
1642 tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES); 1621 tp->time_to_die = 0;
1643 if (tp->thr_pid < 0) { 1622
1644 printk (KERN_WARNING "%s: unable to start kernel thread\n", 1623 schedule_delayed_work(&tp->thread, next_tick);
1645 dev->name); 1624}
1646 } 1625
1626static void rtl8139_stop_thread(struct rtl8139_private *tp)
1627{
1628 if (tp->time_to_die < 0)
1629 return;
1630
1631 tp->time_to_die = 1;
1632 wmb();
1633
1634 if (cancel_delayed_work(&tp->thread) == 0)
1635 flush_scheduled_work();
1647} 1636}
1648 1637
1649static inline void rtl8139_tx_clear (struct rtl8139_private *tp) 1638static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
@@ -2224,22 +2213,12 @@ static int rtl8139_close (struct net_device *dev)
2224{ 2213{
2225 struct rtl8139_private *tp = netdev_priv(dev); 2214 struct rtl8139_private *tp = netdev_priv(dev);
2226 void __iomem *ioaddr = tp->mmio_addr; 2215 void __iomem *ioaddr = tp->mmio_addr;
2227 int ret = 0;
2228 unsigned long flags; 2216 unsigned long flags;
2229 2217
2230 netif_stop_queue (dev); 2218 netif_stop_queue (dev);
2231 2219
2232 if (tp->thr_pid >= 0) { 2220 rtl8139_stop_thread(tp);
2233 tp->time_to_die = 1; 2221
2234 wmb();
2235 ret = kill_proc (tp->thr_pid, SIGTERM, 1);
2236 if (ret) {
2237 printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
2238 return ret;
2239 }
2240 wait_for_completion (&tp->thr_exited);
2241 }
2242
2243 if (netif_msg_ifdown(tp)) 2222 if (netif_msg_ifdown(tp))
2244 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", 2223 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
2245 dev->name, RTL_R16 (IntrStatus)); 2224 dev->name, RTL_R16 (IntrStatus));