Home | History | Annotate | Line # | Download | only in kern
tty_conf.c revision 1.33.2.5
      1 /*	$NetBSD: tty_conf.c,v 1.33.2.5 2002/10/10 18:43:18 jdolecek Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1982, 1986, 1991, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  * (c) UNIX System Laboratories, Inc.
      7  * All or some portions of this file are derived from material licensed
      8  * to the University of California by American Telephone and Telegraph
      9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
     10  * the permission of UNIX System Laboratories, Inc.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. All advertising materials mentioning features or use of this software
     21  *    must display the following acknowledgement:
     22  *	This product includes software developed by the University of
     23  *	California, Berkeley and its contributors.
     24  * 4. Neither the name of the University nor the names of its contributors
     25  *    may be used to endorse or promote products derived from this software
     26  *    without specific prior written permission.
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  * SUCH DAMAGE.
     39  *
     40  *	@(#)tty_conf.c	8.5 (Berkeley) 1/9/95
     41  */
     42 
     43 #include <sys/cdefs.h>
     44 __KERNEL_RCSID(0, "$NetBSD: tty_conf.c,v 1.33.2.5 2002/10/10 18:43:18 jdolecek Exp $");
     45 
     46 #include "opt_compat_freebsd.h"
     47 #include "opt_compat_43.h"
     48 
     49 #include <sys/param.h>
     50 #include <sys/systm.h>
     51 #include <sys/buf.h>
     52 #include <sys/ioctl.h>
     53 #include <sys/proc.h>
     54 #include <sys/tty.h>
     55 #include <sys/ioctl.h>
     56 #include <sys/ttycom.h>
     57 #include <sys/conf.h>
     58 #include <sys/malloc.h>
     59 
     60 #include "tb.h"
     61 #if NTB > 0
     62 int	tbopen __P((dev_t dev, struct tty *tp));
     63 int	tbclose __P((struct tty *tp, int flags));
     64 int	tbread __P((struct tty *tp, struct uio *uio, int flags));
     65 int	tbtioctl __P((struct tty *tp, u_long cmd, caddr_t data,
     66 			int flag, struct proc *p));
     67 int	tbinput __P((int c, struct tty *tp));
     68 #endif
     69 
     70 #include "sl.h"
     71 #if NSL > 0
     72 int	slopen __P((dev_t dev, struct tty *tp));
     73 int	slclose __P((struct tty *tp, int flags));
     74 int	sltioctl __P((struct tty *tp, u_long cmd, caddr_t data,
     75 			int flag, struct proc *p));
     76 int	slinput __P((int c, struct tty *tp));
     77 int	slstart __P((struct tty *tp));
     78 #endif
     79 
     80 #include "ppp.h"
     81 #if NPPP > 0
     82 int	pppopen __P((dev_t dev, struct tty *tp));
     83 int	pppclose __P((struct tty *tp, int flags));
     84 int	ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data,
     85 			int flag, struct proc *p));
     86 int	pppinput __P((int c, struct tty *tp));
     87 int	pppstart __P((struct tty *tp));
     88 int	pppread __P((struct tty *tp, struct uio *uio, int flag));
     89 int	pppwrite __P((struct tty *tp, struct uio *uio, int flag));
     90 #endif
     91 
     92 #include "strip.h"
     93 #if NSTRIP > 0
     94 int	stripopen __P((dev_t dev, struct tty *tp));
     95 int	stripclose __P((struct tty *tp, int flags));
     96 int	striptioctl __P((struct tty *tp, u_long cmd, caddr_t data,
     97 			int flag, struct proc *p));
     98 int	stripinput __P((int c, struct tty *tp));
     99 int	stripstart __P((struct tty *tp));
    100 #endif
    101 
    102 #include "irframetty.h"
    103 #if NIRFRAMETTY > 0
    104 int	irframetopen __P((dev_t dev, struct tty *tp));
    105 int	irframetclose __P((struct tty *tp, int flags));
    106 int	irframetioctl __P((struct tty *tp, u_long cmd, caddr_t data,
    107 			int flag, struct proc *p));
    108 int	irframetinput __P((int c, struct tty *tp));
    109 int	irframetstart __P((struct tty *tp));
    110 int	irframetread __P((struct tty *tp, struct uio *uio, int flag));
    111 int	irframetwrite __P((struct tty *tp, struct uio *uio, int flag));
    112 int	irframetpoll __P((struct tty *tp, int events, struct proc *p));
    113 #endif
    114 
    115 
    116 struct  linesw termios_disc =
    117 	{ "termios", TTYDISC, ttylopen, ttylclose, ttread, ttwrite,
    118 	  ttynullioctl, ttyinput, ttstart, ttymodem, ttpoll };	/* 0- termios */
    119 struct  linesw defunct_disc =
    120 	{ "defunct", 1, ttynodisc, ttyerrclose, ttyerrio, ttyerrio,
    121 	  ttynullioctl, ttyerrinput, ttyerrstart, nullmodem, ttyerrpoll }; /* 1- defunct */
    122 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD)
    123 struct  linesw ntty_disc =
    124 	{ "ntty", 2, ttylopen, ttylclose, ttread, ttwrite, ttynullioctl,
    125 	  ttyinput, ttstart, ttymodem, ttpoll };	/* 2- old NTTYDISC */
    126 #endif
    127 #if NTB > 0
    128 struct  linesw table_disc =
    129 	{ "tablet", TABLDISC, tbopen, tbclose, tbread, ttyerrio, tbtioctl,
    130 	  tbinput, ttstart, nullmodem, ttyerrpoll };	/* 3- TABLDISC */
    131 #endif
    132 #if NSL > 0
    133 struct  linesw slip_disc =
    134 	{ "slip", SLIPDISC, slopen, slclose, ttyerrio, ttyerrio, sltioctl,
    135 	  slinput, slstart, nullmodem, ttyerrpoll };	/* 4- SLIPDISC */
    136 #endif
    137 #if NPPP > 0
    138 struct  linesw ppp_disc =
    139 	{ "ppp", PPPDISC, pppopen, pppclose, pppread, pppwrite, ppptioctl,
    140 	  pppinput, pppstart, ttymodem, ttpoll };	/* 5- PPPDISC */
    141 #endif
    142 #if NSTRIP > 0
    143 struct  linesw strip_disc =
    144 	{ "strip", STRIPDISC, stripopen, stripclose, ttyerrio, ttyerrio,
    145 	  striptioctl, stripinput, stripstart, nullmodem, ttyerrpoll };
    146 							/* 6- STRIPDISC */
    147 #endif
    148 #if NIRFRAMETTY > 0
    149 struct  linesw irframet_disc =
    150 	{ "irframe", IRFRAMEDISC, irframetopen, irframetclose, ttyerrio,
    151 	  ttyerrio, irframetioctl, irframetinput, irframetstart,
    152 	  ttymodem, ttyerrpoll };			/* 10- IRFRAMEDISC */
    153 #endif
    154 
    155 /*
    156  * Registered line disciplines.  Don't use this
    157  * it will go away.
    158  */
    159 #define LSWITCHBRK	20
    160 struct	linesw **linesw = NULL;
    161 int	nlinesw = 0;
    162 int	slinesw = 0;
    163 
    164 /*
    165  * Do nothing specific version of line
    166  * discipline specific ioctl command.
    167  */
    168 /*ARGSUSED*/
    169 int
    170 ttynullioctl(tp, cmd, data, flags, p)
    171 	struct tty *tp;
    172 	u_long cmd;
    173 	char *data;
    174 	int flags;
    175 	struct proc *p;
    176 {
    177 
    178 #ifdef lint
    179 	tp = tp; data = data; flags = flags; p = p;
    180 #endif
    181 	return (EPASSTHROUGH);
    182 }
    183 
    184 /*
    185  * Register a line discipline, optionally providing a
    186  * specific discipline number for compatibility, -1 allocates
    187  * a new one.  Returns a discipline number, or -1 on
    188  * failure.
    189  */
    190 int
    191 ttyldisc_add(disc, no)
    192 	struct linesw *disc;
    193 	int no;
    194 {
    195 
    196 	/* You are not allowed to exceed TTLINEDNAMELEN */
    197 	if (strlen(disc->l_name) >= TTLINEDNAMELEN)
    198 		return (-1);
    199 
    200 	/*
    201 	 * You are not allowed to specify a line switch
    202 	 * compatibility number greater than 10.
    203 	 */
    204 	if (no > 10)
    205 		return (-1);
    206 
    207 	if (linesw == NULL)
    208 		panic("adding uninitialized linesw");
    209 
    210 #ifdef DEBUG
    211 	/*
    212 	 * XXX: For the benefit of LKMs
    213 	 */
    214 	if (disc->l_poll == NULL)
    215 		panic("line discipline must now provide l_poll() entry point");
    216 #endif
    217 
    218 	if (no == -1) {
    219 		/* Hunt for any slot */
    220 
    221 		for (no = slinesw; no-- > 0;)
    222 			if (linesw[no] == NULL)
    223 				break;
    224 		/* if no == -1 we should realloc linesw, but for now... */
    225 		if (no == -1)
    226 			return (-1);
    227 	}
    228 
    229 	/* Need a specific slot */
    230 	if (linesw[no] != NULL)
    231 		return (-1);
    232 
    233 	linesw[no] = disc;
    234 	disc->l_no = no;
    235 
    236 	/* Define size of table */
    237 	if (no >= nlinesw)
    238 		nlinesw = no + 1;
    239 
    240 	return (no);
    241 }
    242 
    243 /*
    244  * Remove a line discipline by its name.  Returns the
    245  * discipline on success or NULL on failure.
    246  */
    247 struct linesw *
    248 ttyldisc_remove(name)
    249 	char *name;
    250 {
    251 	struct linesw *disc;
    252 	int i;
    253 
    254 	if (linesw == NULL)
    255 		panic("removing uninitialized linesw");
    256 
    257 	for (i = 0; i < nlinesw; i++) {
    258 		if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0)) {
    259 			disc = linesw[i];
    260 			linesw[i] = NULL;
    261 
    262 			if (nlinesw == i + 1) {
    263 				/* Need to fix up array sizing */
    264 				while (i-- > 0 && linesw[i] == NULL)
    265 					continue;
    266 				nlinesw = i + 1;
    267 			}
    268 			return (disc);
    269 		}
    270 	}
    271 	return (NULL);
    272 }
    273 
    274 /*
    275  * Look up a line discipline by its name.
    276  */
    277 struct linesw *
    278 ttyldisc_lookup(name)
    279 	char *name;
    280 {
    281 	int i;
    282 
    283 	for (i = 0; i < nlinesw; i++)
    284 		if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0))
    285 			return (linesw[i]);
    286 	return (NULL);
    287 }
    288 
    289 #define TTYLDISCINIT(s, v) \
    290 	do { \
    291 		if (ttyldisc_add(&(s), (v)) != (v)) \
    292 			panic("ttyldisc_init: " __STRING(s)); \
    293 	} while (0)
    294 
    295 /*
    296  * Register the basic line disciplines.
    297  */
    298 void
    299 ttyldisc_init()
    300 {
    301 
    302 	/* Only initialize once */
    303 	if (linesw)
    304 		return;
    305 
    306 	slinesw = LSWITCHBRK;
    307 	linesw = malloc(slinesw * sizeof(struct linesw *),
    308 	    M_TTYS, M_WAITOK);
    309 	memset(linesw, 0, slinesw * sizeof(struct linesw *));
    310 
    311 	TTYLDISCINIT(termios_disc, 0);
    312 	/* Do we really need this one? */
    313 	TTYLDISCINIT(defunct_disc, 1);
    314 
    315 	/*
    316 	 * The following should really be moved to
    317 	 * initialization code for each module.
    318 	 */
    319 
    320 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD)
    321 	TTYLDISCINIT(ntty_disc, 2);
    322 #endif
    323 #if NTB > 0
    324 	TTYLDISCINIT(table_disc, 3);
    325 #endif
    326 #if NSL > 0
    327 	TTYLDISCINIT(slip_disc, 4);
    328 #endif
    329 #if NPPP > 0
    330 	TTYLDISCINIT(ppp_disc, 5);
    331 #endif
    332 #if NSTRIP > 0
    333 	TTYLDISCINIT(strip_disc, 6);
    334 #endif
    335 #if NIRFRAMETTY > 0
    336 	ttyldisc_add(&irframet_disc, -1);
    337 #endif
    338 }
    339