diff --git a/sys/arch/pmax/dev/rcons.c b/sys/arch/pmax/dev/rcons.c index 922e60fa4b89..93adcfd2d5b1 100644 --- a/sys/arch/pmax/dev/rcons.c +++ b/sys/arch/pmax/dev/rcons.c @@ -1,4 +1,4 @@ -/* $NetBSD: rcons.c,v 1.61 2005/09/06 21:40:38 kleink Exp $ */ +/* $NetBSD: rcons.c,v 1.62 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 1995 @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rcons.c,v 1.61 2005/09/06 21:40:38 kleink Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rcons.c,v 1.62 2005/11/27 05:35:52 thorpej Exp $"); #include "rasterconsole.h" #if NRASTERCONSOLE > 0 @@ -282,7 +282,7 @@ rasterconsoleattach (n) /* output queue doesn't need quoting */ clalloc(&tp->t_outq, 1024, 0); /* Set default line discipline. */ - tp->t_linesw = linesw[0]; + tp->t_linesw = ttyldisc_default(); #ifdef DEBUG printf("rconsattach: %d raster consoles\n", n); #endif diff --git a/sys/compat/common/tty_43.c b/sys/compat/common/tty_43.c index 08f12652636a..5d573340fbed 100644 --- a/sys/compat/common/tty_43.c +++ b/sys/compat/common/tty_43.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty_43.c,v 1.18 2004/04/25 06:23:40 matt Exp $ */ +/* $NetBSD: tty_43.c,v 1.19 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty_43.c,v 1.18 2004/04/25 06:23:40 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty_43.c,v 1.19 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -225,7 +225,8 @@ ttcompat(tp, com, data, flag, p) break; case OTIOCGETD: - *(int *)data = (tp->t_linesw != NULL) ? tp->t_linesw->l_no : 2; + *(int *)data = (tp->t_linesw == NULL) ? + 2 /* XXX old NTTYDISC */ : tp->t_linesw->l_no; break; case OTIOCSETD: { diff --git a/sys/dev/hpc/biconsdev.c b/sys/dev/hpc/biconsdev.c index afaec29834ab..2bba0353cb19 100644 --- a/sys/dev/hpc/biconsdev.c +++ b/sys/dev/hpc/biconsdev.c @@ -1,4 +1,4 @@ -/* $NetBSD: biconsdev.c,v 1.11 2005/09/06 21:40:39 kleink Exp $ */ +/* $NetBSD: biconsdev.c,v 1.12 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1999-2001 @@ -67,7 +67,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: biconsdev.c,v 1.11 2005/09/06 21:40:39 kleink Exp $"); +__KERNEL_RCSID(0, "$NetBSD: biconsdev.c,v 1.12 2005/11/27 05:35:52 thorpej Exp $"); #include "biconsdev.h" #include @@ -115,7 +115,7 @@ biconsdevattach(int n) /* output queue doesn't need quoting */ clalloc(&tp->t_outq, 1024, 0); /* Set default line discipline. */ - tp->t_linesw = linesw[0]; + tp->t_linesw = ttyldisc_default(); tp->t_dev = makedev(maj, 0); diff --git a/sys/dev/hpc/hpf1275a_tty.c b/sys/dev/hpc/hpf1275a_tty.c index 56befa40b9f7..c6378f5b3415 100644 --- a/sys/dev/hpc/hpf1275a_tty.c +++ b/sys/dev/hpc/hpf1275a_tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: hpf1275a_tty.c,v 1.2 2004/10/15 04:38:37 thorpej Exp $ */ +/* $NetBSD: hpf1275a_tty.c,v 1.3 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 2004 Valeriy E. Ushakov @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: hpf1275a_tty.c,v 1.2 2004/10/15 04:38:37 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hpf1275a_tty.c,v 1.3 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -90,9 +90,16 @@ CFATTACH_DECL(hpf1275a, sizeof(struct hpf1275a_softc), static struct linesw hpf1275a_disc = { - "hpf1275a", -1, hpf1275a_open, hpf1275a_close, - ttyerrio, ttyerrio, ttynullioctl, - hpf1275a_input, ttstart, nullmodem, ttpoll, + .l_name = "hpf1275a", + .l_open = hpf1275a_open, + .l_close = hpf1275a_close, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = ttynullioctl, + .l_rint = hpf1275a_input, + .l_start = ttstart, + .l_modem = nullmodem, + .l_poll = ttpoll }; @@ -206,13 +213,12 @@ static uint8_t hpf1275a_to_xtscan[128] = { void hpf1275aattach(int n) { - int discno; int error; - discno = ttyldisc_add(&hpf1275a_disc, -1); - if (discno < 0) { - printf("%s: unable to register line discipline\n", - hpf1275a_cd.cd_name); + error = ttyldisc_attach(&hpf1275a_disc); + if (error) { + printf("%s: unable to register line discipline, error = %d\n", + hpf1275a_cd.cd_name, error); return; } @@ -221,7 +227,7 @@ hpf1275aattach(int n) printf("%s: unable to register cfattach, error = %d\n", hpf1275a_cd.cd_name, error); config_cfdriver_detach(&hpf1275a_cd); - ttyldisc_remove(hpf1275a_disc.l_name); + (void) ttyldisc_detach(hpf1275a_disc.l_name); } } @@ -324,7 +330,8 @@ hpf1275a_close(struct tty *tp, int flag) s = spltty(); ttyflush(tp, FREAD | FWRITE); - tp->t_linesw = linesw[0]; /* default line discipline */ + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_default(); if (sc != NULL) { tp->t_sc = NULL; if (sc->sc_tp == tp) diff --git a/sys/dev/ir/irframe_tty.c b/sys/dev/ir/irframe_tty.c index a01747b18e87..f5bf1f1259de 100644 --- a/sys/dev/ir/irframe_tty.c +++ b/sys/dev/ir/irframe_tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: irframe_tty.c,v 1.29 2005/05/29 22:15:25 christos Exp $ */ +/* $NetBSD: irframe_tty.c,v 1.30 2005/11/27 05:35:52 thorpej Exp $ */ /* * TODO @@ -48,7 +48,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: irframe_tty.c,v 1.29 2005/05/29 22:15:25 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irframe_tty.c,v 1.30 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -191,9 +191,24 @@ static const struct dongle { { irts_girbil, IRDA_SPEEDS_SIR, IRDA_TURNT_10000 | IRDA_TURNT_5000 }, }; +static struct linesw irframet_disc = { + .l_name = "irframe", + .l_open = irframetopen, + .l_close = irframetclose, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = irframetioctl, + .l_rint = irframetinput, + .l_start = irframetstart, + .l_modem = ttymodem, + .l_poll = ttyerrpoll +}; + void irframettyattach(int n) { + + (void) ttyldisc_attach(&irframet_disc); } /* @@ -218,7 +233,7 @@ irframetopen(dev_t dev, struct tty *tp) DPRINTF(("%s: linesw=%p disc=%s\n", __FUNCTION__, tp->t_linesw, tp->t_linesw->l_name)); - if (strcmp(tp->t_linesw->l_name, "irframe") == 0) { /* XXX */ + if (tp->t_linesw == &irframet_disc) { sc = (struct irframet_softc *)tp->t_sc; DPRINTF(("%s: sc=%p sc_tp=%p\n", __FUNCTION__, sc, sc->sc_tp)); if (sc != NULL) { @@ -262,7 +277,8 @@ irframetclose(struct tty *tp, int flag) s = spltty(); ttyflush(tp, FREAD | FWRITE); - tp->t_linesw = linesw[0]; /* default line discipline */ + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_default(); if (sc != NULL) { tp->t_sc = NULL; printf("%s detached from tty%02d\n", sc->sc_irp.sc_dev.dv_xname, diff --git a/sys/dev/sun/sunkbd.c b/sys/dev/sun/sunkbd.c index bfb88c97423a..42954d1c5a94 100644 --- a/sys/dev/sun/sunkbd.c +++ b/sys/dev/sun/sunkbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: sunkbd.c,v 1.21 2005/02/21 22:43:07 heas Exp $ */ +/* $NetBSD: sunkbd.c,v 1.22 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 1992, 1993 @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.21 2005/02/21 22:43:07 heas Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.22 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -99,9 +99,18 @@ int sunkbd_bps = KBD_DEFAULT_BPS; CFATTACH_DECL(kbd_tty, sizeof(struct kbd_sun_softc), sunkbd_match, sunkbd_attach, NULL, NULL); -struct linesw sunkbd_disc = - { "sunkbd", -1, ttylopen, ttylclose, ttyerrio, ttyerrio, ttynullioctl, - sunkbdinput, sunkbdstart, nullmodem, ttpoll }; +struct linesw sunkbd_disc = { + .l_name = "sunkbd", + .l_open = ttylopen, + .l_close = ttylclose, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = ttynullioctl, + .l_rint = sunkbdinput, + .l_start = sunkbdstart, + .l_modem = nullmodem, + .l_poll = ttpoll +}; /* @@ -132,10 +141,11 @@ sunkbd_attach(parent, self, aux) struct cons_channel *cc; /* Set up the proper line discipline. */ - ttyldisc_init(); - if (ttyldisc_add(&sunkbd_disc, -1) == -1) + if (ttyldisc_attach(&sunkbd_disc) != 0) panic("sunkbd_attach: sunkbd_disc"); - tp->t_linesw = &sunkbd_disc; + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_lookup(sunkbd_disc.l_name); + KASSERT(tp->t_linesw == &sunkbd_disc); tp->t_oflag &= ~OPOST; tp->t_dev = args->kmta_dev; diff --git a/sys/dev/sun/sunms.c b/sys/dev/sun/sunms.c index 1ba3a251ff60..d0ee48373fb8 100644 --- a/sys/dev/sun/sunms.c +++ b/sys/dev/sun/sunms.c @@ -1,4 +1,4 @@ -/* $NetBSD: sunms.c,v 1.19 2005/02/27 00:27:49 perry Exp $ */ +/* $NetBSD: sunms.c,v 1.20 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 1992, 1993 @@ -52,7 +52,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sunms.c,v 1.19 2005/02/27 00:27:49 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunms.c,v 1.20 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -97,9 +97,18 @@ int sunmsinput(int, struct tty *); CFATTACH_DECL(ms_tty, sizeof(struct ms_softc), sunms_match, sunms_attach, NULL, NULL); -struct linesw sunms_disc = - { "sunms", -1, ttylopen, ttylclose, ttyerrio, ttyerrio, ttynullioctl, - sunmsinput, ttstart, nullmodem, ttpoll }; +struct linesw sunms_disc = { + .l_name = "sunms", + .l_open = ttylopen, + .l_close = ttylclose, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = ttynullioctl, + .l_rint = sunmsinput, + .l_start = ttstart, + .l_modem = nullmodem, + .l_poll = ttpoll +}; int sunms_enable(void *); int sunms_ioctl(void *, u_long, caddr_t, int, struct proc *); @@ -157,9 +166,11 @@ sunms_attach(parent, self, aux) printf("\n"); /* Initialize the speed, etc. */ - if (ttyldisc_add(&sunms_disc, -1) == -1) + if (ttyldisc_attach(&sunms_disc) != 0) panic("sunms_attach: sunms_disc"); - tp->t_linesw = &sunms_disc; + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_lookup(sunms_disc.l_name); + KASSERT(tp->t_linesw == &sunms_disc); tp->t_oflag &= ~OPOST; /* Initialize translator. */ diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index d86e59a2c04f..95f3ebf36e55 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.258 2005/11/25 20:32:32 thorpej Exp $ */ +/* $NetBSD: init_main.c,v 1.259 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.258 2005/11/25 20:32:32 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.259 2005/11/27 05:35:52 thorpej Exp $"); #include "opt_ipsec.h" #include "opt_sysv.h" @@ -254,7 +254,6 @@ main(void) * The following things must be done before autoconfiguration. */ evcnt_init(); /* initialize event counters */ - tty_init(); /* initialize tty list */ #if NRND > 0 rnd_init(); /* initialize RNG */ #endif diff --git a/sys/kern/tty.c b/sys/kern/tty.c index a87eae987778..b2cab2252729 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.176 2005/10/13 16:18:43 christos Exp $ */ +/* $NetBSD: tty.c,v 1.177 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1991, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.176 2005/10/13 16:18:43 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.177 2005/11/27 05:35:52 thorpej Exp $"); #include #include @@ -945,10 +945,10 @@ ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) memcpy(t, &tp->t_termios, sizeof(struct termios)); break; } - case TIOCGETD: /* get line discipline */ + case TIOCGETD: /* get line discipline (old) */ *(int *)data = tp->t_linesw->l_no; break; - case TIOCGLINED: + case TIOCGLINED: /* get line discipline (new) */ (void)strncpy((char *)data, tp->t_linesw->l_name, TTLINEDNAMELEN - 1); break; @@ -1067,24 +1067,17 @@ ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) splx(s); break; } - case TIOCSETD: { /* set line discipline */ - int t = *(int *)data; - - if (t < 0) - return (EINVAL); - if (t >= nlinesw) - return (ENXIO); - lp = linesw[t]; + case TIOCSETD: /* set line discipline (old) */ + lp = ttyldisc_lookup_bynum(*(int *)data); goto setldisc; - } - case TIOCSLINED: { /* set line discipline */ + + case TIOCSLINED: { /* set line discipline (new) */ char *name = (char *)data; dev_t device; /* Null terminate to prevent buffer overflow */ name[TTLINEDNAMELEN - 1] = '\0'; lp = ttyldisc_lookup(name); - setldisc: if (lp == NULL) return (ENXIO); @@ -1097,10 +1090,15 @@ ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) if (error) { (void)(*tp->t_linesw->l_open)(device, tp); splx(s); + ttyldisc_release(lp); return (error); } + ttyldisc_release(tp->t_linesw); tp->t_linesw = lp; splx(s); + } else { + /* Drop extra reference. */ + ttyldisc_release(lp); } break; } @@ -2507,16 +2505,6 @@ ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo) return (tp->t_gen == gen ? 0 : ERESTART); } -/* - * Initialise the global tty list. - */ -void -tty_init(void) -{ - - ttyldisc_init(); -} - /* * Attach a tty to the tty list. * @@ -2574,7 +2562,7 @@ ttymalloc(void) /* output queue doesn't need quoting */ clalloc(&tp->t_outq, 1024, 0); /* Set default line discipline. */ - tp->t_linesw = linesw[0]; + tp->t_linesw = ttyldisc_default(); return (tp); } @@ -2589,6 +2577,7 @@ ttyfree(struct tty *tp) { callout_stop(&tp->t_rstrt_ch); + ttyldisc_release(tp->t_linesw); clfree(&tp->t_rawq); clfree(&tp->t_canq); clfree(&tp->t_outq); diff --git a/sys/kern/tty_conf.c b/sys/kern/tty_conf.c index b931987a411a..a20498b84d16 100644 --- a/sys/kern/tty_conf.c +++ b/sys/kern/tty_conf.c @@ -1,4 +1,40 @@ -/* $NetBSD: tty_conf.c,v 1.47 2005/06/21 14:01:13 ws Exp $ */ +/* $NetBSD: tty_conf.c,v 1.48 2005/11/27 05:35:52 thorpej Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -37,126 +73,79 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty_conf.c,v 1.47 2005/06/21 14:01:13 ws Exp $"); - -#include "opt_compat_freebsd.h" -#include "opt_compat_43.h" +__KERNEL_RCSID(0, "$NetBSD: tty_conf.c,v 1.48 2005/11/27 05:35:52 thorpej Exp $"); #include #include -#include -#include #include #include #include -#include #include #include -#include +#include +#include +#include -#include "tb.h" -#if NTB > 0 -int tbopen(dev_t dev, struct tty *tp); -int tbclose(struct tty *tp, int flags); -int tbread(struct tty *tp, struct uio *uio, int flags); -int tbtioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct proc *p); -int tbinput(int c, struct tty *tp); -#endif - -#include "sl.h" -#if NSL > 0 -int slopen(dev_t dev, struct tty *tp); -int slclose(struct tty *tp, int flags); -int sltioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct proc *p); -int slinput(int c, struct tty *tp); -int slstart(struct tty *tp); -#endif - -#include "ppp.h" -#if NPPP > 0 -int pppopen(dev_t dev, struct tty *tp); -int pppclose(struct tty *tp, int flags); -int ppptioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct proc *p); -int pppinput(int c, struct tty *tp); -int pppstart(struct tty *tp); -int pppread(struct tty *tp, struct uio *uio, int flag); -int pppwrite(struct tty *tp, struct uio *uio, int flag); -#endif - -#include "strip.h" -#if NSTRIP > 0 -int stripopen(dev_t dev, struct tty *tp); -int stripclose(struct tty *tp, int flags); -int striptioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct proc *p); -int stripinput(int c, struct tty *tp); -int stripstart(struct tty *tp); -#endif - -#include "irframetty.h" -#if NIRFRAMETTY > 0 -int irframetopen(dev_t dev, struct tty *tp); -int irframetclose(struct tty *tp, int flags); -int irframetioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct proc *p); -int irframetinput(int c, struct tty *tp); -int irframetstart(struct tty *tp); -int irframetread(struct tty *tp, struct uio *uio, int flag); -int irframetwrite(struct tty *tp, struct uio *uio, int flag); -int irframetpoll(struct tty *tp, int events, struct proc *p); -#endif - - -struct linesw termios_disc = - { "termios", TTYDISC, ttylopen, ttylclose, ttread, ttwrite, - ttynullioctl, ttyinput, ttstart, ttymodem, ttpoll }; /* 0- termios */ -struct linesw defunct_disc = - { "defunct", 1, ttynodisc, ttyerrclose, ttyerrio, ttyerrio, - ttynullioctl, ttyerrinput, ttyerrstart, nullmodem, ttyerrpoll }; /* 1- defunct */ -#if defined(COMPAT_43) || defined(COMPAT_FREEBSD) -struct linesw ntty_disc = - { "ntty", 2, ttylopen, ttylclose, ttread, ttwrite, ttynullioctl, - ttyinput, ttstart, ttymodem, ttpoll }; /* 2- old NTTYDISC */ -#endif -#if NTB > 0 -struct linesw table_disc = - { "tablet", TABLDISC, tbopen, tbclose, tbread, ttyerrio, tbtioctl, - tbinput, ttstart, nullmodem, ttyerrpoll }; /* 3- TABLDISC */ -#endif -#if NSL > 0 -struct linesw slip_disc = - { "slip", SLIPDISC, slopen, slclose, ttyerrio, ttyerrio, sltioctl, - slinput, slstart, nullmodem, ttyerrpoll }; /* 4- SLIPDISC */ -#endif -#if NPPP > 0 -struct linesw ppp_disc = - { "ppp", PPPDISC, pppopen, pppclose, pppread, pppwrite, ppptioctl, - pppinput, pppstart, ttymodem, ttpoll }; /* 5- PPPDISC */ -#endif -#if NSTRIP > 0 -struct linesw strip_disc = - { "strip", STRIPDISC, stripopen, stripclose, ttyerrio, ttyerrio, - striptioctl, stripinput, stripstart, nullmodem, ttyerrpoll }; - /* 6- STRIPDISC */ -#endif -#if NIRFRAMETTY > 0 -struct linesw irframet_disc = - { "irframe", -1, irframetopen, irframetclose, ttyerrio, - ttyerrio, irframetioctl, irframetinput, irframetstart, - ttymodem, ttyerrpoll }; /* irframe */ -#endif +static struct linesw termios_disc = { + .l_name = "termios", + .l_open = ttylopen, + .l_close = ttylclose, + .l_read = ttread, + .l_write = ttwrite, + .l_ioctl = ttynullioctl, + .l_rint = ttyinput, + .l_start = ttstart, + .l_modem = ttymodem, + .l_poll = ttpoll +}; /* - * Registered line disciplines. Don't use this - * it will go away. + * This is for the benefit of old BSD TTY compatbility, but since it is + * identical to termios (except for the name), don't bother conditionalizing + * it. */ -#define LSWITCHBRK 20 -struct linesw **linesw = NULL; -int nlinesw = 0; -int slinesw = 0; +static struct linesw ntty_disc = { /* old NTTYDISC */ + .l_name = "ntty", + .l_open = ttylopen, + .l_close = ttylclose, + .l_read = ttread, + .l_write = ttwrite, + .l_ioctl = ttynullioctl, + .l_rint = ttyinput, + .l_start = ttstart, + .l_modem = ttymodem, + .l_poll = ttpoll +}; + +static LIST_HEAD(, linesw) ttyldisc_list = LIST_HEAD_INITIALIZER(ttyldisc_head); +static struct simplelock ttyldisc_list_slock = SIMPLELOCK_INITIALIZER; + +/* + * Note: We don't bother refcounting termios_disc and ntty_disc; they can't + * be removed from the list, and termios_disc is likely to have very many + * references (could we overflow the count?). + */ +#define TTYLDISC_ISSTATIC(disc) \ + ((disc) == &termios_disc || (disc) == &ntty_disc) + +#define TTYLDISC_HOLD(disc) \ +do { \ + if (! TTYLDISC_ISSTATIC(disc)) { \ + KASSERT((disc)->l_refcnt != UINT_MAX); \ + (disc)->l_refcnt++; \ + } \ +} while (/*CONSTCOND*/0) + +#define TTYLDISC_RELE(disc) \ +do { \ + if (! TTYLDISC_ISSTATIC(disc)) { \ + KASSERT((disc)->l_refcnt != 0); \ + (disc)->l_refcnt--; \ + } \ +} while (/*CONSTCOND*/0) + +#define TTYLDISC_ISINUSE(disc) \ + (TTYLDISC_ISSTATIC(disc) || (disc)->l_refcnt != 0) /* * Do nothing specific version of line @@ -164,12 +153,7 @@ int slinesw = 0; */ /*ARGSUSED*/ int -ttynullioctl(tp, cmd, data, flags, p) - struct tty *tp; - u_long cmd; - char *data; - int flags; - struct proc *p; +ttynullioctl(struct tty *tp, u_long cmd, char *data, int flags, struct proc *p) { #ifdef lint @@ -184,10 +168,7 @@ ttynullioctl(tp, cmd, data, flags, p) */ /*ARGSUSED*/ int -ttyerrpoll(tp, events, p) - struct tty *tp; - int events; - struct proc *p; +ttyerrpoll(struct tty *tp, int events, struct proc *p) { #ifdef lint @@ -196,158 +177,202 @@ ttyerrpoll(tp, events, p) return (POLLERR); } -/* - * Register a line discipline, optionally providing a - * specific discipline number for compatibility, -1 allocates - * a new one. Returns a discipline number, or -1 on - * failure. - */ -int -ttyldisc_add(disc, no) - struct linesw *disc; - int no; +static ONCE_DECL(ttyldisc_init_once); + +static void +ttyldisc_init(void) { - /* You are not allowed to exceed TTLINEDNAMELEN */ - if (strlen(disc->l_name) >= TTLINEDNAMELEN) - return (-1); + if (ttyldisc_attach(&termios_disc) != 0) + panic("ttyldisc_init: termios_disc"); + if (ttyldisc_attach(&ntty_disc) != 0) + panic("ttyldisc_init: ntty_disc"); +} - /* - * You are not allowed to specify a line switch - * compatibility number greater than 10. - */ - if (no > 10) - return (-1); +static struct linesw * +ttyldisc_lookup_locked(const char *name) +{ + struct linesw *disc; - if (linesw == NULL) - panic("adding uninitialized linesw"); - -#ifdef DEBUG - /* - * XXX: For the benefit of LKMs - */ - if (disc->l_poll == NULL) - panic("line discipline must now provide l_poll() entry point"); -#endif - - if (no == -1) { - /* Hunt for any slot */ - - for (no = slinesw; no-- > 0;) - if (linesw[no] == NULL) - break; - /* if no == -1 we should realloc linesw, but for now... */ - if (no == -1) - return (-1); + LIST_FOREACH(disc, &ttyldisc_list, l_list) { + if (strcmp(name, disc->l_name) == 0) + return (disc); } - /* Need a specific slot */ - if (linesw[no] != NULL) - return (-1); - - linesw[no] = disc; - disc->l_no = no; - - /* Define size of table */ - if (no >= nlinesw) - nlinesw = no + 1; - - return (no); + return (NULL); } /* - * Remove a line discipline by its name. Returns the - * discipline on success or NULL on failure. + * Look up a line discipline by its name. Caller holds a reference on + * the returned line discipline. */ struct linesw * -ttyldisc_remove(name) - const char *name; +ttyldisc_lookup(const char *name) { struct linesw *disc; - int i; - if (linesw == NULL) - panic("removing uninitialized linesw"); + RUN_ONCE(&ttyldisc_init_once, ttyldisc_init); - for (i = 0; i < nlinesw; i++) { - if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0)) { - disc = linesw[i]; - linesw[i] = NULL; + simple_lock(&ttyldisc_list_slock); + disc = ttyldisc_lookup_locked(name); + if (disc != NULL) + TTYLDISC_HOLD(disc); + simple_unlock(&ttyldisc_list_slock); - if (nlinesw == i + 1) { - /* Need to fix up array sizing */ - while (i-- > 0 && linesw[i] == NULL) - continue; - nlinesw = i + 1; - } + return (disc); +} + +/* + * Look up a line discipline by its legacy number. Caller holds a + * reference on the returned line discipline. + */ +struct linesw * +ttyldisc_lookup_bynum(int num) +{ + struct linesw *disc; + + RUN_ONCE(&ttyldisc_init_once, ttyldisc_init); + + simple_lock(&ttyldisc_list_slock); + + LIST_FOREACH(disc, &ttyldisc_list, l_list) { + if (disc->l_no == num) { + TTYLDISC_HOLD(disc); + simple_unlock(&ttyldisc_list_slock); return (disc); } } + + simple_unlock(&ttyldisc_list_slock); return (NULL); } /* - * Look up a line discipline by its name. - */ -struct linesw * -ttyldisc_lookup(name) - const char *name; -{ - int i; - - for (i = 0; i < nlinesw; i++) - if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0)) - return (linesw[i]); - return (NULL); -} - -#define TTYLDISCINIT(s, v) \ - do { \ - if (ttyldisc_add(&(s), (v)) != (v)) \ - panic("ttyldisc_init: " __STRING(s)); \ - } while (/*CONSTCOND*/ 0) - -/* - * Register the basic line disciplines. + * Release a reference on a line discipline previously added by + * ttyldisc_lookup() or ttyldisc_lookup_bynum(). */ void -ttyldisc_init() +ttyldisc_release(struct linesw *disc) { - /* Only initialize once */ - if (linesw) + if (disc == NULL) return; - slinesw = LSWITCHBRK; - linesw = malloc(slinesw * sizeof(struct linesw *), - M_TTYS, M_WAITOK); - memset(linesw, 0, slinesw * sizeof(struct linesw *)); - - TTYLDISCINIT(termios_disc, 0); - /* Do we really need this one? */ - TTYLDISCINIT(defunct_disc, 1); - - /* - * The following should really be moved to - * initialization code for each module. - */ - -#if defined(COMPAT_43) || defined(COMPAT_FREEBSD) - TTYLDISCINIT(ntty_disc, 2); -#endif -#if NTB > 0 - TTYLDISCINIT(table_disc, 3); -#endif -#if NSL > 0 - TTYLDISCINIT(slip_disc, 4); -#endif -#if NPPP > 0 - TTYLDISCINIT(ppp_disc, 5); -#endif -#if NSTRIP > 0 - TTYLDISCINIT(strip_disc, 6); -#endif -#if NIRFRAMETTY > 0 - ttyldisc_add(&irframet_disc, -1); -#endif + simple_lock(&ttyldisc_list_slock); + TTYLDISC_RELE(disc); + simple_unlock(&ttyldisc_list_slock); +} + +#define TTYLDISC_LEGACY_NUMBER_MIN 10 +#define TTYLDISC_LEGACY_NUMBER_MAX INT_MAX + +static void +ttyldisc_assign_legacy_number(struct linesw *disc) +{ + static const struct { + const char *name; + int num; + } table[] = { + { "termios", TTYDISC }, + { "ntty", 2 /* XXX old NTTYDISC */ }, + { "tablet", TABLDISC }, + { "slip", SLIPDISC }, + { "ppp", PPPDISC }, + { "strip", STRIPDISC }, + { "hdlc", HDLCDISC }, + { NULL, 0 } + }; + struct linesw *ldisc; + int i; + + for (i = 0; table[i].name != NULL; i++) { + if (strcmp(disc->l_name, table[i].name) == 0) { + disc->l_no = table[i].num; + return; + } + } + + disc->l_no = TTYLDISC_LEGACY_NUMBER_MIN; + + LIST_FOREACH(ldisc, &ttyldisc_list, l_list) { + if (disc->l_no == ldisc->l_no) { + KASSERT(disc->l_no < TTYLDISC_LEGACY_NUMBER_MAX); + disc->l_no++; + } + } +} + +/* + * Register a line discipline. + */ +int +ttyldisc_attach(struct linesw *disc) +{ + + KASSERT(disc->l_name != NULL); + KASSERT(disc->l_open != NULL); + KASSERT(disc->l_close != NULL); + KASSERT(disc->l_read != NULL); + KASSERT(disc->l_write != NULL); + KASSERT(disc->l_ioctl != NULL); + KASSERT(disc->l_rint != NULL); + KASSERT(disc->l_start != NULL); + KASSERT(disc->l_modem != NULL); + KASSERT(disc->l_poll != NULL); + + /* You are not allowed to exceed TTLINEDNAMELEN */ + if (strlen(disc->l_name) >= TTLINEDNAMELEN) + return (ENAMETOOLONG); + + simple_lock(&ttyldisc_list_slock); + + if (ttyldisc_lookup_locked(disc->l_name) != NULL) { + simple_unlock(&ttyldisc_list_slock); + return (EEXIST); + } + + ttyldisc_assign_legacy_number(disc); + LIST_INSERT_HEAD(&ttyldisc_list, disc, l_list); + + simple_unlock(&ttyldisc_list_slock); + + return (0); +} + +/* + * Remove a line discipline. + */ +int +ttyldisc_detach(struct linesw *disc) +{ +#ifdef DIAGNOSTIC + struct linesw *ldisc = ttyldisc_lookup(disc->l_name); + + KASSERT(ldisc != NULL); + KASSERT(ldisc == disc); + ttyldisc_release(ldisc); +#endif + + simple_lock(&ttyldisc_list_slock); + + if (TTYLDISC_ISINUSE(disc)) { + simple_unlock(&ttyldisc_list_slock); + return (EBUSY); + } + + LIST_REMOVE(disc, l_list); + + simple_unlock(&ttyldisc_list_slock); + + return (0); +} + +/* + * Return the default line discipline. + */ +struct linesw * +ttyldisc_default(void) +{ + + return (&termios_disc); } diff --git a/sys/kern/tty_tb.c b/sys/kern/tty_tb.c index 9d69da87e8ad..9023190fe944 100644 --- a/sys/kern/tty_tb.c +++ b/sys/kern/tty_tb.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty_tb.c,v 1.32 2005/05/29 22:24:15 christos Exp $ */ +/* $NetBSD: tty_tb.c,v 1.33 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty_tb.c,v 1.32 2005/05/29 22:24:15 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty_tb.c,v 1.33 2005/11/27 05:35:52 thorpej Exp $"); #include "tb.h" @@ -109,12 +109,25 @@ struct tb { int tbopen(dev_t, struct tty *); -void tbclose(struct tty *); -int tbread(struct tty *, struct uio *); -void tbinput(int, struct tty *); +int tbclose(struct tty *, int); +int tbread(struct tty *, struct uio *, int); +int tbinput(int, struct tty *); int tbtioctl(struct tty *, u_long, caddr_t, int, struct proc *); void tbattach(int); +static struct linesw tablet_disc = { + .l_name = "tablet", + .l_open = tbopen, + .l_close = tbclose, + .l_read = tbread, + .l_write = ttyerrio, + .l_ioctl = tbtioctl, + .l_rint = tbinput, + .l_start = ttstart, + .l_modem = nullmodem, + .l_poll = ttyerrpoll +}; + /* * Open as tablet discipline; called on discipline change. */ @@ -126,7 +139,7 @@ tbopen(dev, tp) { struct tb *tbp; - if (tp->t_linesw->l_no == TABLDISC) + if (tp->t_linesw == &tablet_disc) return (ENODEV); ttywflush(tp); for (tbp = tb; tbp < &tb[NTB]; tbp++) @@ -146,13 +159,14 @@ tbopen(dev, tp) /* * Line discipline change or last device close. */ -void -tbclose(tp) +int +tbclose(tp, flag) struct tty *tp; + int flag; { int modebits = TBPOINT|TBSTOP; - tbtioctl(tp, BIOSMODE, (caddr_t) &modebits, 0, curproc); + return (tbtioctl(tp, BIOSMODE, (caddr_t) &modebits, 0, curproc)); } /* @@ -160,9 +174,10 @@ tbclose(tp) * Characters have been buffered in a buffer and decoded. */ int -tbread(tp, uio) +tbread(tp, uio, flag) struct tty *tp; struct uio *uio; + int flag; { struct tb *tbp = (struct tb *)tp->t_sc; const struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE]; @@ -184,7 +199,7 @@ tbread(tp, uio) * This routine could be expanded in-line in the receiver * interrupt routine to make it run as fast as possible. */ -void +int tbinput(c, tp) int c; struct tty *tp; @@ -193,7 +208,7 @@ tbinput(c, tp) const struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE]; if (tc->tbc_recsize == 0 || tc->tbc_decode == 0) /* paranoid? */ - return; + return (0); /* * Locate sync bit/byte or reset input buffer. */ @@ -207,6 +222,8 @@ tbinput(c, tp) */ if (++tbp->tbinbuf == tc->tbc_recsize) (*tc->tbc_decode)(tc, tbp->cbuf, &tbp->tbpos); + + return (0); } /* @@ -401,5 +418,7 @@ void tbattach(dummy) int dummy; { - /* stub to handle side effect of new config */ + + if (ttyldisc_attach(&tablet_disc) != 0) + panic("tbattach"); } diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 90bb649a4bf9..2a389257a1ed 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ppp.c,v 1.101 2005/05/29 21:22:52 christos Exp $ */ +/* $NetBSD: if_ppp.c,v 1.102 2005/11/27 05:35:52 thorpej Exp $ */ /* Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp */ /* @@ -102,7 +102,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.101 2005/05/29 21:22:52 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.102 2005/11/27 05:35:52 thorpej Exp $"); #include "ppp.h" @@ -124,6 +124,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.101 2005/05/29 21:22:52 christos Exp $" #include #include #include +#include #include #include @@ -242,6 +243,10 @@ struct compressor *ppp_compressors[PPP_COMPRESSORS_MAX] = { void pppattach(void) { + extern struct linesw ppp_disc; + + if (ttyldisc_attach(&ppp_disc) != 0) + panic("pppattach"); LIST_INIT(&ppp_softc_list); if_clone_attach(&ppp_cloner); } diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 1a16e481f7da..26309859e062 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_sl.c,v 1.92 2005/08/18 00:30:58 yamt Exp $ */ +/* $NetBSD: if_sl.c,v 1.93 2005/11/27 05:35:52 thorpej Exp $ */ /* * Copyright (c) 1987, 1989, 1992, 1993 @@ -60,7 +60,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.92 2005/08/18 00:30:58 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.93 2005/11/27 05:35:52 thorpej Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -192,9 +192,24 @@ void slintr(void *); static int slinit __P((struct sl_softc *)); static struct mbuf *sl_btom __P((struct sl_softc *, int)); +static struct linesw slip_disc = { + .l_name = "slip", + .l_open = slopen, + .l_close = slclose, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = sltioctl, + .l_rint = slinput, + .l_start = slstart, + .l_modem = nullmodem, + .l_poll = ttyerrpoll +}; + void slattach(void) { + if (ttyldisc_attach(&slip_disc) != 0) + panic("slattach"); LIST_INIT(&sl_softc_list); if_clone_attach(&sl_cloner); } @@ -284,7 +299,7 @@ slopen(dev, tp) if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) return (error); - if (tp->t_linesw->l_no == SLIPDISC) + if (tp->t_linesw == &slip_disc) return (0); LIST_FOREACH(sc, &sl_softc_list, sc_iflist) @@ -349,9 +364,10 @@ slopen(dev, tp) * Line specific close routine. * Detach the tty from the sl unit. */ -void -slclose(tp) +int +slclose(tp, flag) struct tty *tp; + int flag; { struct sl_softc *sc; int s; @@ -369,7 +385,8 @@ slclose(tp) splx(s); s = spltty(); - tp->t_linesw = linesw[0]; /* default line disc. */ + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_default(); tp->t_state = 0; sc->sc_ttyp = NULL; @@ -391,6 +408,8 @@ slclose(tp) } splx(s); } + + return (0); } /* @@ -399,11 +418,12 @@ slclose(tp) */ /* ARGSUSED */ int -sltioctl(tp, cmd, data, flag) +sltioctl(tp, cmd, data, flag, p) struct tty *tp; u_long cmd; caddr_t data; int flag; + struct proc *p; { struct sl_softc *sc = (struct sl_softc *)tp->t_sc; @@ -508,7 +528,7 @@ sloutput(ifp, m, dst, rtp) * to send from the interface queue and map it to * the interface before starting output. */ -void +int slstart(tp) struct tty *tp; { @@ -522,14 +542,14 @@ slstart(tp) if (tp->t_outq.c_cc != 0) { (*tp->t_oproc)(tp); if (tp->t_outq.c_cc > SLIP_HIWAT) - return; + return (0); } /* * This happens briefly when the line shuts down. */ if (sc == NULL) - return; + return (0); #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS softintr_schedule(sc->sc_si); #else @@ -539,6 +559,7 @@ slstart(tp) splx(s); } #endif + return (0); } /* @@ -579,7 +600,7 @@ sl_btom(sc, len) /* * tty interface receiver interrupt. */ -void +int slinput(c, tp) int c; struct tty *tp; @@ -591,11 +612,11 @@ slinput(c, tp) tk_nin++; sc = (struct sl_softc *)tp->t_sc; if (sc == NULL) - return; + return (0); if ((c & TTY_ERRORMASK) || ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)) { sc->sc_flags |= SC_ERROR; - return; + return (0); } c &= TTY_CHARMASK; @@ -618,8 +639,8 @@ slinput(c, tp) if (++sc->sc_abortcount == 1) sc->sc_starttime = time.tv_sec; if (sc->sc_abortcount >= ABT_COUNT) { - slclose(tp); - return; + slclose(tp, 0); + return (0); } } } else @@ -641,7 +662,7 @@ slinput(c, tp) case FRAME_ESCAPE: sc->sc_escape = 1; - return; + return (0); case FRAME_END: if(sc->sc_flags & SC_ERROR) { @@ -672,7 +693,7 @@ slinput(c, tp) if (sc->sc_mp < sc->sc_ep) { *sc->sc_mp++ = c; sc->sc_escape = 0; - return; + return (0); } /* can't put lower; would miss an extra frame */ @@ -684,6 +705,8 @@ newpack: sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf + BUFOFFSET; sc->sc_escape = 0; + + return (0); } #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS diff --git a/sys/net/if_slvar.h b/sys/net/if_slvar.h index 1daa62e32fe8..e9d832f38d9d 100644 --- a/sys/net/if_slvar.h +++ b/sys/net/if_slvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_slvar.h,v 1.27 2005/02/26 22:45:09 perry Exp $ */ +/* $NetBSD: if_slvar.h,v 1.28 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -81,14 +81,14 @@ struct sl_softc { #ifdef _KERNEL void slattach __P((void)); -void slclose __P((struct tty *)); -void slinput __P((int, struct tty *)); +int slclose __P((struct tty *, int)); +int slinput __P((int, struct tty *)); int slioctl __P((struct ifnet *, u_long, caddr_t)); int slopen __P((dev_t, struct tty *)); int sloutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); -void slstart __P((struct tty *)); -int sltioctl __P((struct tty *, u_long, caddr_t, int)); +int slstart __P((struct tty *)); +int sltioctl __P((struct tty *, u_long, caddr_t, int, struct proc *)); #endif /* _KERNEL */ #endif /* _NET_IF_SLVAR_H_ */ diff --git a/sys/net/if_strip.c b/sys/net/if_strip.c index c13835214d60..f0bc2de301dc 100644 --- a/sys/net/if_strip.c +++ b/sys/net/if_strip.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_strip.c,v 1.61 2005/08/18 00:30:58 yamt Exp $ */ +/* $NetBSD: if_strip.c,v 1.62 2005/11/27 05:35:52 thorpej Exp $ */ /* from: NetBSD: if_sl.c,v 1.38 1996/02/13 22:00:23 christos Exp $ */ /* @@ -87,7 +87,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.61 2005/08/18 00:30:58 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.62 2005/11/27 05:35:52 thorpej Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -330,11 +330,24 @@ void strip_timeout __P((void *x)); #define RADIO_PROBE_TIMEOUT(sc) \ ((sc)-> sc_statetimo > time.tv_sec) - +static struct linesw strip_disc = { + .l_name = "strip", + .l_open = stripopen, + .l_close = stripclose, + .l_read = ttyerrio, + .l_write = ttyerrio, + .l_ioctl = striptioctl, + .l_rint = stripinput, + .l_start = stripstart, + .l_modem = nullmodem, + .l_poll = ttyerrpoll +}; void stripattach(void) { + if (ttyldisc_attach(&strip_disc) != 0) + panic("stripattach"); LIST_INIT(&strip_softc_list); if_clone_attach(&strip_cloner); } @@ -465,7 +478,7 @@ stripopen(dev, tp) if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) return (error); - if (tp->t_linesw->l_no == STRIPDISC) + if (tp->t_linesw == &strip_disc) return (0); LIST_FOREACH(sc, &strip_softc_list, sc_iflist) { @@ -536,9 +549,10 @@ stripopen(dev, tp) * Line specific close routine. * Detach the tty from the strip unit. */ -void -stripclose(tp) +int +stripclose(tp, flag) struct tty *tp; + int flag; { struct strip_softc *sc; int s; @@ -561,7 +575,8 @@ stripclose(tp) splx(s); s = spltty(); - tp->t_linesw = linesw[0]; /* default line disc. */ + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_default(); tp->t_state = 0; sc->sc_ttyp = NULL; @@ -596,6 +611,8 @@ stripclose(tp) } splx(s); } + + return (0); } /* @@ -604,11 +621,12 @@ stripclose(tp) */ /* ARGSUSED */ int -striptioctl(tp, cmd, data, flag) +striptioctl(tp, cmd, data, flag, p) struct tty *tp; u_long cmd; caddr_t data; int flag; + struct proc *p; { struct strip_softc *sc = (struct strip_softc *)tp->t_sc; @@ -891,7 +909,7 @@ stripoutput(ifp, m, dst, rt) * the interface before starting output. * */ -void +int stripstart(tp) struct tty *tp; { @@ -905,14 +923,14 @@ stripstart(tp) if (tp->t_outq.c_cc != 0) { (*tp->t_oproc)(tp); if (tp->t_outq.c_cc > SLIP_HIWAT) - return; + return (0); } /* * This happens briefly when the line shuts down. */ if (sc == NULL) - return; + return (0); #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS softintr_schedule(sc->sc_si); #else @@ -922,6 +940,7 @@ stripstart(tp) splx(s); } #endif + return (0); } /* @@ -967,7 +986,7 @@ strip_btom(sc, len) * char is a packet delimiter, decapsulate the packet, wrap it in * an mbuf, and put it on the protocol input queue. */ -void +int stripinput(c, tp) int c; struct tty *tp; @@ -979,12 +998,12 @@ stripinput(c, tp) tk_nin++; sc = (struct strip_softc *)tp->t_sc; if (sc == NULL) - return; + return (0); if (c & TTY_ERRORMASK || ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)) { sc->sc_flags |= SC_ERROR; DPRINTF(("strip: input, error %x\n", c)); /* XXX */ - return; + return (0); } c &= TTY_CHARMASK; @@ -1014,7 +1033,7 @@ stripinput(c, tp) sc->sc_flags |= SC_ERROR; goto error; } - return; + return (0); case STRIP_FRAME_END: break; @@ -1072,6 +1091,8 @@ error: newpack: sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf + BUFOFFSET; + + return (0); } #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS diff --git a/sys/net/if_stripvar.h b/sys/net/if_stripvar.h index f5a6c754fdfc..90c325053233 100644 --- a/sys/net/if_stripvar.h +++ b/sys/net/if_stripvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_stripvar.h,v 1.13 2004/12/05 05:43:04 christos Exp $ */ +/* $NetBSD: if_stripvar.h,v 1.14 2005/11/27 05:35:52 thorpej Exp $ */ #ifndef _NET_IF_STRIPVAR_H_ #define _NET_IF_STRIPVAR_H_ @@ -57,14 +57,14 @@ struct strip_softc { #ifdef _KERNEL void stripattach __P((void)); -void stripclose __P((struct tty *)); -void stripinput __P((int, struct tty *)); +int stripclose __P((struct tty *, int)); +int stripinput __P((int, struct tty *)); int stripioctl __P((struct ifnet *, u_long, caddr_t)); int stripopen __P((dev_t, struct tty *)); int stripoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); -void stripstart __P((struct tty *)); -int striptioctl __P((struct tty *, u_long, caddr_t, int)); +int stripstart __P((struct tty *)); +int striptioctl __P((struct tty *, u_long, caddr_t, int, struct proc *)); #endif /* _KERNEL */ #endif /* _NET_IF_STRIPVAR_H_ */ diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c index 32f6e835d038..ecb9c6765efb 100644 --- a/sys/net/ppp_tty.c +++ b/sys/net/ppp_tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: ppp_tty.c,v 1.38 2005/06/11 22:26:42 christos Exp $ */ +/* $NetBSD: ppp_tty.c,v 1.39 2005/11/27 05:35:52 thorpej Exp $ */ /* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */ /* @@ -93,7 +93,7 @@ /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ #include -__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.38 2005/06/11 22:26:42 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.39 2005/11/27 05:35:52 thorpej Exp $"); #include "ppp.h" @@ -141,6 +141,19 @@ int ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data, int flag, int pppinput __P((int c, struct tty *tp)); int pppstart __P((struct tty *tp)); +struct linesw ppp_disc = { + .l_name = "ppp", + .l_open = pppopen, + .l_close = pppclose, + .l_read = pppread, + .l_write = pppwrite, + .l_ioctl = ppptioctl, + .l_rint = pppinput, + .l_start = pppstart, + .l_modem = ttymodem, + .l_poll = ttpoll +}; + static void ppprcvframe __P((struct ppp_softc *sc, struct mbuf *m)); static u_int16_t pppfcs __P((u_int16_t fcs, u_char *cp, int len)); static void pppsyncstart __P((struct ppp_softc *sc)); @@ -202,7 +215,7 @@ pppopen(dev, tp) s = spltty(); - if (tp->t_linesw->l_no == PPPDISC) { + if (tp->t_linesw == &ppp_disc) { sc = (struct ppp_softc *) tp->t_sc; if (sc != NULL && sc->sc_devp == (void *) tp) { splx(s); @@ -261,7 +274,8 @@ pppclose(tp, flag) s = spltty(); ttyflush(tp, FREAD|FWRITE); - tp->t_linesw = linesw[0]; /* default line discipline */ + ttyldisc_release(tp->t_linesw); + tp->t_linesw = ttyldisc_default(); sc = (struct ppp_softc *) tp->t_sc; if (sc != NULL) { tp->t_sc = NULL; @@ -327,7 +341,7 @@ pppread(tp, uio, flag) s = spltty(); for (;;) { if (tp != (struct tty *) sc->sc_devp || - tp->t_linesw->l_no != PPPDISC) { + tp->t_linesw != &ppp_disc) { splx(s); return 0; } @@ -379,7 +393,7 @@ pppwrite(tp, uio, flag) if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) return 0; /* wrote 0 bytes */ - if (tp->t_linesw->l_no != PPPDISC) + if (tp->t_linesw != &ppp_disc) return (EINVAL); if (sc == NULL || tp != (struct tty *) sc->sc_devp) return EIO; diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 64341280d3bc..71eaf8ae7af0 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -1,4 +1,4 @@ -/* $NetBSD: conf.h,v 1.119 2005/06/21 14:01:13 ws Exp $ */ +/* $NetBSD: conf.h,v 1.120 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -155,7 +155,10 @@ extern const char devioc[], devcls[]; */ struct linesw { const char *l_name; /* Linesw name */ - int l_no; /* Linesw number (compatibility) */ + + LIST_ENTRY(linesw) l_list; + u_int l_refcnt; /* locked by ttyldisc_list_slock */ + int l_no; /* legacy discipline number (for TIOCGETD) */ int (*l_open) (dev_t, struct tty *); int (*l_close) (struct tty *, int); @@ -170,12 +173,12 @@ struct linesw { }; #ifdef _KERNEL -extern struct linesw **linesw; -extern int nlinesw; -extern void ttyldisc_init(void); -int ttyldisc_add(struct linesw *, int); -struct linesw *ttyldisc_remove(const char *); +int ttyldisc_attach(struct linesw *); +int ttyldisc_detach(struct linesw *); struct linesw *ttyldisc_lookup(const char *); +struct linesw *ttyldisc_lookup_bynum(int); +struct linesw *ttyldisc_default(void); +void ttyldisc_release(struct linesw *); /* For those defining their own line disciplines: */ #define ttynodisc ((int (*)(dev_t, struct tty *))enodev) diff --git a/sys/sys/param.h b/sys/sys/param.h index d83e3ec026d4..cc67cabc8c7a 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.223 2005/11/02 12:42:58 yamt Exp $ */ +/* $NetBSD: param.h,v 1.224 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -63,7 +63,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 399001100 /* NetBSD 3.99.11 */ +#define __NetBSD_Version__ 399001200 /* NetBSD 3.99.12 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) >= __NetBSD_Version__) diff --git a/sys/sys/tty.h b/sys/sys/tty.h index f2adefe76f24..2e34b9f0d7a5 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.67 2005/03/17 20:39:18 kleink Exp $ */ +/* $NetBSD: tty.h,v 1.68 2005/11/27 05:35:52 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1993 @@ -250,7 +250,6 @@ int ttysleep(struct tty *, void *, int, const char *, int); int ttywait(struct tty *); int ttywflush(struct tty *); -void tty_init(void); void tty_attach(struct tty *); void tty_detach(struct tty *); struct tty