From: Pavel Pisa Date: Mon, 29 Jul 2019 17:21:50 +0000 (+0200) Subject: sllin: register the second line discipline to distinguish request for slave configura... X-Git-Url: http://rtime.felk.cvut.cz/gitweb/linux-lin.git/commitdiff_plain/b56f1ea7a09bf50fc5f115a0c2e148e17d9e4799 sllin: register the second line discipline to distinguish request for slave configuration. This allows to combining master and slave devices on single computer/system. Signed-off-by: Pavel Pisa --- diff --git a/sllin/sllin.c b/sllin/sllin.c index ff9b0fe..cdc4327 100644 --- a/sllin/sllin.c +++ b/sllin/sllin.c @@ -72,6 +72,7 @@ /* Should be in include/linux/tty.h */ #define N_SLLIN 25 +#define N_SLLIN_SLAVE 26 /* -------------------------------- */ #ifdef SLLIN_LED_TRIGGER @@ -1597,7 +1598,7 @@ static struct sllin *sll_alloc(dev_t line) * Called in process context serialized from other ldisc calls. */ -static int sllin_open(struct tty_struct *tty) +static int sllin_open_common(struct tty_struct *tty, bool setup_master) { struct sllin *sl; int err; @@ -1638,8 +1639,8 @@ static int sllin_open(struct tty_struct *tty) if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLLIN initialization. */ - sl->lin_master = master; - if (master) + sl->lin_master = setup_master; + if (sl->lin_master) pr_debug("sllin: Configured as MASTER\n"); else pr_debug("sllin: Configured as SLAVE\n"); @@ -1704,6 +1705,43 @@ err_exit: return err; } +/* + * Open the high-level part of the SLLIN channel. + * This function is called by the TTY module when the + * SLLIN line discipline is called for. Because we are + * sure the tty line exists, we only have to link it to + * a free SLLIN channel... + * + * Called in process context serialized from other ldisc calls. + * + * This call variant preserves original functionality where + * slave/master can be selected by module parameter. + * Default is the master. + */ + +static int sllin_open(struct tty_struct *tty) +{ + return sllin_open_common(tty, master); +} + +/* + * Open the high-level part of the SLLIN channel. + * This function is called by the TTY module when the + * SLLIN line discipline is called for. Because we are + * sure the tty line exists, we only have to link it to + * a free SLLIN channel... + * + * Called in process context serialized from other ldisc calls. + * + * This call variant enforces slave/LIN device functionality. + */ + +static int sllin_open_slave(struct tty_struct *tty) +{ + return sllin_open_common(tty, false); +} + + /* * Close down a SLLIN channel. * This means flushing out any pending queues, and then returning. This @@ -1775,6 +1813,18 @@ static struct tty_ldisc_ops sll_ldisc = { .write_wakeup = sllin_write_wakeup, }; +static struct tty_ldisc_ops sll_slave_ldisc = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "sllin-slave", + .open = sllin_open_slave, + .close = sllin_close, + .hangup = sllin_hangup, + .ioctl = sllin_ioctl, + .receive_buf = sllin_receive_buf, + .write_wakeup = sllin_write_wakeup, +}; + static int __init sllin_init(void) { int status; @@ -1802,8 +1852,16 @@ static int __init sllin_init(void) if (status) { pr_err("sllin: can't register line discipline\n"); kfree(sllin_devs); + } else { + status = tty_register_ldisc(N_SLLIN_SLAVE, &sll_slave_ldisc); + if (status) { + tty_unregister_ldisc(N_SLLIN); + pr_err("sllin: can't register slave line discipline\n"); + kfree(sllin_devs); + } } + if (break_by_baud) pr_debug("sllin: Break is generated by baud-rate change."); else @@ -1874,6 +1932,11 @@ static void __exit sllin_exit(void) if (i) pr_err("sllin: can't unregister ldisc (err %d)\n", i); + i = tty_unregister_ldisc(N_SLLIN_SLAVE); + if (i) + pr_err("sllin: can't unregister slave ldisc (err %d)\n", i); + + #ifdef SLLIN_LED_TRIGGER unregister_netdevice_notifier(&sllin_netdev_notifier); #endif