diff options
author | Dominik Brodowski <linux@dominikbrodowski.de> | 2005-01-11 03:22:33 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-11 03:22:33 -0800 |
commit | eff0cf2fcc19854c7db6b152d49cc0bf8d5cacdb (patch) | |
tree | a4baf35b12056db504df426753e8dcf6fafa2748 /drivers | |
parent | 00bfce19fba26c176381ddde535e5d85efdeea19 (diff) | |
download | history-eff0cf2fcc19854c7db6b152d49cc0bf8d5cacdb.tar.gz |
[PATCH] pcmcia: use pcmcia_device in send_event
Use a struct pcmcia_device-based approach to inform "clients" of events. It
needs to be done using bus_for_each_device() so that we don't need to take the
device_list spinlock.
Signed-off-by: Dominik Brodowski <linux@brodo.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/cs.c | 5 | ||||
-rw-r--r-- | drivers/pcmcia/ds.c | 47 |
2 files changed, 40 insertions, 12 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c7827c26db94e6..d8564ac9a95bc6 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -399,8 +399,9 @@ static void shutdown_socket(struct pcmcia_socket *s) /*====================================================================== - The central event handler. Send_event() sends an event to all - valid clients. Parse_events() interprets the event bits from + The central event handler. Send_event() sends an event to the + 16-bit subsystem, which then calls the relevant device drivers. + Parse_events() interprets the event bits from a card status change report. Do_shutdown() handles the high priority stuff associated with a card removal. diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 107a48ba4ac83e..63029a08e24a35 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -537,20 +537,47 @@ static int handle_request(struct pcmcia_bus_socket *s, event_t event) ======================================================================*/ +struct send_event_data { + struct pcmcia_socket *skt; + event_t event; + int priority; +}; + +static int send_event_callback(struct device *dev, void * _data) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + struct send_event_data *data = _data; + + /* we get called for all sockets, but may only pass the event + * for drivers _on the affected socket_ */ + if (p_dev->socket != data->skt) + return 0; + + if (p_dev->client->state & (CLIENT_UNBOUND|CLIENT_STALE)) + return 0; + + if (p_dev->client->EventMask & data->event) + return EVENT(p_dev->client, data->event, data->priority); + + return 0; +} + static int send_event(struct pcmcia_socket *s, event_t event, int priority) { int ret = 0; - client_t *client; + struct send_event_data private; + struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia); - for (client = s->clients; client; client = client->next) { - if (client->state & (CLIENT_UNBOUND|CLIENT_STALE)) - continue; - if (client->EventMask & event) { - ret = EVENT(client, event, priority); - if (ret != 0) - return ret; - } - } + if (!skt) + return 0; + + private.skt = s; + private.event = event; + private.priority = priority; + + ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); + + pcmcia_put_bus_socket(skt); return ret; } /* send_event */ |