#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>
/* -------- 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 ------------------------------------------------- */
/* -------- 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 */
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;
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;
}
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",
#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 {
struct sk_buff *skb;
size_t copied;
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
if (!cdev->ap.applid)
return -ENODEV;
struct sk_buff *skb;
u16 mlen;
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
if (!cdev->ap.applid)
return -ENODEV;
if ((file->private_data = capidev_alloc()) == 0)
return -ENOMEM;
- return 0;
+ return nonseekable_open(inode, file);
}
static int
#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) {
}
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;
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) {
{
char *p;
char *compileinfo;
+ int major_ret;
if ((p = strchr(revision, ':')) != 0 && p[1]) {
strlcpy(rev, p + 2, sizeof(rev));
} else
strcpy(rev, "1.0");
- if (register_chrdev(capi_major, "capi20", &capi_fops)) {
+ major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
+ if (major_ret < 0) {
printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
- return -EIO;
+ return major_ret;
}
-
- 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;
}
{
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");