aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.de>2005-01-11 03:22:33 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 03:22:33 -0800
commiteff0cf2fcc19854c7db6b152d49cc0bf8d5cacdb (patch)
treea4baf35b12056db504df426753e8dcf6fafa2748 /drivers
parent00bfce19fba26c176381ddde535e5d85efdeea19 (diff)
downloadhistory-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.c5
-rw-r--r--drivers/pcmcia/ds.c47
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 */