linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / isdn / capi / capi.c
index 42d7c6b..623adbb 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/moduleparam.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
@@ -57,20 +58,20 @@ MODULE_LICENSE("GPL");
 
 /* -------- driver information -------------------------------------- */
 
-static struct class_simple *capi_class;
+static struct class *capi_class;
 
-int capi_major = 68;           /* allocated */
+static int capi_major = 68;            /* allocated */
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #define CAPINC_NR_PORTS        32
 #define CAPINC_MAX_PORTS       256
-int capi_ttymajor = 191;
-int capi_ttyminors = CAPINC_NR_PORTS;
+static int capi_ttymajor = 191;
+static int capi_ttyminors = CAPINC_NR_PORTS;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
-MODULE_PARM(capi_major, "i");
+module_param_named(major, capi_major, uint, 0);
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-MODULE_PARM(capi_ttymajor, "i");
-MODULE_PARM(capi_ttyminors, "i");
+module_param_named(ttymajor, capi_ttymajor, uint, 0);
+module_param_named(ttyminors, capi_ttyminors, uint, 0);
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
 /* -------- defines ------------------------------------------------- */
@@ -142,11 +143,11 @@ struct capidev {
 
 /* -------- global variables ---------------------------------------- */
 
-static rwlock_t capidev_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(capidev_list_lock);
 static LIST_HEAD(capidev_list);
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-static rwlock_t capiminor_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(capiminor_list_lock);
 static LIST_HEAD(capiminor_list);
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
@@ -267,7 +268,7 @@ static void capiminor_free(struct capiminor *mp)
        kfree(mp);
 }
 
-struct capiminor *capiminor_find(unsigned int minor)
+static struct capiminor *capiminor_find(unsigned int minor)
 {
        struct list_head *l;
        struct capiminor *p = NULL;
@@ -436,51 +437,61 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
        struct sk_buff *nskb;
        int datalen;
        u16 errcode, datahandle;
-
+       struct tty_ldisc *ld;
+       
        datalen = skb->len - CAPIMSG_LEN(skb->data);
-       if (mp->tty) {
-               if (mp->tty->ldisc.receive_buf == 0) {
-                       printk(KERN_ERR "capi: ldisc has no receive_buf function\n");
-                       return -1;
-               }
-               if (mp->ttyinstop) {
+       if (mp->tty == NULL)
+       {
+#ifdef _DEBUG_DATAFLOW
+               printk(KERN_DEBUG "capi: currently no receiver\n");
+#endif
+               return -1;
+       }
+       
+       ld = tty_ldisc_ref(mp->tty);
+       if (ld == NULL)
+               return -1;
+       if (ld->receive_buf == NULL) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-                       printk(KERN_DEBUG "capi: recv tty throttled\n");
+               printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
 #endif
-                       return -1;
-               }
-               if (mp->tty->ldisc.receive_room &&
-                   mp->tty->ldisc.receive_room(mp->tty) < datalen) {
+               goto bad;
+       }
+       if (mp->ttyinstop) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-                       printk(KERN_DEBUG "capi: no room in tty\n");
+               printk(KERN_DEBUG "capi: recv tty throttled\n");
 #endif
-                       return -1;
-               }
-               if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
-                       printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
-                       return -1;
-               }
-               datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
-               errcode = capi20_put_message(mp->ap, nskb);
-               if (errcode != CAPI_NOERROR) {
-                       printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
-                                       errcode);
-                       kfree_skb(nskb);
-                       return -1;
-               }
-               (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
-#ifdef _DEBUG_DATAFLOW
-               printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
-                                       datahandle, skb->len);
+               goto bad;
+       }
+       if (mp->tty->receive_room < datalen) {
+#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
+               printk(KERN_DEBUG "capi: no room in tty\n");
 #endif
-               mp->tty->ldisc.receive_buf(mp->tty, skb->data, NULL, skb->len);
-               kfree_skb(skb);
-               return 0;
-
+               goto bad;
+       }
+       if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
+               printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
+               goto bad;
+       }
+       datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
+       errcode = capi20_put_message(mp->ap, nskb);
+       if (errcode != CAPI_NOERROR) {
+               printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
+                               errcode);
+               kfree_skb(nskb);
+               goto bad;
        }
+       (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
 #ifdef _DEBUG_DATAFLOW
-       printk(KERN_DEBUG "capi: currently no receiver\n");
+       printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
+                               datahandle, skb->len);
 #endif
+       ld->receive_buf(mp->tty, skb->data, NULL, skb->len);
+       kfree_skb(skb);
+       tty_ldisc_deref(ld);
+       return 0;
+bad:
+       tty_ldisc_deref(ld);
        return -1;
 }
 
@@ -614,6 +625,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 
 
        if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
+               
                datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
 #ifdef _DEBUG_DATAFLOW
                printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
@@ -633,10 +645,8 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 #endif
                kfree_skb(skb);
                (void)capiminor_del_ack(mp, datahandle);
-               if (mp->tty) {
-                       if (mp->tty->ldisc.write_wakeup)
-                               mp->tty->ldisc.write_wakeup(mp->tty);
-               }
+               if (mp->tty)
+                       tty_wakeup(mp->tty);
                (void)handle_minor_send(mp);
 
        } else {
@@ -656,9 +666,6 @@ capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        struct sk_buff *skb;
        size_t copied;
 
-       if (ppos != &file->f_pos)
-               return -ESPIPE;
-
        if (!cdev->ap.applid)
                return -ENODEV;
 
@@ -699,9 +706,6 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
        struct sk_buff *skb;
        u16 mlen;
 
-        if (ppos != &file->f_pos)
-               return -ESPIPE;
-
        if (!cdev->ap.applid)
                return -ENODEV;
 
@@ -965,7 +969,7 @@ capi_open(struct inode *inode, struct file *file)
        if ((file->private_data = capidev_alloc()) == 0)
                return -ENOMEM;
 
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 static int
@@ -1040,16 +1044,14 @@ static void capinc_tty_close(struct tty_struct * tty, struct file * file)
 #endif
 }
 
-static int capinc_tty_write(struct tty_struct * tty, int from_user,
+static int capinc_tty_write(struct tty_struct * tty,
                            const unsigned char *buf, int count)
 {
        struct capiminor *mp = (struct capiminor *)tty->driver_data;
        struct sk_buff *skb;
-       int retval;
 
 #ifdef _DEBUG_TTYFUNCS
-       printk(KERN_DEBUG "capinc_tty_write(from_user=%d,count=%d)\n",
-                               from_user, count);
+       printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
 #endif
 
        if (!mp || !mp->nccip) {
@@ -1073,18 +1075,7 @@ static int capinc_tty_write(struct tty_struct * tty, int from_user,
        }
 
        skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
-       if (from_user) {
-               retval = copy_from_user(skb_put(skb, count), buf, count);
-               if (retval) {
-                       kfree_skb(skb);
-#ifdef _DEBUG_TTYFUNCS
-                       printk(KERN_DEBUG "capinc_tty_write: copy_from_user=%d\n", retval);
-#endif
-                       return -EFAULT;
-               }
-       } else {
-               memcpy(skb_put(skb, count), buf, count);
-       }
+       memcpy(skb_put(skb, count), buf, count);
 
        skb_queue_tail(&mp->outqueue, skb);
        mp->outbytes += skb->len;
@@ -1174,7 +1165,7 @@ static int capinc_tty_write_room(struct tty_struct *tty)
        return room;
 }
 
-int capinc_tty_chars_in_buffer(struct tty_struct *tty)
+static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
 {
        struct capiminor *mp = (struct capiminor *)tty->driver_data;
        if (!mp || !mp->nccip) {
@@ -1507,20 +1498,20 @@ static int __init capi_init(void)
                return -EIO;
        }
 
-       capi_class = class_simple_create(THIS_MODULE, "capi");
+       capi_class = class_create(THIS_MODULE, "capi");
        if (IS_ERR(capi_class)) {
                unregister_chrdev(capi_major, "capi20");
                return PTR_ERR(capi_class);
        }
 
-       class_simple_device_add(capi_class, MKDEV(capi_major, 0), NULL, "capi");
+       class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
        devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
                        "isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
-               class_simple_device_remove(MKDEV(capi_major, 0));
-               class_simple_destroy(capi_class);
+               class_device_destroy(capi_class, MKDEV(capi_major, 0));
+               class_destroy(capi_class);
                unregister_chrdev(capi_major, "capi20");
                return -ENOMEM;
        }
@@ -1547,8 +1538,8 @@ static void __exit capi_exit(void)
 {
        proc_exit();
 
-       class_simple_device_remove(MKDEV(capi_major, 0));
-       class_simple_destroy(capi_class);
+       class_device_destroy(capi_class, MKDEV(capi_major, 0));
+       class_destroy(capi_class);
        unregister_chrdev(capi_major, "capi20");
        devfs_remove("isdn/capi20");