From 18e4786e89f773ff4bacebad598ae52151b1c4de Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 30 Mar 2003 00:13:33 +0000 Subject: [PATCH] [PCMCIA] Fix "Removing wireless card triggers might_sleep warnings." Bug 516. Use schedule_delayed_work instead of a timer should fix this. Thanks to Andrew Morton and Russell King. (Added flush_scheduled_work() to ensure our delayed work completes before we free the pcmcia_bus_socket structure. --rmk) --- drivers/pcmcia/ds.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 09432fb60545a..2117f33a7dd11 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -103,7 +104,7 @@ struct pcmcia_bus_socket { user_info_t *user; int req_pending, req_result; wait_queue_head_t queue, request; - struct timer_list removal; + struct work_struct removal; socket_bind_t *bind; struct device *socket_dev; struct list_head socket_list; @@ -299,9 +300,9 @@ static int handle_request(struct pcmcia_bus_socket *s, event_t event) return CS_SUCCESS; } -static void handle_removal(u_long sn) +static void handle_removal(void *data) { - struct pcmcia_bus_socket *s = get_socket_info_by_nr(sn); + struct pcmcia_bus_socket *s = data; handle_event(s, CS_EVENT_CARD_REMOVAL); s->state &= ~SOCKET_REMOVAL_PENDING; } @@ -326,10 +327,8 @@ static int ds_event(event_t event, int priority, case CS_EVENT_CARD_REMOVAL: s->state &= ~SOCKET_PRESENT; if (!(s->state & SOCKET_REMOVAL_PENDING)) { - s->state |= SOCKET_REMOVAL_PENDING; - init_timer(&s->removal); - s->removal.expires = jiffies + HZ/10; - add_timer(&s->removal); + s->state |= SOCKET_REMOVAL_PENDING; + schedule_delayed_work(&s->removal, HZ/10); } break; @@ -922,9 +921,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock /* initialize data */ s->socket_dev = dev; - s->removal.data = s->socket_no; - s->removal.function = &handle_removal; - init_timer(&s->removal); + INIT_WORK(&s->removal, handle_removal, s); /* Set up hotline to Card Services */ client_reg.dev_info = bind.dev_info = &dev_info; @@ -986,6 +983,8 @@ static int __devexit pcmcia_bus_remove_socket_dev(struct device *dev) if (!cls_d) return -ENODEV; + flush_scheduled_work(); + down_write(&bus_socket_list_rwsem); list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) { struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list); -- 2.53.0