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