# HG changeset patch # User Florian Pose # Date 1265116252 -3600 # Node ID 5bf740cd1599a5b86c970bda9a81a9e16e00c2d9 # Parent 3bb9ca8b58f244115373500292202fe0f5418e1c Allow multiple open() calls to tty devices. diff -r 3bb9ca8b58f2 -r 5bf740cd1599 tty/module.c --- a/tty/module.c Tue Jan 26 16:43:08 2010 +0100 +++ b/tty/module.c Tue Feb 02 14:10:52 2010 +0100 @@ -109,6 +109,8 @@ struct timer_list timer; struct tty_struct *tty; + unsigned int open_count; + struct semaphore sem; ec_tty_operations_t ops; void *cb_data; @@ -198,6 +200,8 @@ t->rx_write_idx = 0; init_timer(&t->timer); t->tty = NULL; + t->open_count = 0; + init_MUTEX(&t->sem); t->ops = *ops; t->cb_data = cb_data; @@ -366,24 +370,29 @@ int line = tty->index; #if EC_TTY_DEBUG >= 1 - printk(KERN_INFO PFX "Opening line %i.\n", line); + printk(KERN_INFO PFX "%s(tty=%p, file=%p): Opening line %i.\n", + __func__, tty, file, line); #endif if (line < 0 || line >= EC_TTY_MAX_DEVICES) { + tty->driver_data = NULL; return -ENXIO; } t = ttys[line]; if (!t) { + tty->driver_data = NULL; return -ENXIO; } - if (t->tty) { - return -EBUSY; - } - - t->tty = tty; - tty->driver_data = t; + if (!t->tty) { + t->tty = tty; + tty->driver_data = t; + } + + down(&t->sem); + t->open_count++; + up(&t->sem); return 0; } @@ -394,11 +403,16 @@ ec_tty_t *t = (ec_tty_t *) tty->driver_data; #if EC_TTY_DEBUG >= 1 - printk(KERN_INFO PFX "Closing line %i.\n", tty->index); -#endif - - if (t->tty == tty) { - t->tty = NULL; + printk(KERN_INFO PFX "%s(tty=%p, file=%p): Closing line %i.\n", + __func__, tty, file, tty->index); +#endif + + if (t) { + down(&t->sem); + if (--t->open_count == 0) { + t->tty = NULL; + } + up(&t->sem); } }