include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / isdn / capi / kcapi.c
index a99f7e3..bd00dce 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
@@ -34,6 +35,7 @@
 #include <linux/b1lli.h>
 #endif
 #include <linux/mutex.h>
+#include <linux/rcupdate.h>
 
 static int showcapimsgs = 0;
 
@@ -64,8 +66,6 @@ DEFINE_MUTEX(capi_drivers_lock);
 struct capi_ctr *capi_controller[CAPI_MAXCONTR];
 DEFINE_MUTEX(capi_controller_lock);
 
-static DEFINE_RWLOCK(application_lock);
-
 struct capi20_appl *capi_applications[CAPI_MAXAPPL];
 
 static int ncontrollers;
@@ -103,7 +103,7 @@ static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
        if (applid - 1 >= CAPI_MAXAPPL)
                return NULL;
 
-       return capi_applications[applid - 1];
+       return rcu_dereference(capi_applications[applid - 1]);
 }
 
 /* -------- util functions ------------------------------------ */
@@ -186,7 +186,7 @@ static void notify_up(u32 contr)
 
                for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
                        ap = get_capi_appl_by_nr(applid);
-                       if (!ap || ap->release_in_progress)
+                       if (!ap)
                                continue;
                        register_appl(ctr, applid, &ap->rparam);
                }
@@ -216,7 +216,7 @@ static void ctr_down(struct capi_ctr *ctr, int new_state)
 
        for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
                ap = get_capi_appl_by_nr(applid);
-               if (ap && !ap->release_in_progress)
+               if (ap)
                        capi_ctr_put(ctr);
        }
 
@@ -336,7 +336,6 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
        struct capi20_appl *ap;
        int showctl = 0;
        u8 cmd, subcmd;
-       unsigned long flags;
        _cdebbuf *cdb;
 
        if (ctr->state != CAPI_CTR_RUNNING) {
@@ -384,10 +383,10 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
 
        }
 
-       read_lock_irqsave(&application_lock, flags);
+       rcu_read_lock();
        ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
-       if ((!ap) || (ap->release_in_progress)) {
-               read_unlock_irqrestore(&application_lock, flags);
+       if (!ap) {
+               rcu_read_unlock();
                cdb = capi_message2str(skb->data);
                if (cdb) {
                        printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
@@ -401,7 +400,7 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
        }
        skb_queue_tail(&ap->recv_queue, skb);
        schedule_work(&ap->recv_work);
-       read_unlock_irqrestore(&application_lock, flags);
+       rcu_read_unlock();
 
        return;
 
@@ -656,40 +655,35 @@ u16 capi20_register(struct capi20_appl *ap)
 {
        int i;
        u16 applid;
-       unsigned long flags;
 
        DBG("");
 
        if (ap->rparam.datablklen < 128)
                return CAPI_LOGBLKSIZETOSMALL;
 
-       write_lock_irqsave(&application_lock, flags);
+       ap->nrecvctlpkt = 0;
+       ap->nrecvdatapkt = 0;
+       ap->nsentctlpkt = 0;
+       ap->nsentdatapkt = 0;
+       mutex_init(&ap->recv_mtx);
+       skb_queue_head_init(&ap->recv_queue);
+       INIT_WORK(&ap->recv_work, recv_handler);
+       ap->release_in_progress = 0;
+
+       mutex_lock(&capi_controller_lock);
 
        for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
                if (capi_applications[applid - 1] == NULL)
                        break;
        }
        if (applid > CAPI_MAXAPPL) {
-               write_unlock_irqrestore(&application_lock, flags);
+               mutex_unlock(&capi_controller_lock);
                return CAPI_TOOMANYAPPLS;
        }
 
        ap->applid = applid;
        capi_applications[applid - 1] = ap;
 
-       ap->nrecvctlpkt = 0;
-       ap->nrecvdatapkt = 0;
-       ap->nsentctlpkt = 0;
-       ap->nsentdatapkt = 0;
-       mutex_init(&ap->recv_mtx);
-       skb_queue_head_init(&ap->recv_queue);
-       INIT_WORK(&ap->recv_work, recv_handler);
-       ap->release_in_progress = 0;
-
-       write_unlock_irqrestore(&application_lock, flags);
-       
-       mutex_lock(&capi_controller_lock);
-
        for (i = 0; i < CAPI_MAXCONTR; i++) {
                if (!capi_controller[i] ||
                    capi_controller[i]->state != CAPI_CTR_RUNNING)
@@ -721,16 +715,15 @@ EXPORT_SYMBOL(capi20_register);
 u16 capi20_release(struct capi20_appl *ap)
 {
        int i;
-       unsigned long flags;
 
        DBG("applid %#x", ap->applid);
 
-       write_lock_irqsave(&application_lock, flags);
+       mutex_lock(&capi_controller_lock);
+
        ap->release_in_progress = 1;
        capi_applications[ap->applid - 1] = NULL;
-       write_unlock_irqrestore(&application_lock, flags);
 
-       mutex_lock(&capi_controller_lock);
+       synchronize_rcu();
 
        for (i = 0; i < CAPI_MAXCONTR; i++) {
                if (!capi_controller[i] ||
@@ -785,11 +778,8 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
         * synchronizes this service with capi20_release.
         */
        ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
-       if (!ctr || ctr->state != CAPI_CTR_RUNNING) {
-               ctr = get_capi_ctr_by_nr(1); /* XXX why? */
-               if (!ctr || ctr->state != CAPI_CTR_RUNNING)
-                       return CAPI_REGNOTINSTALLED;
-       }
+       if (!ctr || ctr->state != CAPI_CTR_RUNNING)
+               return CAPI_REGNOTINSTALLED;
        if (ctr->blocked)
                return CAPI_SENDQUEUEFULL;