Patch from Max Krasnyansky This changeset adds module refcounting for TTY line disciplines. I've sent the patch to LKM earlier. No negative comments (actually most people didn't seem to care). This is needed at least for Bluetooth and IrDA (Jean is ok with the patch). char/tty_io.c | 16 ++++++++++++++++ linux/tty_ldisc.h | 3 +++ 2 files changed, 19 insertions(+) diff -puN drivers/char/tty_io.c~tty-module-refcounting drivers/char/tty_io.c --- 25/drivers/char/tty_io.c~tty-module-refcounting 2003-02-14 19:09:27.000000000 -0800 +++ 25-akpm/drivers/char/tty_io.c 2003-02-14 19:09:27.000000000 -0800 @@ -289,6 +289,10 @@ static int tty_set_ldisc(struct tty_stru if (tty->ldisc.num == ldisc) return 0; /* We are already in the desired discipline */ + + if (!try_module_get(ldiscs[ldisc].owner)) + return -EINVAL; + o_ldisc = tty->ldisc; tty_wait_until_sent(tty, 0); @@ -303,9 +307,13 @@ static int tty_set_ldisc(struct tty_stru if (tty->ldisc.open) retval = (tty->ldisc.open)(tty); if (retval < 0) { + module_put(tty->ldisc.owner); + tty->ldisc = o_ldisc; tty->termios->c_line = tty->ldisc.num; if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { + module_put(tty->ldisc.owner); + tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (tty->ldisc.open) { @@ -317,7 +325,10 @@ static int tty_set_ldisc(struct tty_stru tty_name(tty, buf), r); } } + } else { + module_put(o_ldisc.owner); } + if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc) tty->driver.set_ldisc(tty); return retval; @@ -493,6 +504,8 @@ void do_tty_hangup(void *data) if (tty->ldisc.num != ldiscs[N_TTY].num) { if (tty->ldisc.close) (tty->ldisc.close)(tty); + module_put(tty->ldisc.owner); + tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (tty->ldisc.open) { @@ -1271,11 +1284,14 @@ static void release_dev(struct file * fi */ if (tty->ldisc.close) (tty->ldisc.close)(tty); + module_put(tty->ldisc.owner); + tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (o_tty) { if (o_tty->ldisc.close) (o_tty->ldisc.close)(o_tty); + module_put(o_tty->ldisc.owner); o_tty->ldisc = ldiscs[N_TTY]; } diff -puN include/linux/tty_ldisc.h~tty-module-refcounting include/linux/tty_ldisc.h --- 25/include/linux/tty_ldisc.h~tty-module-refcounting 2003-02-14 19:09:27.000000000 -0800 +++ 25-akpm/include/linux/tty_ldisc.h 2003-02-14 19:09:27.000000000 -0800 @@ -105,6 +105,7 @@ struct tty_ldisc { char *name; int num; int flags; + /* * The following routines are called from above. */ @@ -129,6 +130,8 @@ struct tty_ldisc { char *fp, int count); int (*receive_room)(struct tty_struct *); void (*write_wakeup)(struct tty_struct *); + + struct module *owner; }; #define TTY_LDISC_MAGIC 0x5403 _