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