fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / isdn / capi / capidrv.c
index 150e31d..c4d438c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kernelcapi.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/moduleparam.h>
 
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
@@ -40,7 +41,7 @@ static int debugmode = 0;
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debugmode, "i");
+module_param(debugmode, uint, 0);
 
 /* -------- type definitions ----------------------------------------- */
 
@@ -139,7 +140,7 @@ typedef struct capidrv_bchan capidrv_bchan;
 /* -------- data definitions ----------------------------------------- */
 
 static capidrv_data global;
-static spinlock_t global_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(global_lock);
 
 static void handle_dtrace_data(capidrv_contr *card,
        int send, int level2, u8 *data, u16 len);
@@ -333,12 +334,11 @@ static capidrv_plci *new_plci(capidrv_contr * card, int chan)
 {
        capidrv_plci *plcip;
 
-       plcip = (capidrv_plci *) kmalloc(sizeof(capidrv_plci), GFP_ATOMIC);
+       plcip = kzalloc(sizeof(capidrv_plci), GFP_ATOMIC);
 
        if (plcip == 0)
                return NULL;
 
-       memset(plcip, 0, sizeof(capidrv_plci));
        plcip->state = ST_PLCI_NONE;
        plcip->plci = 0;
        plcip->msgid = 0;
@@ -403,12 +403,11 @@ static inline capidrv_ncci *new_ncci(capidrv_contr * card,
 {
        capidrv_ncci *nccip;
 
-       nccip = (capidrv_ncci *) kmalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
+       nccip = kzalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
 
        if (nccip == 0)
                return NULL;
 
-       memset(nccip, 0, sizeof(capidrv_ncci));
        nccip->ncci = ncci;
        nccip->state = ST_NCCI_NONE;
        nccip->plcip = plcip;
@@ -512,7 +511,8 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
        len = CAPIMSG_LEN(cmsg->buf);
        skb = alloc_skb(len, GFP_ATOMIC);
        memcpy(skb_put(skb, len), cmsg->buf, len);
-       capi20_put_message(&global.ap, skb);
+       if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
+               kfree_skb(skb);
 }
 
 /* -------- state machine -------------------------------------------- */
@@ -1905,7 +1905,8 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel)
        }
 
        for (p=buf, count=0; count < len; p++, count++) {
-               put_user(*card->q931_read++, p);
+               if (put_user(*card->q931_read++, p))
+                       return -EFAULT;
                if (card->q931_read > card->q931_end)
                        card->q931_read = card->q931_buf;
        }
@@ -2002,18 +2003,17 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
                printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
                return -1;
        }
-       if (!(card = (capidrv_contr *) kmalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
+       if (!(card = kzalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
                printk(KERN_WARNING
                 "capidrv: (%s) Could not allocate contr-struct.\n", id);
                return -1;
        }
-       memset(card, 0, sizeof(capidrv_contr));
        card->owner = THIS_MODULE;
        init_timer(&card->listentimer);
        strcpy(card->name, id);
        card->contrnr = contr;
        card->nbchan = profp->nbchannel;
-       card->bchans = (capidrv_bchan *) kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
+       card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
        if (!card->bchans) {
                printk(KERN_WARNING
                "capidrv: (%s) Could not allocate bchan-structs.\n", id);
@@ -2056,6 +2056,10 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
                return -1;
        }
        card->myid = card->interface.channels;
+       memset(card->bchans, 0, sizeof(capidrv_bchan) * card->nbchan);
+       for (i = 0; i < card->nbchan; i++) {
+               card->bchans[i].contr = card;
+       }
 
        spin_lock_irqsave(&global_lock, flags);
        card->next = global.contr_list;
@@ -2063,11 +2067,6 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
        global.ncontr++;
        spin_unlock_irqrestore(&global_lock, flags);
 
-       memset(card->bchans, 0, sizeof(capidrv_bchan) * card->nbchan);
-       for (i = 0; i < card->nbchan; i++) {
-               card->bchans[i].contr = card;
-       }
-
        cmd.command = ISDN_STAT_RUN;
        cmd.driver = card->myid;
        card->interface.statcallb(&cmd);
@@ -2075,10 +2074,9 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
        card->cipmask = 0x1FFF03FF;     /* any */
        card->cipmask2 = 0;
 
-       send_listen(card);
-
        card->listentimer.data = (unsigned long)card;
        card->listentimer.function = listentimerfunc;
+       send_listen(card);
        mod_timer(&card->listentimer, jiffies + 60*HZ);
 
        printk(KERN_INFO "%s: now up (%d B channels)\n",