Input: wacom - fix some formatting issues
[safe/jmp/linux-2.6] / drivers / isdn / capi / capidrv.c
index 8cec9c3..bf55ed5 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/fs.h>
@@ -25,6 +24,7 @@
 #include <linux/isdn.h>
 #include <linux/isdnif.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/ctype.h>
 #include <linux/isdn/capicmd.h>
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.1.2.2 $";
 static int debugmode = 0;
 
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
-module_param(debugmode, uint, 0);
+module_param(debugmode, uint, S_IRUGO|S_IWUSR);
 
 /* -------- type definitions ----------------------------------------- */
 
@@ -336,7 +335,7 @@ static capidrv_plci *new_plci(capidrv_contr * card, int chan)
 
        plcip = kzalloc(sizeof(capidrv_plci), GFP_ATOMIC);
 
-       if (plcip == 0)
+       if (plcip == NULL)
                return NULL;
 
        plcip->state = ST_PLCI_NONE;
@@ -405,7 +404,7 @@ static inline capidrv_ncci *new_ncci(capidrv_contr * card,
 
        nccip = kzalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
 
-       if (nccip == 0)
+       if (nccip == NULL)
                return NULL;
 
        nccip->ncci = ncci;
@@ -427,7 +426,7 @@ static inline capidrv_ncci *find_ncci(capidrv_contr * card, u32 ncci)
        capidrv_plci *plcip;
        capidrv_ncci *p;
 
-       if ((plcip = find_plci_by_ncci(card, ncci)) == 0)
+       if ((plcip = find_plci_by_ncci(card, ncci)) == NULL)
                return NULL;
 
        for (p = plcip->ncci_list; p; p = p->next)
@@ -442,7 +441,7 @@ static inline capidrv_ncci *find_ncci_by_msgid(capidrv_contr * card,
        capidrv_plci *plcip;
        capidrv_ncci *p;
 
-       if ((plcip = find_plci_by_ncci(card, ncci)) == 0)
+       if ((plcip = find_plci_by_ncci(card, ncci)) == NULL)
                return NULL;
 
        for (p = plcip->ncci_list; p; p = p->next)
@@ -507,9 +506,14 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
 {
        struct sk_buff *skb;
        size_t len;
+
        capi_cmsg2message(cmsg, cmsg->buf);
        len = CAPIMSG_LEN(cmsg->buf);
        skb = alloc_skb(len, GFP_ATOMIC);
+       if (!skb) {
+               printk(KERN_ERR "capidrv::send_message: can't allocate mem\n");
+               return;
+       }
        memcpy(skb_put(skb, len), cmsg->buf, len);
        if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
                kfree_skb(skb);
@@ -667,8 +671,8 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
                                 NULL,  /* Useruserdata */   /* $$$$ */
                                 NULL   /* Facilitydataarray */
        );
-       send_message(card, &cmsg);
        plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
+       send_message(card, &cmsg);
 
        cmd.command = ISDN_STAT_BHUP;
        cmd.driver = card->myid;
@@ -751,7 +755,7 @@ static inline int new_bchan(capidrv_contr * card)
 {
        int i;
        for (i = 0; i < card->nbchan; i++) {
-               if (card->bchans[i].plcip == 0) {
+               if (card->bchans[i].plcip == NULL) {
                        card->bchans[i].disconnecting = 0;
                        return i;
                }
@@ -826,7 +830,7 @@ static void handle_controller(_cmsg * cmsg)
                      case 0: break;
                      case 1: s = "unknown class"; break;
                      case 2: s = "unknown function"; break;
-                     default: s = "unkown error"; break;
+                     default: s = "unknown error"; break;
                   }
                   if (s)
                   printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
@@ -873,7 +877,7 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
                return;
        }
        bchan = &card->bchans[chan];
-       if ((plcip = new_plci(card, chan)) == 0) {
+       if ((plcip = new_plci(card, chan)) == NULL) {
                printk(KERN_ERR "capidrv-%d: incoming call: no memory, sorry.\n", card->contrnr);
                return;
        }
@@ -920,8 +924,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
                 */
                capi_cmsg_answer(cmsg);
                cmsg->Reject = 1;       /* ignore */
-               send_message(card, cmsg);
                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+               send_message(card, cmsg);
                printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
                        card->contrnr,
                        cmd.parm.setup.phone,
@@ -970,8 +974,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
        case 2:         /* Call will be rejected. */
                capi_cmsg_answer(cmsg);
                cmsg->Reject = 2;       /* reject call, normal call clearing */
-               send_message(card, cmsg);
                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+               send_message(card, cmsg);
                break;
 
        default:
@@ -979,8 +983,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
                capi_cmsg_answer(cmsg);
                cmsg->Reject = 8;       /* reject call,
                                           destination out of order */
-               send_message(card, cmsg);
                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+               send_message(card, cmsg);
                break;
        }
        return;
@@ -991,6 +995,7 @@ static void handle_plci(_cmsg * cmsg)
        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
        capidrv_plci *plcip;
        isdn_ctrl cmd;
+       _cdebbuf *cdb;
 
        if (!card) {
                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
@@ -1015,8 +1020,8 @@ static void handle_plci(_cmsg * cmsg)
                card->bchans[plcip->chan].disconnecting = 1;
                plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
                capi_cmsg_answer(cmsg);
-               send_message(card, cmsg);
                plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
+               send_message(card, cmsg);
                break;
 
        case CAPI_DISCONNECT_CONF:      /* plci */
@@ -1073,8 +1078,8 @@ static void handle_plci(_cmsg * cmsg)
 
                if (card->bchans[plcip->chan].incoming) {
                        capi_cmsg_answer(cmsg);
-                       send_message(card, cmsg);
                        plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
+                       send_message(card, cmsg);
                } else {
                        capidrv_ncci *nccip;
                        capi_cmsg_answer(cmsg);
@@ -1093,13 +1098,14 @@ static void handle_plci(_cmsg * cmsg)
                                                 NULL   /* NCPI */
                        );
                        nccip->msgid = cmsg->Messagenumber;
+                       plci_change_state(card, plcip,
+                                         EV_PLCI_CONNECT_ACTIVE_IND);
+                       ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
                        send_message(card, cmsg);
                        cmd.command = ISDN_STAT_DCONN;
                        cmd.driver = card->myid;
                        cmd.arg = plcip->chan;
                        card->interface.statcallb(&cmd);
-                       plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
-                       ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
                }
                break;
 
@@ -1123,8 +1129,15 @@ static void handle_plci(_cmsg * cmsg)
                                break;
                        }
                }
-               printk(KERN_ERR "capidrv-%d: %s\n",
-                               card->contrnr, capi_cmsg2str(cmsg));
+               cdb = capi_cmsg2str(cmsg);
+               if (cdb) {
+                       printk(KERN_WARNING "capidrv-%d: %s\n",
+                               card->contrnr, cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n",
+                               card->contrnr, cmsg->InfoNumber);
+
                break;
 
        case CAPI_CONNECT_ACTIVE_CONF:          /* plci */
@@ -1181,8 +1194,8 @@ static void handle_ncci(_cmsg * cmsg)
                        goto notfound;
 
                capi_cmsg_answer(cmsg);
-               send_message(card, cmsg);
                ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
+               send_message(card, cmsg);
 
                cmd.command = ISDN_STAT_BCONN;
                cmd.driver = card->myid;
@@ -1210,8 +1223,8 @@ static void handle_ncci(_cmsg * cmsg)
                                                          0,    /* Reject */
                                                          NULL  /* NCPI */
                                );
-                               send_message(card, cmsg);
                                ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
+                               send_message(card, cmsg);
                                break;
                        }
                        printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n",                                                 card->contrnr);
@@ -1287,8 +1300,8 @@ static void handle_ncci(_cmsg * cmsg)
                card->bchans[nccip->chan].disconnecting = 1;
                ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
                capi_cmsg_answer(cmsg);
-               send_message(card, cmsg);
                ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
+               send_message(card, cmsg);
                break;
 
        case CAPI_DISCONNECT_B3_CONF:   /* ncci */
@@ -1372,10 +1385,18 @@ static _cmsg s_cmsg;
 static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 {
        capi_message2cmsg(&s_cmsg, skb->data);
-       if (debugmode > 3)
-               printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
-                      ap->applid, capi_cmsg2str(&s_cmsg));
-       
+       if (debugmode > 3) {
+               _cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
+
+               if (cdb) {
+                       printk(KERN_DEBUG "%s: applid=%d %s\n", __func__,
+                               ap->applid, cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_DEBUG "%s: applid=%d %s not traced\n",
+                               __func__, ap->applid,
+                               capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand));
+       }
        if (s_cmsg.Command == CAPI_DATA_B3
            && s_cmsg.Subcommand == CAPI_IND) {
                handle_data(&s_cmsg, skb);
@@ -1499,7 +1520,7 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
                int digit2 = 0;
                if (!isdigit(*s)) return -3;
                while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; }
-               if (digit1 <= 0 && digit1 > 30) return -4;
+               if (digit1 <= 0 || digit1 > 30) return -4;
                if (*s == 0 || *s == ',' || *s == ' ') {
                        bmask |= (1 << digit1);
                        digit1 = 0;
@@ -1510,7 +1531,7 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
                s++;
                if (!isdigit(*s)) return -3;
                while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; }
-               if (digit2 <= 0 && digit2 > 30) return -4;
+               if (digit2 <= 0 || digit2 > 30) return -4;
                if (*s == 0 || *s == ',' || *s == ' ') {
                        if (digit1 > digit2)
                                for (i = digit2; i <= digit1 ; i++)
@@ -1641,7 +1662,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
                                              NULL,     /* Useruserdata */
                                              NULL      /* Facilitydataarray */
                            );
-                       if ((plcip = new_plci(card, (c->arg % card->nbchan))) == 0) {
+                       if ((plcip = new_plci(card, (c->arg % card->nbchan))) == NULL) {
                                cmd.command = ISDN_STAT_DHUP;
                                cmd.driver = card->myid;
                                cmd.arg = (c->arg % card->nbchan);
@@ -1823,6 +1844,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
        int msglen;
        u16 errcode;
        u16 datahandle;
+       u32 data;
 
        if (!card) {
                printk(KERN_ERR "capidrv: if_sendbuf called with invalid driverId %d!\n",
@@ -1840,9 +1862,26 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
                return 0;
        }
        datahandle = nccip->datahandle;
+
+       /*
+        * Here we copy pointer skb->data into the 32-bit 'Data' field.
+        * The 'Data' field is not used in practice in linux kernel
+        * (neither in 32 or 64 bit), but should have some value,
+        * since a CAPI message trace will display it.
+        *
+        * The correct value in the 32 bit case is the address of the
+        * data, in 64 bit it makes no sense, we use 0 there.
+        */
+
+#ifdef CONFIG_64BIT
+       data = 0;
+#else
+       data = (unsigned long) skb->data;
+#endif
+
        capi_fill_DATA_B3_REQ(&sendcmsg, global.ap.applid, card->msgid++,
                              nccip->ncci,      /* adr */
-                             (u32) skb->data,  /* Data */
+                             data,             /* Data */
                              skb->len,         /* DataLength */
                              datahandle,       /* DataHandle */
                              0 /* Flags */
@@ -1928,7 +1967,7 @@ static void enable_dchannel_trace(capidrv_contr *card)
                        card->name, errcode);
           return;
        }
-       if (strstr(manufacturer, "AVM") == 0) {
+       if (strstr(manufacturer, "AVM") == NULL) {
           printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
                        card->name, manufacturer);
           return;
@@ -1976,8 +2015,8 @@ static void send_listen(capidrv_contr *card)
                             card->cipmask,
                             card->cipmask2,
                             NULL, NULL);
-       send_message(card, &cmdcmsg);
        listen_change_state(card, EV_LISTEN_REQ);
+       send_message(card, &cmdcmsg);
 }
 
 static void listentimerfunc(unsigned long x)
@@ -2103,7 +2142,10 @@ static int capidrv_delcontr(u16 contr)
                printk(KERN_ERR "capidrv: delcontr: no contr %u\n", contr);
                return -1;
        }
-       #warning FIXME: maybe a race condition the card should be removed here from global list /kkeil
+
+       /* FIXME: maybe a race condition the card should be removed
+        * here from global list /kkeil
+        */
        spin_unlock_irqrestore(&global_lock, flags);
 
        del_timer(&card->listentimer);
@@ -2168,96 +2210,73 @@ static int capidrv_delcontr(u16 contr)
 }
 
 
-static void lower_callback(unsigned int cmd, u32 contr, void *data)
+static int
+lower_callback(struct notifier_block *nb, unsigned long val, void *v)
 {
+       capi_profile profile;
+       u32 contr = (long)v;
 
-       switch (cmd) {
-       case KCI_CONTRUP:
+       switch (val) {
+       case CAPICTR_UP:
                printk(KERN_INFO "capidrv: controller %hu up\n", contr);
-               (void) capidrv_addcontr(contr, (capi_profile *) data);
+               if (capi20_get_profile(contr, &profile) == CAPI_NOERROR)
+                       (void) capidrv_addcontr(contr, &profile);
                break;
-       case KCI_CONTRDOWN:
+       case CAPICTR_DOWN:
                printk(KERN_INFO "capidrv: controller %hu down\n", contr);
                (void) capidrv_delcontr(contr);
                break;
        }
+       return NOTIFY_OK;
 }
 
 /*
  * /proc/capi/capidrv:
  * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
  */
-static int proc_capidrv_read_proc(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
+static int capidrv_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-
-       len += sprintf(page+len, "%lu %lu %lu %lu\n",
+       seq_printf(m, "%lu %lu %lu %lu\n",
                        global.ap.nrecvctlpkt,
                        global.ap.nrecvdatapkt,
                        global.ap.nsentctlpkt,
                        global.ap.nsentdatapkt);
-       if (off+count >= len)
-          *eof = 1;
-       if (len < off)
-           return 0;
-       *start = page + off;
-       return ((count < len-off) ? count : len-off);
+       return 0;
 }
 
-static struct procfsentries {
-  char *name;
-  mode_t mode;
-  int (*read_proc)(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data);
-  struct proc_dir_entry *procent;
-} procfsentries[] = {
-   /* { "capi",                  S_IFDIR, 0 }, */
-   { "capi/capidrv",     0      , proc_capidrv_read_proc },
+static int capidrv_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, capidrv_proc_show, NULL);
+}
+
+static const struct file_operations capidrv_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = capidrv_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
 };
 
 static void __init proc_init(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=0; i < nelem; i++) {
-        struct procfsentries *p = procfsentries + i;
-       p->procent = create_proc_entry(p->name, p->mode, NULL);
-       if (p->procent) p->procent->read_proc = p->read_proc;
-    }
+       proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
 }
 
 static void __exit proc_exit(void)
 {
-    int nelem = ARRAY_SIZE(procfsentries);
-    int i;
-
-    for (i=nelem-1; i >= 0; i--) {
-        struct procfsentries *p = procfsentries + i;
-       if (p->procent) {
-          remove_proc_entry(p->name, NULL);
-          p->procent = NULL;
-       }
-    }
+       remove_proc_entry("capi/capidrv", NULL);
 }
 
+static struct notifier_block capictr_nb = {
+       .notifier_call = lower_callback,
+};
+
 static int __init capidrv_init(void)
 {
        capi_profile profile;
-       char rev[32];
-       char *p;
        u32 ncontr, contr;
        u16 errcode;
 
-       if ((p = strchr(revision, ':')) != 0 && p[1]) {
-               strncpy(rev, p + 2, sizeof(rev));
-               rev[sizeof(rev)-1] = 0;
-               if ((p = strchr(rev, '$')) != 0 && p > rev)
-                  *(p-1) = 0;
-       } else
-               strcpy(rev, "1.0");
-
        global.ap.rparam.level3cnt = -2;  /* number of bchannels twice */
        global.ap.rparam.datablkcnt = 16;
        global.ap.rparam.datablklen = 2048;
@@ -2268,7 +2287,7 @@ static int __init capidrv_init(void)
                return -EIO;
        }
 
-       capi20_set_callback(&global.ap, lower_callback);
+       register_capictr_notifier(&capictr_nb);
 
        errcode = capi20_get_profile(0, &profile);
        if (errcode != CAPI_NOERROR) {
@@ -2285,28 +2304,15 @@ static int __init capidrv_init(void)
        }
        proc_init();
 
-       printk(KERN_NOTICE "capidrv: Rev %s: loaded\n", rev);
        return 0;
 }
 
 static void __exit capidrv_exit(void)
 {
-       char rev[10];
-       char *p;
-
-       if ((p = strchr(revision, ':')) != 0) {
-               strcpy(rev, p + 1);
-               p = strchr(rev, '$');
-               *p = 0;
-       } else {
-               strcpy(rev, " ??? ");
-       }
-
+       unregister_capictr_notifier(&capictr_nb);
        capi20_release(&global.ap);
 
        proc_exit();
-
-       printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
 }
 
 module_init(capidrv_init);