tty_conf.c revision 1.34.4.1 1 /* $NetBSD: tty_conf.c,v 1.34.4.1 2001/11/12 21:18:57 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 <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: tty_conf.c,v 1.34.4.1 2001/11/12 21:18:57 thorpej 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