diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c22b34976c24..901b79bc3b56 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -153,6 +153,8 @@ static LIST_HEAD(capidev_list); static DEFINE_RWLOCK(capiminors_lock); static struct capiminor **capiminors; +static struct tty_driver *capinc_tty_driver; + /* -------- datahandles --------------------------------------------- */ static int capiminor_add_ack(struct capiminor *mp, u16 datahandle) @@ -213,6 +215,7 @@ static void capiminor_del_all_ack(struct capiminor *mp) static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) { struct capiminor *mp; + struct device *dev; unsigned int minor; unsigned long flags; @@ -243,19 +246,33 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) if (minor == capi_ttyminors) { printk(KERN_NOTICE "capi: out of minors\n"); - kfree(mp); - return NULL; + goto err_out1; } mp->minor = minor; + dev = tty_register_device(capinc_tty_driver, minor, NULL); + if (IS_ERR(dev)) + goto err_out2; + return mp; + +err_out2: + write_lock_irqsave(&capiminors_lock, flags); + capiminors[minor] = NULL; + write_unlock_irqrestore(&capiminors_lock, flags); + +err_out1: + kfree(mp); + return NULL; } static void capiminor_free(struct capiminor *mp) { unsigned long flags; + tty_unregister_device(capinc_tty_driver, mp->minor); + write_lock_irqsave(&capiminors_lock, flags); capiminors[mp->minor] = NULL; write_unlock_irqrestore(&capiminors_lock, flags); @@ -268,13 +285,10 @@ static void capiminor_free(struct capiminor *mp) kfree(mp); } -static struct capiminor *capiminor_find(unsigned int minor) +static struct capiminor *capiminor_get(unsigned int minor) { struct capiminor *mp; - if (minor >= capi_ttyminors) - return NULL; - read_lock(&capiminors_lock); mp = capiminors[minor]; read_unlock(&capiminors_lock); @@ -981,8 +995,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file) struct capiminor *mp; unsigned long flags; - if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == NULL) - return -ENXIO; + mp = capiminor_get(iminor(file->f_path.dentry->d_inode)); if (mp->nccip == NULL) return -ENXIO; @@ -1284,8 +1297,6 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) #endif } -static struct tty_driver *capinc_tty_driver; - static const struct tty_operations capinc_ops = { .open = capinc_tty_open, .close = capinc_tty_close, @@ -1339,7 +1350,9 @@ static int __init capinc_tty_init(void) drv->init_termios.c_oflag = OPOST | ONLCR; drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; drv->init_termios.c_lflag = 0; - drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS; + drv->flags = + TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | + TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(drv, &capinc_ops); err = tty_register_driver(drv);