Home | History | Annotate | Line # | Download | only in kern
tty_conf.c revision 1.35
      1 /*	$NetBSD: tty_conf.c,v 1.35 2001/11/12 15:25:28 lukem 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.35 2001/11/12 15:25:28 lukem 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 
    103 struct  linesw termios_disc =
    104 	{ "termios", 0, ttylopen, ttylclose, ttread, ttwrite, nullioctl,
    105 	  ttyinput, ttstart, ttymodem, ttpoll };	/* 0- termios */
    106 struct  linesw defunct_disc =
    107 	{ "defunct", 1, ttynodisc, ttyerrclose, ttyerrio, ttyerrio, nullioctl,
    108 	  ttyerrinput, ttyerrstart, nullmodem, ttyerrpoll }; /* 1- defunct */
    109 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD)
    110 struct  linesw ntty_disc =
    111 	{ "ntty", 2, ttylopen, ttylclose, ttread, ttwrite, nullioctl,
    112 	  ttyinput, ttstart, ttymodem, ttpoll };	/* 2- old NTTYDISC */
    113 #endif
    114 #if NTB > 0
    115 struct  linesw table_disc =
    116 	{ "tablet", 3, tbopen, tbclose, tbread, ttyerrio, tbtioctl,
    117 	  tbinput, ttstart, nullmodem, ttyerrpoll };	/* 3- TABLDISC */
    118 #endif
    119 #if NSL > 0
    120 struct  linesw slip_disc =
    121 	{ "slip", 4, slopen, slclose, ttyerrio, ttyerrio, sltioctl,
    122 	  slinput, slstart, nullmodem, ttyerrpoll };	/* 4- SLIPDISC */
    123 #endif
    124 #if NPPP > 0
    125 struct  linesw ppp_disc =
    126 	{ "ppp", 5, pppopen, pppclose, pppread, pppwrite, ppptioctl,
    127 	  pppinput, pppstart, ttymodem, ttpoll };	/* 5- PPPDISC */
    128 #endif
    129 #if NSTRIP > 0
    130 struct  linesw strip_disc =
    131 	{ "strip", 6, stripopen, stripclose, ttyerrio, ttyerrio, striptioctl,
    132 	  stripinput, stripstart, nullmodem, ttyerrpoll }; /* 6- STRIPDISC */
    133 #endif
    134 
    135 /*
    136  * Registered line disciplines.  Don't use this
    137  * it will go away.
    138  */
    139 #define LSWITCHBRK	20
    140 struct	linesw **linesw = NULL;
    141 int	nlinesw = 0;
    142 int	slinesw = 0;
    143 
    144 /*
    145  * Do nothing specific version of line
    146  * discipline specific ioctl command.
    147  */
    148 /*ARGSUSED*/
    149 int
    150 nullioctl(tp, cmd, data, flags, p)
    151 	struct tty *tp;
    152 	u_long cmd;
    153 	char *data;
    154 	int flags;
    155 	struct proc *p;
    156 {
    157 
    158 #ifdef lint
    159 	tp = tp; data = data; flags = flags; p = p;
    160 #endif
    161 	return (-1);
    162 }
    163 
    164 /*
    165  * Register a line discipline, optionally providing a
    166  * specific discipline number for compatibility, -1 allocates
    167  * a new one.  Returns a discipline number, or -1 on
    168  * failure.
    169  */
    170 int
    171 ttyldisc_add(disc, no)
    172 	struct linesw *disc;
    173 	int no;
    174 {
    175 
    176 	/* You are not allowed to exceed TTLINEDNAMELEN */
    177 	if (strlen(disc->l_name) > TTLINEDNAMELEN)
    178 		return (-1);
    179 
    180 	/*
    181 	 * You are not allowed to specify a line switch
    182 	 * compatibility number greater than 10.
    183 	 */
    184 	if (no > 10)
    185 		return (-1);
    186 
    187 	if (linesw == NULL)
    188 		panic("adding uninitialized linesw");
    189 
    190 #ifdef DEBUG
    191 	/*
    192 	 * XXX: For the benefit of LKMs
    193 	 */
    194 	if (disc->l_poll == NULL)
    195 		panic("line discipline must now provide l_poll() entry point");
    196 #endif
    197 
    198 	if (no == -1) {
    199 		/* Hunt for any slot */
    200 
    201 		for (no = slinesw; no-- > 0;)
    202 			if (linesw[no] == NULL)
    203 				break;
    204 		/* if no == -1 we should realloc linesw, but for now... */
    205 		if (no == -1)
    206 			return (-1);
    207 	}
    208 
    209 	/* Need a specific slot */
    210 	if (linesw[no] != NULL)
    211 		return (-1);
    212 
    213 	linesw[no] = disc;
    214 	disc->l_no = no;
    215 
    216 	/* Define size of table */
    217 	if (no >= nlinesw)
    218 		nlinesw = no + 1;
    219 
    220 	return (no);
    221 }
    222 
    223 /*
    224  * Remove a line discipline by its name.  Returns the
    225  * discipline on success or NULL on failure.
    226  */
    227 struct linesw *
    228 ttyldisc_remove(name)
    229 	char *name;
    230 {
    231 	struct linesw *disc;
    232 	int i;
    233 
    234 	if (linesw == NULL)
    235 		panic("removing uninitialized linesw");
    236 
    237 	for (i = 0; i < nlinesw; i++) {
    238 		if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0)) {
    239 			disc = linesw[i];
    240 			linesw[i] = NULL;
    241 
    242 			if (nlinesw == i + 1) {
    243 				/* Need to fix up array sizing */
    244 				while (i-- > 0 && linesw[i] == NULL)
    245 					continue;
    246 				nlinesw = i + 1;
    247 			}
    248 			return (disc);
    249 		}
    250 	}
    251 	return (NULL);
    252 }
    253 
    254 /*
    255  * Look up a line discipline by its name.
    256  */
    257 struct linesw *
    258 ttyldisc_lookup(name)
    259 	char *name;
    260 {
    261 	int i;
    262 
    263 	for (i = 0; i < nlinesw; i++)
    264 		if (linesw[i] && (strcmp(name, linesw[i]->l_name) == 0))
    265 			return (linesw[i]);
    266 	return (NULL);
    267 }
    268 
    269 #define TTYLDISCINIT(s, v) \
    270 	do { \
    271 		if (ttyldisc_add(&(s), (v)) != (v)) \
    272 			panic("ttyldisc_init: " __STRING(s)); \
    273 	} while (0)
    274 
    275 /*
    276  * Register the basic line disciplines.
    277  */
    278 void
    279 ttyldisc_init()
    280 {
    281 
    282 	/* Only initialize once */
    283 	if (linesw)
    284 		return;
    285 
    286 	slinesw = LSWITCHBRK;
    287 	linesw = malloc(slinesw * sizeof(struct linesw *),
    288 	    M_TTYS, M_WAITOK);
    289 	memset(linesw, 0, slinesw * sizeof(struct linesw *));
    290 
    291 	TTYLDISCINIT(termios_disc, 0);
    292 	/* Do we really need this one? */
    293 	TTYLDISCINIT(defunct_disc, 1);
    294 
    295 	/*
    296 	 * The following should really be moved to
    297 	 * initialization code for each module.
    298 	 */
    299 
    300 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD)
    301 	TTYLDISCINIT(ntty_disc, 2);
    302 #endif
    303 #if NTB > 0
    304 	TTYLDISCINIT(table_disc, 3);
    305 #endif
    306 #if NSL > 0
    307 	TTYLDISCINIT(slip_disc, 4);
    308 #endif
    309 #if NPPP > 0
    310 	TTYLDISCINIT(ppp_disc, 5);
    311 #endif
    312 #if NSTRIP > 0
    313 	TTYLDISCINIT(strip_disc, 6);
    314 #endif
    315 }
    316