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