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