aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.de>2005-01-11 03:19:14 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 03:19:14 -0800
commite05b1590b2438ae6cb88c2bed68e2a9f60c3eb93 (patch)
treee67cef24de5d3c21e936a90589daefd411cdebfb /drivers
parentf1395ea3c1fbf67824ff83e5d4fd7aefb5346e90 (diff)
downloadhistory-e05b1590b2438ae6cb88c2bed68e2a9f60c3eb93.tar.gz
[PATCH] pcmcia: call device drivers from ds, not from cs
Call the PCMCIA 16-bit device drivers from ds.c instead of cs.c. Also, remove the delayed handling of CS_REMOVAL events, but keep the ordering the same as it used to be due to the delay. 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.c41
-rw-r--r--drivers/pcmcia/ds.c84
2 files changed, 60 insertions, 65 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 7a522f0eed8853..1358959daa105b 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -401,10 +401,18 @@ static void shutdown_socket(struct pcmcia_socket *s)
======================================================================*/
-static int pcmcia_send_event(struct pcmcia_socket *s, event_t event, int priority)
+/* NOTE: send_event needs to be called with skt->sem held. */
+
+static int send_event(struct pcmcia_socket *s, event_t event, int priority)
{
int ret;
+ if (s->state & SOCKET_CARDBUS)
+ return 0;
+
+ cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
+ event, priority, s->callback);
+
if (!s->callback)
return 0;
if (!try_module_get(s->callback->owner))
@@ -417,35 +425,6 @@ static int pcmcia_send_event(struct pcmcia_socket *s, event_t event, int priorit
return ret;
}
-
-/* NOTE: send_event needs to be called with skt->sem held. */
-
-static int send_event(struct pcmcia_socket *s, event_t event, int priority)
-{
- client_t *client = s->clients;
- int ret;
- cs_dbg(s, 1, "send_event(event %d, pri %d)\n",
- event, priority);
- ret = 0;
- if (s->state & SOCKET_CARDBUS)
- return 0;
-
- ret = pcmcia_send_event(s, event, priority);
- if (ret)
- return (ret);
-
- for (; 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;
- }
- }
- return ret;
-} /* send_event */
-
static void socket_remove_drivers(struct pcmcia_socket *skt)
{
client_t *client;
@@ -1404,7 +1383,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
s->callback = c;
if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
- pcmcia_send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+ send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else
s->callback = NULL;
err:
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 536dccc5bff1ee..fee02e131d8591 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -117,7 +117,6 @@ struct pcmcia_bus_socket {
user_info_t *user;
int req_pending, req_result;
wait_queue_head_t queue, request;
- struct work_struct removal;
socket_bind_t *bind;
struct pcmcia_socket *parent;
};
@@ -471,48 +470,68 @@ static int handle_request(struct pcmcia_bus_socket *s, event_t event)
return CS_SUCCESS;
}
-static void handle_removal(void *data)
-{
- struct pcmcia_bus_socket *s = data;
- handle_event(s, CS_EVENT_CARD_REMOVAL);
- s->state &= ~DS_SOCKET_REMOVAL_PENDING;
-}
-
/*======================================================================
The card status event handler.
======================================================================*/
+static int send_event(struct pcmcia_socket *s, event_t event, int priority)
+{
+ int ret = 0;
+ client_t *client;
+
+ 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;
+ }
+ }
+ return ret;
+} /* send_event */
+
+
+/* Normally, the event is passed to individual drivers after
+ * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
+ * is inversed to maintain historic compatibility.
+ */
+
static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
{
- struct pcmcia_bus_socket *s = skt->pcmcia;
+ struct pcmcia_bus_socket *s = skt->pcmcia;
+ int ret = 0;
- ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
- event, priority, s);
+ ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
+ event, priority, s);
- switch (event) {
-
- case CS_EVENT_CARD_REMOVAL:
- s->state &= ~DS_SOCKET_PRESENT;
- if (!(s->state & DS_SOCKET_REMOVAL_PENDING)) {
- s->state |= DS_SOCKET_REMOVAL_PENDING;
- schedule_delayed_work(&s->removal, HZ/10);
- }
- break;
-
- case CS_EVENT_CARD_INSERTION:
- s->state |= DS_SOCKET_PRESENT;
- handle_event(s, event);
- break;
+ switch (event) {
- case CS_EVENT_EJECTION_REQUEST:
- return handle_request(s, event);
- break;
+ case CS_EVENT_CARD_REMOVAL:
+ s->state &= ~DS_SOCKET_PRESENT;
+ send_event(skt, event, priority);
+ handle_event(s, event);
+ break;
- default:
- handle_event(s, event);
- break;
+ case CS_EVENT_CARD_INSERTION:
+ s->state |= DS_SOCKET_PRESENT;
+ handle_event(s, event);
+ send_event(skt, event, priority);
+ break;
+
+ case CS_EVENT_EJECTION_REQUEST:
+ ret = handle_request(s, event);
+ if (ret)
+ break;
+ ret = send_event(skt, event, priority);
+ break;
+
+ default:
+ handle_event(s, event);
+ send_event(skt, event, priority);
+ break;
}
return 0;
@@ -1099,7 +1118,6 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
init_waitqueue_head(&s->request);
/* initialize data */
- INIT_WORK(&s->removal, handle_removal, s);
s->parent = socket;
/* Set up hotline to Card Services */
@@ -1128,8 +1146,6 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev)
pccard_register_pcmcia(socket, NULL);
- flush_scheduled_work();
-
socket->pcmcia->state |= DS_SOCKET_DEAD;
pcmcia_put_bus_socket(socket->pcmcia);
socket->pcmcia = NULL;