CAPI: Rework capi_ctr_ready/down
authorJan Kiszka <jan.kiszka@web.de>
Mon, 8 Feb 2010 10:12:12 +0000 (10:12 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Feb 2010 00:01:21 +0000 (16:01 -0800)
This step prepares the application of proper controller locking: Push
all state changing work into the notify handler that are called by
capi_ctr_ready and capi_ctr_down, switch detach_capi_ctr to issue a
synchronous ctr_down. Also ensure that we do not go through any action
if the state did not change.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/isdn/capi/kcapi.c

index c46964fc17c79656adc9cc0f955652456b297992..9362a7a66aa15f5f8fa2321fa30801c930118687 100644 (file)
@@ -169,44 +169,74 @@ static void release_appl(struct capi_ctr *ctr, u16 applid)
 
 static void notify_up(u32 contr)
 {
-       struct capi_ctr *ctr = get_capi_ctr_by_nr(contr);
        struct capi20_appl *ap;
+       struct capi_ctr *ctr;
        u16 applid;
 
-       if (showcapimsgs & 1) {
+       if (showcapimsgs & 1)
                printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
-       }
-       if (!ctr) {
+
+       ctr = get_capi_ctr_by_nr(contr);
+       if (ctr) {
+               if (ctr->state == CAPI_CTR_RUNNING)
+                       return;
+
+               ctr->state = CAPI_CTR_RUNNING;
+
+               for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
+                       ap = get_capi_appl_by_nr(applid);
+                       if (!ap || ap->release_in_progress)
+                               continue;
+                       register_appl(ctr, applid, &ap->rparam);
+                       if (ap->callback && !ap->release_in_progress)
+                               ap->callback(KCI_CONTRUP, contr,
+                                            &ctr->profile);
+               }
+       } else
                printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
-               return;
-       }
-       for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
-               ap = get_capi_appl_by_nr(applid);
-               if (!ap || ap->release_in_progress) continue;
-               register_appl(ctr, applid, &ap->rparam);
-               if (ap->callback && !ap->release_in_progress)
-                       ap->callback(KCI_CONTRUP, contr, &ctr->profile);
-       }
 }
 
 /* -------- KCI_CONTRDOWN ------------------------------------- */
 
-static void notify_down(u32 contr)
+static void ctr_down(struct capi_ctr *ctr)
 {
        struct capi20_appl *ap;
        u16 applid;
 
-       if (showcapimsgs & 1) {
-               printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
-       }
+       if (ctr->state == CAPI_CTR_DETECTED)
+               return;
+
+       ctr->state = CAPI_CTR_DETECTED;
+
+       memset(ctr->manu, 0, sizeof(ctr->manu));
+       memset(&ctr->version, 0, sizeof(ctr->version));
+       memset(&ctr->profile, 0, sizeof(ctr->profile));
+       memset(ctr->serial, 0, sizeof(ctr->serial));
 
        for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
                ap = get_capi_appl_by_nr(applid);
-               if (ap && ap->callback && !ap->release_in_progress)
-                       ap->callback(KCI_CONTRDOWN, contr, NULL);
+               if (ap && !ap->release_in_progress) {
+                       if (ap->callback)
+                               ap->callback(KCI_CONTRDOWN, ctr->cnr, NULL);
+                       capi_ctr_put(ctr);
+               }
        }
 }
 
+static void notify_down(u32 contr)
+{
+       struct capi_ctr *ctr;
+
+       if (showcapimsgs & 1)
+               printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
+
+       ctr = get_capi_ctr_by_nr(contr);
+       if (ctr)
+               ctr_down(ctr);
+       else
+               printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
+}
+
 static void notify_handler(struct work_struct *work)
 {
        struct capi_notifier *np =
@@ -368,8 +398,6 @@ EXPORT_SYMBOL(capi_ctr_handle_message);
 
 void capi_ctr_ready(struct capi_ctr *ctr)
 {
-       ctr->state = CAPI_CTR_RUNNING;
-
        printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
               ctr->cnr, ctr->name);
 
@@ -388,28 +416,6 @@ EXPORT_SYMBOL(capi_ctr_ready);
 
 void capi_ctr_down(struct capi_ctr *ctr)
 {
-       u16 appl;
-
-       DBG("");
-
-       if (ctr->state == CAPI_CTR_DETECTED)
-               return;
-
-       ctr->state = CAPI_CTR_DETECTED;
-
-       memset(ctr->manu, 0, sizeof(ctr->manu));
-       memset(&ctr->version, 0, sizeof(ctr->version));
-       memset(&ctr->profile, 0, sizeof(ctr->profile));
-       memset(ctr->serial, 0, sizeof(ctr->serial));
-
-       for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-               struct capi20_appl *ap = get_capi_appl_by_nr(appl);
-               if (!ap || ap->release_in_progress)
-                       continue;
-
-               capi_ctr_put(ctr);
-       }
-
        printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
 
        notify_push(KCI_CONTRDOWN, ctr->cnr, 0, 0);
@@ -513,8 +519,7 @@ EXPORT_SYMBOL(attach_capi_ctr);
 
 int detach_capi_ctr(struct capi_ctr *ctr)
 {
-       if (ctr->state != CAPI_CTR_DETECTED)
-               capi_ctr_down(ctr);
+       ctr_down(ctr);
 
        ncontrollers--;