From 93ec2c723e3f8a216dde2899aeb85c648672bc6b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 26 Oct 2006 15:46:50 -0700 Subject: netpoll info leak After looking harder, Steve noticed that the netpoll beast leaked a little every time it shutdown for a nap. Not a big leak, but a nuisance kind of thing. He took out his refcount duct tape and patched the leak. It was overkill since there was already other locking in that area, but it looked clean and wouldn't attract fleas. Signed-off-by: Stephen Hemminger --- include/linux/netpoll.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/netpoll.h') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 1efe60c5c00c..39845fc975f9 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -25,6 +25,7 @@ struct netpoll { }; struct netpoll_info { + atomic_t refcnt; spinlock_t poll_lock; int poll_owner; int tries; -- cgit v1.2.3 From b6cd27ed33886a5ffaf0925a6d98e13e18e8a1af Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 26 Oct 2006 15:46:51 -0700 Subject: netpoll per device txq When the netpoll beast got really busy, it tended to clog things, so it stored them for later. But the beast was putting all it's skb's in one basket. This was bad because maybe some pipes were clogged and others were not. Signed-off-by: Stephen Hemminger --- include/linux/netpoll.h | 2 ++ net/core/netpoll.c | 50 +++++++++++++++---------------------------------- 2 files changed, 17 insertions(+), 35 deletions(-) (limited to 'include/linux/netpoll.h') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 39845fc975f9..93a8b7664423 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -33,6 +33,8 @@ struct netpoll_info { spinlock_t rx_lock; struct netpoll *rx_np; /* netpoll that registered an rx_hook */ struct sk_buff_head arp_tx; /* list of arp requests to reply to */ + struct sk_buff_head txq; + struct work_struct tx_work; }; void netpoll_poll(struct netpoll *np); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index c66df2f45d26..ac4e8b8f57d1 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -38,10 +38,6 @@ static struct sk_buff_head skb_pool; -static DEFINE_SPINLOCK(queue_lock); -static int queue_depth; -static struct sk_buff *queue_head, *queue_tail; - static atomic_t trapped; #define NETPOLL_RX_ENABLED 1 @@ -56,46 +52,25 @@ static void arp_reply(struct sk_buff *skb); static void queue_process(void *p) { - unsigned long flags; + struct netpoll_info *npinfo = p; struct sk_buff *skb; - while (queue_head) { - spin_lock_irqsave(&queue_lock, flags); - - skb = queue_head; - queue_head = skb->next; - if (skb == queue_tail) - queue_head = NULL; - - queue_depth--; - - spin_unlock_irqrestore(&queue_lock, flags); - + while ((skb = skb_dequeue(&npinfo->txq))) dev_queue_xmit(skb); - } -} -static DECLARE_WORK(send_queue, queue_process, NULL); +} void netpoll_queue(struct sk_buff *skb) { - unsigned long flags; + struct net_device *dev = skb->dev; + struct netpoll_info *npinfo = dev->npinfo; - if (queue_depth == MAX_QUEUE_DEPTH) { - __kfree_skb(skb); - return; + if (!npinfo) + kfree_skb(skb); + else { + skb_queue_tail(&npinfo->txq, skb); + schedule_work(&npinfo->tx_work); } - - spin_lock_irqsave(&queue_lock, flags); - if (!queue_head) - queue_head = skb; - else - queue_tail->next = skb; - queue_tail = skb; - queue_depth++; - spin_unlock_irqrestore(&queue_lock, flags); - - schedule_work(&send_queue); } static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, @@ -658,6 +633,9 @@ int netpoll_setup(struct netpoll *np) npinfo->tries = MAX_RETRIES; spin_lock_init(&npinfo->rx_lock); skb_queue_head_init(&npinfo->arp_tx); + skb_queue_head_init(&npinfo->txq); + INIT_WORK(&npinfo->tx_work, queue_process, npinfo); + atomic_set(&npinfo->refcnt, 1); } else { npinfo = ndev->npinfo; @@ -780,6 +758,8 @@ void netpoll_cleanup(struct netpoll *np) np->dev->npinfo = NULL; if (atomic_dec_and_test(&npinfo->refcnt)) { skb_queue_purge(&npinfo->arp_tx); + skb_queue_purge(&npinfo->txq); + flush_scheduled_work(); kfree(npinfo); } -- cgit v1.2.3 From 2bdfe0baeca0e2750037b8fba71905c00ac3c515 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 26 Oct 2006 15:46:54 -0700 Subject: netpoll retry cleanup The netpoll beast was still not happy. If the beast got clogged pipes, it tended to stare blankly off in space for a long time. The problem couldn't be completely fixed because the beast talked with irq's disabled. But it could be made less painful and shorter. Signed-off-by: Stephen Hemminger --- include/linux/netpoll.h | 1 - net/core/netpoll.c | 71 +++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 39 deletions(-) (limited to 'include/linux/netpoll.h') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 93a8b7664423..c65d12ec7bb0 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -28,7 +28,6 @@ struct netpoll_info { atomic_t refcnt; spinlock_t poll_lock; int poll_owner; - int tries; int rx_flags; spinlock_t rx_lock; struct netpoll *rx_np; /* netpoll that registered an rx_hook */ diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 93cb828f3aaf..6b34c394672f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -34,12 +34,12 @@ #define MAX_UDP_CHUNK 1460 #define MAX_SKBS 32 #define MAX_QUEUE_DEPTH (MAX_SKBS / 2) -#define MAX_RETRIES 20000 static struct sk_buff_head skb_pool; static atomic_t trapped; +#define USEC_PER_POLL 50 #define NETPOLL_RX_ENABLED 1 #define NETPOLL_RX_DROP 2 @@ -72,6 +72,7 @@ static void queue_process(void *p) schedule_delayed_work(&npinfo->tx_work, HZ/10); return; } + netif_tx_unlock_bh(dev); } } @@ -244,50 +245,44 @@ repeat: static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) { - int status; - struct netpoll_info *npinfo; + int status = NETDEV_TX_BUSY; + unsigned long tries; + struct net_device *dev = np->dev; + struct netpoll_info *npinfo = np->dev->npinfo; + + if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { + __kfree_skb(skb); + return; + } + + /* don't get messages out of order, and no recursion */ + if ( !(np->drop == netpoll_queue && skb_queue_len(&npinfo->txq)) + && npinfo->poll_owner != smp_processor_id() + && netif_tx_trylock(dev)) { + + /* try until next clock tick */ + for(tries = jiffies_to_usecs(1)/USEC_PER_POLL; tries > 0; --tries) { + if (!netif_queue_stopped(dev)) + status = dev->hard_start_xmit(skb, dev); + + if (status == NETDEV_TX_OK) + break; - if (!np || !np->dev || !netif_running(np->dev)) { - __kfree_skb(skb); - return; - } + /* tickle device maybe there is some cleanup */ + netpoll_poll(np); - npinfo = np->dev->npinfo; + udelay(USEC_PER_POLL); + } + netif_tx_unlock(dev); + } - /* avoid recursion */ - if (npinfo->poll_owner == smp_processor_id() || - np->dev->xmit_lock_owner == smp_processor_id()) { + if (status != NETDEV_TX_OK) { + /* requeue for later */ if (np->drop) np->drop(skb); else __kfree_skb(skb); - return; } - - do { - npinfo->tries--; - netif_tx_lock(np->dev); - - /* - * network drivers do not expect to be called if the queue is - * stopped. - */ - status = NETDEV_TX_BUSY; - if (!netif_queue_stopped(np->dev)) - status = np->dev->hard_start_xmit(skb, np->dev); - - netif_tx_unlock(np->dev); - - /* success */ - if(!status) { - npinfo->tries = MAX_RETRIES; /* reset */ - return; - } - - /* transmit busy */ - netpoll_poll(np); - udelay(50); - } while (npinfo->tries > 0); } void netpoll_send_udp(struct netpoll *np, const char *msg, int len) @@ -649,7 +644,7 @@ int netpoll_setup(struct netpoll *np) npinfo->rx_np = NULL; spin_lock_init(&npinfo->poll_lock); npinfo->poll_owner = -1; - npinfo->tries = MAX_RETRIES; + spin_lock_init(&npinfo->rx_lock); skb_queue_head_init(&npinfo->arp_tx); skb_queue_head_init(&npinfo->txq); -- cgit v1.2.3 From 5de4a473bda49554e4e9bd93b78f43c49a7ea69c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 26 Oct 2006 15:46:55 -0700 Subject: netpoll queue cleanup The beast had a long and not very happy history. At one point, a friend (netdump) had asked that he open up a little. Well, the friend was long gone now, and the beast had this dangling piece hanging (netpoll_queue). It wasn't hard to stitch the netpoll_queue back in where it belonged and make everything tidy. Signed-off-by: Stephen Hemminger --- drivers/net/netconsole.c | 1 - include/linux/netpoll.h | 4 ++-- net/core/netpoll.c | 23 +++-------------------- 3 files changed, 5 insertions(+), 23 deletions(-) (limited to 'include/linux/netpoll.h') diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index e6e8a9797b6d..69233f6aa05c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -60,7 +60,6 @@ static struct netpoll np = { .local_port = 6665, .remote_port = 6666, .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - .drop = netpoll_queue, }; static int configured = 0; diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index c65d12ec7bb0..b7eb008c43de 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -18,7 +18,7 @@ struct netpoll { struct net_device *dev; char dev_name[16], *name; void (*rx_hook)(struct netpoll *, int, char *, int); - void (*drop)(struct sk_buff *skb); + u32 local_ip, remote_ip; u16 local_port, remote_port; unsigned char local_mac[6], remote_mac[6]; @@ -44,7 +44,7 @@ int netpoll_trap(void); void netpoll_set_trap(int trap); void netpoll_cleanup(struct netpoll *np); int __netpoll_rx(struct sk_buff *skb); -void netpoll_queue(struct sk_buff *skb); + #ifdef CONFIG_NETPOLL static inline int netpoll_rx(struct sk_buff *skb) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 6b34c394672f..0d1de3c47a01 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -77,19 +77,6 @@ static void queue_process(void *p) } } -void netpoll_queue(struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - struct netpoll_info *npinfo = dev->npinfo; - - if (!npinfo) - kfree_skb(skb); - else { - skb_queue_tail(&npinfo->txq, skb); - schedule_work(&npinfo->tx_work); - } -} - static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, unsigned short ulen, u32 saddr, u32 daddr) { @@ -256,7 +243,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) } /* don't get messages out of order, and no recursion */ - if ( !(np->drop == netpoll_queue && skb_queue_len(&npinfo->txq)) + if ( skb_queue_len(&npinfo->txq) == 0 && npinfo->poll_owner != smp_processor_id() && netif_tx_trylock(dev)) { @@ -277,11 +264,8 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) } if (status != NETDEV_TX_OK) { - /* requeue for later */ - if (np->drop) - np->drop(skb); - else - __kfree_skb(skb); + skb_queue_tail(&npinfo->txq, skb); + schedule_work(&npinfo->tx_work); } } @@ -809,4 +793,3 @@ EXPORT_SYMBOL(netpoll_setup); EXPORT_SYMBOL(netpoll_cleanup); EXPORT_SYMBOL(netpoll_send_udp); EXPORT_SYMBOL(netpoll_poll); -EXPORT_SYMBOL(netpoll_queue); -- cgit v1.2.3 From bf6bce71eae386dbc37f93af7e5ad173450d9945 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 26 Oct 2006 15:46:56 -0700 Subject: netpoll header cleanup As Steve left netpoll beast, hopefully not to return soon. He noticed that the header was messy. He straightened it up and polished it a little, then waved goodbye. Signed-off-by: Stephen Hemminger --- include/linux/netpoll.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux/netpoll.h') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index b7eb008c43de..2cc9867b1626 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -12,16 +12,15 @@ #include #include -struct netpoll; - struct netpoll { struct net_device *dev; - char dev_name[16], *name; + char dev_name[IFNAMSIZ]; + const char *name; void (*rx_hook)(struct netpoll *, int, char *, int); u32 local_ip, remote_ip; u16 local_port, remote_port; - unsigned char local_mac[6], remote_mac[6]; + u8 local_mac[ETH_ALEN], remote_mac[ETH_ALEN]; }; struct netpoll_info { -- cgit v1.2.3 From 6d5aefb8eaa38e44b5b8cf60c812aceafc02d924 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 5 Dec 2006 19:36:26 +0000 Subject: WorkQueue: Fix up arch-specific work items where possible Fix up arch-specific work items where possible to use the new work_struct and delayed_work structs. Three places that enqueue bits of their stack and then return have been marked with #error as this is not permitted. Signed-Off-By: David Howells --- arch/arm/common/sharpsl_pm.c | 22 +++++++++++----------- arch/arm/mach-omap1/board-h3.c | 3 ++- arch/arm/mach-omap1/board-nokia770.c | 6 +++--- arch/arm/mach-omap1/leds-osk.c | 4 ++-- arch/arm/mach-omap2/board-h4.c | 3 ++- arch/arm/mach-pxa/akita-ioexp.c | 6 +++--- arch/ia64/hp/sim/simserial.c | 4 ++-- arch/ia64/kernel/mca.c | 8 ++++---- arch/ia64/kernel/smpboot.c | 12 +++++++----- arch/mips/kernel/kspd.c | 4 ++-- arch/powerpc/platforms/embedded6xx/ls_uart.c | 4 ++-- arch/powerpc/platforms/powermac/backlight.c | 12 ++++++------ arch/ppc/8260_io/fcc_enet.c | 21 +++++++++++++-------- arch/ppc/8xx_io/fec.c | 21 +++++++++++++-------- arch/s390/appldata/appldata_base.c | 6 +++--- arch/um/drivers/chan_kern.c | 2 +- arch/um/drivers/mconsole_kern.c | 4 ++-- arch/um/drivers/net_kern.c | 1 + arch/um/drivers/port_kern.c | 4 ++-- drivers/macintosh/rack-meter.c | 16 ++++++++++------ drivers/net/chelsio/cphy.h | 2 +- drivers/net/chelsio/my3126.c | 8 +++++--- drivers/net/netxen/netxen_nic.h | 3 ++- drivers/net/netxen/netxen_nic_init.c | 5 +++-- drivers/net/netxen/netxen_nic_main.c | 19 ++++++++++--------- drivers/net/smc91x.c | 15 +++++++++------ drivers/net/wireless/zd1211rw/zd_mac.c | 23 +++++++++++++---------- drivers/net/wireless/zd1211rw/zd_mac.h | 4 ++-- drivers/spi/pxa2xx_spi.c | 9 +++++---- drivers/usb/core/hub.c | 2 +- drivers/usb/misc/appledisplay.c | 11 ++++++----- drivers/video/pxafb.c | 7 ++++--- include/asm-arm/arch-omap/irda.h | 2 +- include/linux/netpoll.h | 2 +- 34 files changed, 154 insertions(+), 121 deletions(-) (limited to 'include/linux/netpoll.h') diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 605dedf96790..b3599743093b 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -60,16 +60,16 @@ static int sharpsl_ac_check(void); static int sharpsl_fatal_check(void); static int sharpsl_average_value(int ad); static void sharpsl_average_clear(void); -static void sharpsl_charge_toggle(void *private_); -static void sharpsl_battery_thread(void *private_); +static void sharpsl_charge_toggle(struct work_struct *private_); +static void sharpsl_battery_thread(struct work_struct *private_); /* * Variables */ struct sharpsl_pm_status sharpsl_pm; -DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); -DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); +DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); +DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); @@ -116,7 +116,7 @@ void sharpsl_battery_kick(void) EXPORT_SYMBOL(sharpsl_battery_kick); -static void sharpsl_battery_thread(void *private_) +static void sharpsl_battery_thread(struct work_struct *private_) { int voltage, percent, apm_status, i = 0; @@ -128,7 +128,7 @@ static void sharpsl_battery_thread(void *private_) /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); while(1) { voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); @@ -212,7 +212,7 @@ static void sharpsl_charge_off(void) sharpsl_pm_led(SHARPSL_LED_OFF); sharpsl_pm.charge_mode = CHRG_OFF; - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } static void sharpsl_charge_error(void) @@ -222,7 +222,7 @@ static void sharpsl_charge_error(void) sharpsl_pm.charge_mode = CHRG_ERROR; } -static void sharpsl_charge_toggle(void *private_) +static void sharpsl_charge_toggle(struct work_struct *private_) { dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); @@ -254,7 +254,7 @@ static void sharpsl_ac_timer(unsigned long data) else if (sharpsl_pm.charge_mode == CHRG_ON) sharpsl_charge_off(); - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } @@ -279,10 +279,10 @@ static void sharpsl_chrg_full_timer(unsigned long data) sharpsl_charge_off(); } else if (sharpsl_pm.full_count < 2) { dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else { sharpsl_charge_off(); sharpsl_pm.charge_mode = CHRG_DONE; diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index f225a083dee1..9d2346fb68f4 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -323,7 +323,8 @@ static int h3_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index dbc555d209ff..cbe909bad79b 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -74,7 +74,7 @@ static struct omap_kp_platform_data nokia770_kp_data = { .rows = 8, .cols = 8, .keymap = nokia770_keymap, - .keymapsize = ARRAY_SIZE(nokia770_keymap) + .keymapsize = ARRAY_SIZE(nokia770_keymap), .delay = 4, }; @@ -191,7 +191,7 @@ static void nokia770_audio_pwr_up(void) printk("HP connected\n"); } -static void codec_delayed_power_down(void *arg) +static void codec_delayed_power_down(struct work_struct *work) { down(&audio_pwr_sem); if (audio_pwr_state == -1) @@ -200,7 +200,7 @@ static void codec_delayed_power_down(void *arg) up(&audio_pwr_sem); } -static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); +static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); static void nokia770_audio_pwr_down(void) { diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index 3b29e59b0e6f..0cbf1b0071f8 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c @@ -35,7 +35,7 @@ static u8 hw_led_state; static u8 tps_leds_change; -static void tps_work(void *unused) +static void tps_work(struct work_struct *unused) { for (;;) { u8 leds; @@ -61,7 +61,7 @@ static void tps_work(void *unused) } } -static DECLARE_WORK(work, tps_work, NULL); +static DECLARE_WORK(work, tps_work); #ifdef CONFIG_OMAP_OSK_MISTRAL diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 26a95a642ad7..3b1ad1d981a3 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -206,7 +206,8 @@ static int h4_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c index 1b398742ab56..12d2fe0ceff6 100644 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ b/arch/arm/mach-pxa/akita-ioexp.c @@ -36,11 +36,11 @@ I2C_CLIENT_INSMOD; static int max7310_write(struct i2c_client *client, int address, int data); static struct i2c_client max7310_template; -static void akita_ioexp_work(void *private_); +static void akita_ioexp_work(struct work_struct *private_); static struct device *akita_ioexp_device; static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT; -DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL); +DECLARE_WORK(akita_ioexp, akita_ioexp_work); /* @@ -158,7 +158,7 @@ void akita_reset_ioexp(struct device *dev, unsigned char bit) EXPORT_SYMBOL(akita_set_ioexp); EXPORT_SYMBOL(akita_reset_ioexp); -static void akita_ioexp_work(void *private_) +static void akita_ioexp_work(struct work_struct *private_) { if (akita_ioexp_device) max7310_set_ouputs(akita_ioexp_device, ioexp_output_value); diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index caab986af70c..b62f0c4d2c7c 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -209,7 +209,7 @@ static void do_serial_bh(void) } #endif -static void do_softint(void *private_) +static void do_softint(struct work_struct *private_) { printk(KERN_ERR "simserial: do_softint called\n"); } @@ -698,7 +698,7 @@ static int get_async_struct(int line, struct async_struct **ret_info) info->flags = sstate->flags; info->xmit_fifo_size = sstate->xmit_fifo_size; info->line = line; - INIT_WORK(&info->work, do_softint, info); + INIT_WORK(&info->work, do_softint); info->state = sstate; if (sstate->info) { kfree(info); diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 7cfa63a98cb3..6bedd97570ca 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -678,7 +678,7 @@ ia64_mca_cmc_vector_enable (void *dummy) * disable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_disable_keventd(void *unused) +ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0); } @@ -690,7 +690,7 @@ ia64_mca_cmc_vector_disable_keventd(void *unused) * enable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_enable_keventd(void *unused) +ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0); } @@ -1247,8 +1247,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = -1; } -static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL); -static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL); +static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); +static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd); /* * ia64_mca_cmc_int_handler diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index f7d7f5668144..b21ddecea943 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -463,15 +463,17 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) } struct create_idle { + struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; void -do_fork_idle(void *_c_idle) +do_fork_idle(struct work_struct *work) { - struct create_idle *c_idle = _c_idle; + struct create_idle *c_idle = + container_of(work, struct create_idle, work); c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -482,10 +484,10 @@ do_boot_cpu (int sapicid, int cpu) { int timeout; struct create_idle c_idle = { + .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER(c_idle.done), }; - DECLARE_WORK(work, do_fork_idle, &c_idle); c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -497,9 +499,9 @@ do_boot_cpu (int sapicid, int cpu) * We can't use kernel_thread since we must avoid to reschedule the child. */ if (!keventd_up() || current_is_keventd()) - work.func(work.data); + c_idle.work.func(&c_idle.work); else { - schedule_work(&work); + schedule_work(&c_idle.work); wait_for_completion(&c_idle.done); } diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index f06a144c7881..2c82412b9efe 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -319,7 +319,7 @@ static void sp_cleanup(void) static int channel_open = 0; /* the work handler */ -static void sp_work(void *data) +static void sp_work(struct work_struct *unused) { if (!channel_open) { if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { @@ -354,7 +354,7 @@ static void startwork(int vpe) return; } - INIT_WORK(&work, sp_work, NULL); + INIT_WORK(&work, sp_work); queue_work(workqueue, &work); } else queue_work(workqueue, &work); diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c index 31bcdae84823..0e837762cc5b 100644 --- a/arch/powerpc/platforms/embedded6xx/ls_uart.c +++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c @@ -14,7 +14,7 @@ static unsigned long avr_clock; static struct work_struct wd_work; -static void wd_stop(void *unused) +static void wd_stop(struct work_struct *unused) { const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"; int i = 0, rescue = 8; @@ -122,7 +122,7 @@ static int __init ls_uarts_init(void) ls_uart_init(); - INIT_WORK(&wd_work, wd_stop, NULL); + INIT_WORK(&wd_work, wd_stop); schedule_work(&wd_work); return 0; diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index afa593a8544a..c3a89414ddc0 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -18,11 +18,11 @@ #define OLD_BACKLIGHT_MAX 15 -static void pmac_backlight_key_worker(void *data); -static void pmac_backlight_set_legacy_worker(void *data); +static void pmac_backlight_key_worker(struct work_struct *work); +static void pmac_backlight_set_legacy_worker(struct work_struct *work); -static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); -static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); +static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker); +static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker); /* Although these variables are used in interrupt context, it makes no sense to * protect them. No user is able to produce enough key events per second and @@ -94,7 +94,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) return level; } -static void pmac_backlight_key_worker(void *data) +static void pmac_backlight_key_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; @@ -166,7 +166,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) return error; } -static void pmac_backlight_set_legacy_worker(void *data) +static void pmac_backlight_set_legacy_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 2e1943e27819..709952c25f29 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -385,6 +385,7 @@ struct fcc_enet_private { phy_info_t *phy; struct work_struct phy_relink; struct work_struct phy_display_config; + struct net_device *dev; uint sequence_done; @@ -1391,10 +1392,11 @@ static phy_info_t *phy_info[] = { NULL }; -static void mii_display_status(void *data) +static void mii_display_status(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, phy_relink); + struct net_device *dev = fep->dev; uint s = fep->phy_status; if (!fep->link && !fep->old_link) { @@ -1428,10 +1430,12 @@ static void mii_display_status(void *data) printk(".\n"); } -static void mii_display_config(void *data) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, + phy_display_config); + struct net_device *dev = fep->dev; uint s = fep->phy_status; printk("%s: config: auto-negotiation ", dev->name); @@ -1758,8 +1762,9 @@ static int __init fec_enet_init(void) cep->phy_id_done = 0; cep->phy_addr = fip->fc_phyaddr; mii_queue(dev, mk_mii_read(MII_PHYSID1), mii_discover_phy); - INIT_WORK(&cep->phy_relink, mii_display_status, dev); - INIT_WORK(&cep->phy_display_config, mii_display_config, dev); + INIT_WORK(&cep->phy_relink, mii_display_status); + INIT_WORK(&cep->phy_display_config, mii_display_config); + cep->dev = dev; #endif /* CONFIG_USE_MDIO */ fip++; diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 2f9fa9e3d331..e6c28fb423b2 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -173,6 +173,7 @@ struct fec_enet_private { uint phy_speed; phy_info_t *phy; struct work_struct phy_task; + struct net_device *dev; uint sequence_done; @@ -1263,10 +1264,11 @@ static void mii_display_status(struct net_device *dev) printk(".\n"); } -static void mii_display_config(void *priv) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1295,10 +1297,11 @@ static void mii_display_config(void *priv) fep->sequence_done = 1; } -static void mii_relink(void *priv) +static void mii_relink(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1325,7 +1328,8 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_relink, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_relink); schedule_work(&fep->phy_task); } @@ -1333,7 +1337,8 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_display_config); schedule_work(&fep->phy_task); } diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index af1e8fc7d985..67d5cf9cba83 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -92,8 +92,8 @@ static int appldata_timer_active; * Work queue */ static struct workqueue_struct *appldata_wq; -static void appldata_work_fn(void *data); -static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); +static void appldata_work_fn(struct work_struct *work); +static DECLARE_WORK(appldata_work, appldata_work_fn); /* @@ -125,7 +125,7 @@ static void appldata_timer_function(unsigned long data) * * call data gathering function for each (active) module */ -static void appldata_work_fn(void *data) +static void appldata_work_fn(struct work_struct *work) { struct list_head *lh; struct appldata_ops *ops; diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3576b3cc505e..7d4190e55654 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -638,7 +638,7 @@ int chan_out_fd(struct list_head *chans) return -1; } -void chan_interrupt(struct list_head *chans, struct work_struct *task, +void chan_interrupt(struct list_head *chans, struct delayed_work *task, struct tty_struct *tty, int irq) { struct list_head *ele, *next; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 7b172160fe04..96f0189327af 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -56,7 +56,7 @@ static struct notifier_block reboot_notifier = { static LIST_HEAD(mc_requests); -static void mc_work_proc(void *unused) +static void mc_work_proc(struct work_struct *unused) { struct mconsole_entry *req; unsigned long flags; @@ -72,7 +72,7 @@ static void mc_work_proc(void *unused) } } -static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); +static DECLARE_WORK(mconsole_work, mc_work_proc); static irqreturn_t mconsole_interrupt(int irq, void *dev_id) { diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index ec9eb8bd9432..286bc0b3207f 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -99,6 +99,7 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id) * same device, since it tests for (dev->flags & IFF_UP). So * there's no harm in delaying the device shutdown. */ schedule_work(&close_work); +#error this is not permitted - close_work will go out of scope goto out; } reactivate_fd(lp->fd, UM_ETH_IRQ); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index ce9f3733f73e..6dfe632f1c14 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -132,7 +132,7 @@ static int port_accept(struct port_list *port) DECLARE_MUTEX(ports_sem); struct list_head ports = LIST_HEAD_INIT(ports); -void port_work_proc(void *unused) +void port_work_proc(struct work_struct *unused) { struct port_list *port; struct list_head *ele; @@ -150,7 +150,7 @@ void port_work_proc(void *unused) local_irq_restore(flags); } -DECLARE_WORK(port_work, port_work_proc, NULL); +DECLARE_WORK(port_work, port_work_proc); static irqreturn_t port_interrupt(int irq, void *data) { diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index f1b6f563673a..5ed41fe84e57 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -48,7 +48,8 @@ struct rackmeter_dma { } ____cacheline_aligned; struct rackmeter_cpu { - struct work_struct sniffer; + struct delayed_work sniffer; + struct rackmeter *rm; cputime64_t prev_wall; cputime64_t prev_idle; int zero; @@ -208,11 +209,12 @@ static void rackmeter_setup_dbdma(struct rackmeter *rm) rackmeter_do_pause(rm, 0); } -static void rackmeter_do_timer(void *data) +static void rackmeter_do_timer(struct work_struct *work) { - struct rackmeter *rm = data; + struct rackmeter_cpu *rcpu = + container_of(work, struct rackmeter_cpu, sniffer.work); + struct rackmeter *rm = rcpu->rm; unsigned int cpu = smp_processor_id(); - struct rackmeter_cpu *rcpu = &rm->cpu[cpu]; cputime64_t cur_jiffies, total_idle_ticks; unsigned int total_ticks, idle_ticks; int i, offset, load, cumm, pause; @@ -263,8 +265,10 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) * on those machines yet */ - INIT_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer, rm); - INIT_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer, rm); + rm->cpu[0].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer); + rm->cpu[1].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer); for_each_online_cpu(cpu) { struct rackmeter_cpu *rcpu; diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h index 60901f25014e..cf9143499882 100644 --- a/drivers/net/chelsio/cphy.h +++ b/drivers/net/chelsio/cphy.h @@ -91,7 +91,7 @@ struct cphy { int state; /* Link status state machine */ adapter_t *adapter; /* associated adapter */ - struct work_struct phy_update; + struct delayed_work phy_update; u16 bmsr; int count; diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c index 0b90014d5b3e..c7731b6f9de3 100644 --- a/drivers/net/chelsio/my3126.c +++ b/drivers/net/chelsio/my3126.c @@ -93,9 +93,11 @@ static int my3126_interrupt_handler(struct cphy *cphy) return cphy_cause_link_change; } -static void my3216_poll(void *arg) +static void my3216_poll(struct work_struct *work) { - my3126_interrupt_handler(arg); + struct cphy *cphy = container_of(work, struct cphy, phy_update.work); + + my3126_interrupt_handler(cphy); } static int my3126_set_loopback(struct cphy *cphy, int on) @@ -171,7 +173,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter, if (cphy) cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); - INIT_WORK(&cphy->phy_update, my3216_poll, cphy); + INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); cphy->bmsr = 0; return (cphy); diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d925053fe597..9c588af8ab74 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -714,6 +714,7 @@ struct netxen_adapter { spinlock_t lock; struct work_struct watchdog_task; struct work_struct tx_timeout_task; + struct net_device *netdev; struct timer_list watchdog_timer; u32 curr_window; @@ -921,7 +922,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, struct netxen_port *port); int netxen_nic_rx_has_work(struct netxen_adapter *adapter); int netxen_nic_tx_has_work(struct netxen_adapter *adapter); -void netxen_watchdog_task(unsigned long v); +void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); void netxen_process_cmd_ring(unsigned long data); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 0dca029bc3e5..eae18236aefa 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -710,12 +710,13 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) return rv; } -void netxen_watchdog_task(unsigned long v) +void netxen_watchdog_task(struct work_struct *work) { int port_num; struct netxen_port *port; struct net_device *netdev; - struct netxen_adapter *adapter = (struct netxen_adapter *)v; + struct netxen_adapter *adapter = + container_of(work, struct netxen_adapter, watchdog_task); if (netxen_nic_check_temp(adapter)) return; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 1cb662d5bd76..df0bb36a1cfb 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -64,7 +64,7 @@ static int netxen_nic_open(struct net_device *netdev); static int netxen_nic_close(struct net_device *netdev); static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); static void netxen_tx_timeout(struct net_device *netdev); -static void netxen_tx_timeout_task(struct net_device *netdev); +static void netxen_tx_timeout_task(struct work_struct *work); static void netxen_watchdog(unsigned long); static int netxen_handle_int(struct netxen_adapter *, struct net_device *); static int netxen_nic_ioctl(struct net_device *netdev, @@ -274,8 +274,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.xg_linkup = 0; adapter->watchdog_timer.function = &netxen_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; - INIT_WORK(&adapter->watchdog_task, - (void (*)(void *))netxen_watchdog_task, adapter); + INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); adapter->ahw.pdev = pdev; adapter->proc_cmd_buf_counter = 0; pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id); @@ -379,8 +378,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_addr); } } - INIT_WORK(&adapter->tx_timeout_task, - (void (*)(void *))netxen_tx_timeout_task, netdev); + adapter->netdev = netdev; + INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -938,18 +937,20 @@ static void netxen_tx_timeout(struct net_device *netdev) schedule_work(&adapter->tx_timeout_task); } -static void netxen_tx_timeout_task(struct net_device *netdev) +static void netxen_tx_timeout_task(struct work_struct *work) { - struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); + struct netxen_adapter *adapter = + container_of(work, struct netxen_adapter, tx_timeout_task); + struct net_device *netdev = adapter->netdev; unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, netdev->name); - spin_lock_irqsave(&port->adapter->lock, flags); + spin_lock_irqsave(&adapter->lock, flags); netxen_nic_close(netdev); netxen_nic_open(netdev); - spin_unlock_irqrestore(&port->adapter->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); netdev->trans_start = jiffies; netif_wake_queue(netdev); } diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 95b6478f55c6..e62a9586fb95 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -210,6 +210,7 @@ struct smc_local { /* work queue */ struct work_struct phy_configure; + struct net_device *dev; int work_pending; spinlock_t lock; @@ -1114,10 +1115,11 @@ static void smc_phy_check_media(struct net_device *dev, int init) * of autonegotiation.) If the RPC ANEG bit is cleared, the selection * is controlled by the RPC SPEED and RPC DPLX bits. */ -static void smc_phy_configure(void *data) +static void smc_phy_configure(struct work_struct *work) { - struct net_device *dev = data; - struct smc_local *lp = netdev_priv(dev); + struct smc_local *lp = + container_of(work, struct smc_local, phy_configure); + struct net_device *dev = lp->dev; void __iomem *ioaddr = lp->base; int phyaddr = lp->mii.phy_id; int my_phy_caps; /* My PHY capabilities */ @@ -1592,7 +1594,7 @@ smc_open(struct net_device *dev) /* Configure the PHY, initialize the link state */ if (lp->phy_type != 0) - smc_phy_configure(dev); + smc_phy_configure(&lp->phy_configure); else { spin_lock_irq(&lp->lock); smc_10bt_check_media(dev, 1); @@ -1972,7 +1974,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) #endif tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); - INIT_WORK(&lp->phy_configure, smc_phy_configure, dev); + INIT_WORK(&lp->phy_configure, smc_phy_configure); + lp->dev = dev; lp->mii.phy_id_mask = 0x1f; lp->mii.reg_num_mask = 0x1f; lp->mii.force_media = 0; @@ -2322,7 +2325,7 @@ static int smc_drv_resume(struct platform_device *dev) smc_reset(ndev); smc_enable(ndev); if (lp->phy_type != 0) - smc_phy_configure(ndev); + smc_phy_configure(&lp->phy_configure); netif_device_attach(ndev); } } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 44f3cfd4cc1d..f1573a9c2336 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -32,8 +32,8 @@ static void ieee_init(struct ieee80211_device *ieee); static void softmac_init(struct ieee80211softmac_device *sm); -static void set_rts_cts_work(void *d); -static void set_basic_rates_work(void *d); +static void set_rts_cts_work(struct work_struct *work); +static void set_basic_rates_work(struct work_struct *work); static void housekeeping_init(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac); @@ -48,8 +48,8 @@ int zd_mac_init(struct zd_mac *mac, memset(mac, 0, sizeof(*mac)); spin_lock_init(&mac->lock); mac->netdev = netdev; - INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac); - INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac); + INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); + INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); @@ -366,9 +366,10 @@ static void try_enable_tx(struct zd_mac *mac) spin_unlock_irqrestore(&mac->lock, flags); } -static void set_rts_cts_work(void *d) +static void set_rts_cts_work(struct work_struct *work) { - struct zd_mac *mac = d; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_rts_cts_work.work); unsigned long flags; u8 rts_rate; unsigned int short_preamble; @@ -387,9 +388,10 @@ static void set_rts_cts_work(void *d) try_enable_tx(mac); } -static void set_basic_rates_work(void *d) +static void set_basic_rates_work(struct work_struct *work) { - struct zd_mac *mac = d; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_basic_rates_work.work); unsigned long flags; u16 basic_rates; @@ -467,12 +469,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) if (need_set_rts_cts && !mac->updating_rts_rate) { mac->updating_rts_rate = 1; netif_stop_queue(mac->netdev); - queue_work(zd_workqueue, &mac->set_rts_cts_work); + queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); } if (need_set_rates && !mac->updating_basic_rates) { mac->updating_basic_rates = 1; netif_stop_queue(mac->netdev); - queue_work(zd_workqueue, &mac->set_basic_rates_work); + queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, + 0); } spin_unlock_irqrestore(&mac->lock, flags); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 08d6b8c08e75..d4e8b870409d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -133,8 +133,8 @@ struct zd_mac { struct iw_statistics iw_stats; struct housekeeping housekeeping; - struct work_struct set_rts_cts_work; - struct work_struct set_basic_rates_work; + struct delayed_work set_rts_cts_work; + struct delayed_work set_basic_rates_work; unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 72025df5561d..494d9b856488 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -148,7 +148,7 @@ struct chip_data { void (*cs_control)(u32 command); }; -static void pump_messages(void *data); +static void pump_messages(struct work_struct *work); static int flush(struct driver_data *drv_data) { @@ -884,9 +884,10 @@ static void pump_transfers(unsigned long data) } } -static void pump_messages(void *data) +static void pump_messages(struct work_struct *work) { - struct driver_data *drv_data = data; + struct driver_data *drv_data = + container_of(work, struct driver_data, pump_messages); unsigned long flags; /* Lock queue and check for queue work */ @@ -1098,7 +1099,7 @@ static int init_queue(struct driver_data *drv_data) tasklet_init(&drv_data->pump_transfers, pump_transfers, (unsigned long)drv_data); - INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); + INIT_WORK(&drv_data->pump_messages, pump_messages); drv_data->workqueue = create_singlethread_workqueue( drv_data->master->cdev.dev->bus_id); if (drv_data->workqueue == NULL) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 39186db1015f..9be41ed1f9a6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -68,7 +68,7 @@ struct usb_hub { unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; - struct work_struct leds; + struct delayed_work leds; }; diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index ba30ca6a14aa..02cbb7fff24f 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -76,7 +76,7 @@ struct appledisplay { char *urbdata; /* interrupt URB data buffer */ char *msgdata; /* control message data buffer */ - struct work_struct work; + struct delayed_work work; int button_pressed; spinlock_t lock; }; @@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb) case ACD_BTN_BRIGHT_UP: case ACD_BTN_BRIGHT_DOWN: pdata->button_pressed = 1; - queue_work(wq, &pdata->work); + queue_delayed_work(wq, &pdata->work, 0); break; case ACD_BTN_NONE: default: @@ -184,9 +184,10 @@ static struct backlight_properties appledisplay_bl_data = { .max_brightness = 0xFF }; -static void appledisplay_work(void *private) +static void appledisplay_work(struct work_struct *work) { - struct appledisplay *pdata = private; + struct appledisplay *pdata = + container_of(work, struct appledisplay, work.work); int retval; up(&pdata->bd->sem); @@ -238,7 +239,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->udev = udev; spin_lock_init(&pdata->lock); - INIT_WORK(&pdata->work, appledisplay_work, pdata); + INIT_DELAYED_WORK(&pdata->work, appledisplay_work); /* Allocate buffer for control messages */ pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 8a8ae55a7403..38eb0b69c2d7 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -964,9 +964,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) * Our LCD controller task (which is called when we blank or unblank) * via keventd. */ -static void pxafb_task(void *dummy) +static void pxafb_task(struct work_struct *work) { - struct pxafb_info *fbi = dummy; + struct pxafb_info *fbi = + container_of(work, struct pxafb_info, task); u_int state = xchg(&fbi->task_state, -1); set_ctrlr_state(fbi, state); @@ -1159,7 +1160,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) } init_waitqueue_head(&fbi->ctrlr_wait); - INIT_WORK(&fbi->task, pxafb_task, fbi); + INIT_WORK(&fbi->task, pxafb_task); init_MUTEX(&fbi->ctrlr_sem); return fbi; diff --git a/include/asm-arm/arch-omap/irda.h b/include/asm-arm/arch-omap/irda.h index 805ae3575e44..345a649ec838 100644 --- a/include/asm-arm/arch-omap/irda.h +++ b/include/asm-arm/arch-omap/irda.h @@ -24,7 +24,7 @@ struct omap_irda_config { /* Very specific to the needs of some platforms (h3,h4) * having calls which can sleep in irda_set_speed. */ - struct work_struct gpio_expa; + struct delayed_work gpio_expa; int rx_channel; int tx_channel; unsigned long dest_start; diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 2cc9867b1626..29930b71a9aa 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -32,7 +32,7 @@ struct netpoll_info { struct netpoll *rx_np; /* netpoll that registered an rx_hook */ struct sk_buff_head arp_tx; /* list of arp requests to reply to */ struct sk_buff_head txq; - struct work_struct tx_work; + struct delayed_work tx_work; }; void netpoll_poll(struct netpoll *np); -- cgit v1.2.3