]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] pcmcia: call device drivers from ds, not from cs
authorDominik Brodowski <linux@dominikbrodowski.de>
Tue, 11 Jan 2005 11:19:14 +0000 (03:19 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 11 Jan 2005 11:19:14 +0000 (03:19 -0800)
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>
drivers/pcmcia/cs.c
drivers/pcmcia/ds.c

index 7a522f0eed8853f38e9a95c6057d1e60298f23ca..1358959daa105b51566da4339f8225d7fcd5121e 100644 (file)
@@ -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:
index 536dccc5bff1ee929915530905a4a6878a3ba971..fee02e131d8591e27ab2d6fef4c35f28fb322f06 100644 (file)
@@ -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;