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 Index: 2.6.10-rc3/drivers/pcmcia/cs.c =================================================================== --- 2.6.10-rc3.orig/drivers/pcmcia/cs.c 2004-12-13 14:54:04.335268239 +0100 +++ 2.6.10-rc3/drivers/pcmcia/cs.c 2004-12-13 14:55:48.971716181 +0100 @@ -399,8 +399,9 @@ /*====================================================================== - 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. Index: 2.6.10-rc3/drivers/pcmcia/ds.c =================================================================== --- 2.6.10-rc3.orig/drivers/pcmcia/ds.c 2004-12-13 14:55:26.816797322 +0100 +++ 2.6.10-rc3/drivers/pcmcia/ds.c 2004-12-13 14:55:48.973715903 +0100 @@ -537,20 +537,47 @@ ======================================================================*/ +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 */