Skip to content

Commit

Permalink
CAPI: Dynamically register minor devices
Browse files Browse the repository at this point in the history
Register capiminors dynamically with the TTY core so that udev can make
them show up as the NCCIs appear or disappear. This removes the need to
check if the capiminor requested in capinc_tty_open actually exists.

And this completely obsoletes capifs which will be scheduled for removal
in a later patch.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jan Kiszka authored and David S. Miller committed Feb 17, 2010
1 parent e76b154 commit 40fb2d0
Showing 1 changed file with 24 additions and 11 deletions.
35 changes: 24 additions & 11 deletions drivers/isdn/capi/capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 40fb2d0

Please sign in to comment.