| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ppp_tty.c,v 1.70 2022/05/04 07:48:35 andvar Exp $ */ | | 1 | /* $NetBSD: ppp_tty.c,v 1.71 2022/10/26 23:42:56 riastradh Exp $ */ |
2 | /* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */ | | 2 | /* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous | | 5 | * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous |
6 | * tty devices. | | 6 | * tty devices. |
7 | * | | 7 | * |
8 | * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. | | 8 | * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * | | 13 | * |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -83,27 +83,27 @@ | | | @@ -83,27 +83,27 @@ |
83 | * caused system crashes and packet corruption. Changed pppstart | | 83 | * caused system crashes and packet corruption. Changed pppstart |
84 | * so that it doesn't just give up with a "collision" if the whole | | 84 | * so that it doesn't just give up with a "collision" if the whole |
85 | * packet doesn't fit in the output ring buffer. | | 85 | * packet doesn't fit in the output ring buffer. |
86 | * | | 86 | * |
87 | * Added priority queueing for interactive IP packets, following | | 87 | * Added priority queueing for interactive IP packets, following |
88 | * the model of if_sl.c, plus hooks for bpf. | | 88 | * the model of if_sl.c, plus hooks for bpf. |
89 | * Paul Mackerras (paulus@cs.anu.edu.au). | | 89 | * Paul Mackerras (paulus@cs.anu.edu.au). |
90 | */ | | 90 | */ |
91 | | | 91 | |
92 | /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ | | 92 | /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ |
93 | /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ | | 93 | /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ |
94 | | | 94 | |
95 | #include <sys/cdefs.h> | | 95 | #include <sys/cdefs.h> |
96 | __KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.70 2022/05/04 07:48:35 andvar Exp $"); | | 96 | __KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.71 2022/10/26 23:42:56 riastradh Exp $"); |
97 | | | 97 | |
98 | #ifdef _KERNEL_OPT | | 98 | #ifdef _KERNEL_OPT |
99 | #include "ppp.h" | | 99 | #include "ppp.h" |
100 | #include "opt_ppp.h" | | 100 | #include "opt_ppp.h" |
101 | #endif | | 101 | #endif |
102 | #define VJC | | 102 | #define VJC |
103 | #define PPP_COMPRESS | | 103 | #define PPP_COMPRESS |
104 | | | 104 | |
105 | #include <sys/param.h> | | 105 | #include <sys/param.h> |
106 | #include <sys/proc.h> | | 106 | #include <sys/proc.h> |
107 | #include <sys/mbuf.h> | | 107 | #include <sys/mbuf.h> |
108 | #include <sys/dkstat.h> | | 108 | #include <sys/dkstat.h> |
109 | #include <sys/socket.h> | | 109 | #include <sys/socket.h> |
| @@ -225,50 +225,50 @@ pppopen(dev_t dev, struct tty *tp) | | | @@ -225,50 +225,50 @@ pppopen(dev_t dev, struct tty *tp) |
225 | sc->sc_asyncmap[0] = 0xffffffff; | | 225 | sc->sc_asyncmap[0] = 0xffffffff; |
226 | sc->sc_asyncmap[3] = 0x60000000; | | 226 | sc->sc_asyncmap[3] = 0x60000000; |
227 | sc->sc_rasyncmap = 0; | | 227 | sc->sc_rasyncmap = 0; |
228 | sc->sc_devp = (void *) tp; | | 228 | sc->sc_devp = (void *) tp; |
229 | sc->sc_start = pppasyncstart; | | 229 | sc->sc_start = pppasyncstart; |
230 | sc->sc_ctlp = pppasyncctlp; | | 230 | sc->sc_ctlp = pppasyncctlp; |
231 | sc->sc_relinq = pppasyncrelinq; | | 231 | sc->sc_relinq = pppasyncrelinq; |
232 | sc->sc_outm = NULL; | | 232 | sc->sc_outm = NULL; |
233 | pppgetm(sc); | | 233 | pppgetm(sc); |
234 | sc->sc_if.if_flags |= IFF_RUNNING; | | 234 | sc->sc_if.if_flags |= IFF_RUNNING; |
235 | sc->sc_if.if_baudrate = tp->t_ospeed; | | 235 | sc->sc_if.if_baudrate = tp->t_ospeed; |
236 | | | 236 | |
237 | tp->t_sc = (void *) sc; | | 237 | tp->t_sc = (void *) sc; |
238 | mutex_spin_enter(&tty_lock); | | 238 | ttylock(tp); |
239 | ttyflush(tp, FREAD | FWRITE); | | 239 | ttyflush(tp, FREAD | FWRITE); |
240 | mutex_spin_exit(&tty_lock); | | 240 | ttyunlock(tp); |
241 | | | 241 | |
242 | splx(s); | | 242 | splx(s); |
243 | return (0); | | 243 | return (0); |
244 | } | | 244 | } |
245 | | | 245 | |
246 | /* | | 246 | /* |
247 | * Line specific close routine, called from device close routine | | 247 | * Line specific close routine, called from device close routine |
248 | * and from ttioctl. | | 248 | * and from ttioctl. |
249 | * Detach the tty from the ppp unit. | | 249 | * Detach the tty from the ppp unit. |
250 | * Mimics part of ttyclose(). | | 250 | * Mimics part of ttyclose(). |
251 | */ | | 251 | */ |
252 | static int | | 252 | static int |
253 | pppclose(struct tty *tp, int flag) | | 253 | pppclose(struct tty *tp, int flag) |
254 | { | | 254 | { |
255 | struct ppp_softc *sc; | | 255 | struct ppp_softc *sc; |
256 | int s; | | 256 | int s; |
257 | | | 257 | |
258 | s = spltty(); | | 258 | s = spltty(); |
259 | mutex_spin_enter(&tty_lock); | | 259 | ttylock(tp); |
260 | ttyflush(tp, FREAD|FWRITE); | | 260 | ttyflush(tp, FREAD|FWRITE); |
261 | mutex_spin_exit(&tty_lock); /* XXX */ | | 261 | ttyunlock(tp); /* XXX */ |
262 | ttyldisc_release(tp->t_linesw); | | 262 | ttyldisc_release(tp->t_linesw); |
263 | tp->t_linesw = ttyldisc_default(); | | 263 | tp->t_linesw = ttyldisc_default(); |
264 | sc = (struct ppp_softc *) tp->t_sc; | | 264 | sc = (struct ppp_softc *) tp->t_sc; |
265 | if (sc != NULL) { | | 265 | if (sc != NULL) { |
266 | tp->t_sc = NULL; | | 266 | tp->t_sc = NULL; |
267 | if (tp == (struct tty *) sc->sc_devp) { | | 267 | if (tp == (struct tty *) sc->sc_devp) { |
268 | pppasyncrelinq(sc); | | 268 | pppasyncrelinq(sc); |
269 | pppdealloc(sc); | | 269 | pppdealloc(sc); |
270 | } | | 270 | } |
271 | } | | 271 | } |
272 | splx(s); | | 272 | splx(s); |
273 | return 0; | | 273 | return 0; |
274 | } | | 274 | } |
| @@ -306,57 +306,57 @@ pppasyncrelinq(struct ppp_softc *sc) | | | @@ -306,57 +306,57 @@ pppasyncrelinq(struct ppp_softc *sc) |
306 | static int | | 306 | static int |
307 | pppread(struct tty *tp, struct uio *uio, int flag) | | 307 | pppread(struct tty *tp, struct uio *uio, int flag) |
308 | { | | 308 | { |
309 | struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc; | | 309 | struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc; |
310 | struct mbuf *m, *m0; | | 310 | struct mbuf *m, *m0; |
311 | int error = 0; | | 311 | int error = 0; |
312 | | | 312 | |
313 | if (sc == NULL) | | 313 | if (sc == NULL) |
314 | return 0; | | 314 | return 0; |
315 | /* | | 315 | /* |
316 | * Loop waiting for input, checking that nothing disastrous | | 316 | * Loop waiting for input, checking that nothing disastrous |
317 | * happens in the meantime. | | 317 | * happens in the meantime. |
318 | */ | | 318 | */ |
319 | mutex_spin_enter(&tty_lock); | | 319 | ttylock(tp); |
320 | for (;;) { | | 320 | for (;;) { |
321 | if (tp != (struct tty *) sc->sc_devp || | | 321 | if (tp != (struct tty *) sc->sc_devp || |
322 | tp->t_linesw != &ppp_disc) { | | 322 | tp->t_linesw != &ppp_disc) { |
323 | mutex_spin_exit(&tty_lock); | | 323 | ttyunlock(tp); |
324 | return 0; | | 324 | return 0; |
325 | } | | 325 | } |
326 | if (sc->sc_inq.ifq_head != NULL) | | 326 | if (sc->sc_inq.ifq_head != NULL) |
327 | break; | | 327 | break; |
328 | if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0 | | 328 | if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0 |
329 | && (tp->t_state & TS_ISOPEN)) { | | 329 | && (tp->t_state & TS_ISOPEN)) { |
330 | mutex_spin_exit(&tty_lock); | | 330 | ttyunlock(tp); |
331 | return 0; /* end of file */ | | 331 | return 0; /* end of file */ |
332 | } | | 332 | } |
333 | if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) { | | 333 | if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) { |
334 | mutex_spin_exit(&tty_lock); | | 334 | ttyunlock(tp); |
335 | return (EWOULDBLOCK); | | 335 | return (EWOULDBLOCK); |
336 | } | | 336 | } |
337 | error = ttysleep(tp, &tp->t_rawcv, true, 0); | | 337 | error = ttysleep(tp, &tp->t_rawcv, true, 0); |
338 | if (error) { | | 338 | if (error) { |
339 | mutex_spin_exit(&tty_lock); | | 339 | ttyunlock(tp); |
340 | return error; | | 340 | return error; |
341 | } | | 341 | } |
342 | } | | 342 | } |
343 | | | 343 | |
344 | /* Pull place-holder byte out of canonical queue */ | | 344 | /* Pull place-holder byte out of canonical queue */ |
345 | getc(&tp->t_canq); | | 345 | getc(&tp->t_canq); |
346 | | | 346 | |
347 | /* Get the packet from the input queue */ | | 347 | /* Get the packet from the input queue */ |
348 | IF_DEQUEUE(&sc->sc_inq, m0); | | 348 | IF_DEQUEUE(&sc->sc_inq, m0); |
349 | mutex_spin_exit(&tty_lock); | | 349 | ttyunlock(tp); |
350 | | | 350 | |
351 | for (m = m0; m && uio->uio_resid; m = m->m_next) | | 351 | for (m = m0; m && uio->uio_resid; m = m->m_next) |
352 | if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0) | | 352 | if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0) |
353 | break; | | 353 | break; |
354 | m_freem(m0); | | 354 | m_freem(m0); |
355 | return (error); | | 355 | return (error); |
356 | } | | 356 | } |
357 | | | 357 | |
358 | /* | | 358 | /* |
359 | * Line specific (tty) write routine. | | 359 | * Line specific (tty) write routine. |
360 | */ | | 360 | */ |
361 | static int | | 361 | static int |
362 | pppwrite(struct tty *tp, struct uio *uio, int flag) | | 362 | pppwrite(struct tty *tp, struct uio *uio, int flag) |
| @@ -692,27 +692,27 @@ pppasyncstart(struct ppp_softc *sc) | | | @@ -692,27 +692,27 @@ pppasyncstart(struct ppp_softc *sc) |
692 | { | | 692 | { |
693 | struct tty *tp = (struct tty *) sc->sc_devp; | | 693 | struct tty *tp = (struct tty *) sc->sc_devp; |
694 | struct mbuf *m; | | 694 | struct mbuf *m; |
695 | int len; | | 695 | int len; |
696 | u_char *start, *stop, *cp; | | 696 | u_char *start, *stop, *cp; |
697 | int n, ndone, done, idle; | | 697 | int n, ndone, done, idle; |
698 | struct mbuf *m2; | | 698 | struct mbuf *m2; |
699 | | | 699 | |
700 | if (sc->sc_flags & SC_SYNC){ | | 700 | if (sc->sc_flags & SC_SYNC){ |
701 | pppsyncstart(sc); | | 701 | pppsyncstart(sc); |
702 | return; | | 702 | return; |
703 | } | | 703 | } |
704 | | | 704 | |
705 | mutex_spin_enter(&tty_lock); | | 705 | ttylock(tp); |
706 | | | 706 | |
707 | idle = 0; | | 707 | idle = 0; |
708 | while (CCOUNT(&tp->t_outq) < PPP_HIWAT) { | | 708 | while (CCOUNT(&tp->t_outq) < PPP_HIWAT) { |
709 | /* | | 709 | /* |
710 | * See if we have an existing packet partly sent. | | 710 | * See if we have an existing packet partly sent. |
711 | * If not, get a new packet and start sending it. | | 711 | * If not, get a new packet and start sending it. |
712 | */ | | 712 | */ |
713 | m = sc->sc_outm; | | 713 | m = sc->sc_outm; |
714 | if (m == NULL) { | | 714 | if (m == NULL) { |
715 | /* | | 715 | /* |
716 | * Get another packet to be sent. | | 716 | * Get another packet to be sent. |
717 | */ | | 717 | */ |
718 | m = ppp_dequeue(sc); | | 718 | m = ppp_dequeue(sc); |
| @@ -850,44 +850,44 @@ pppasyncstart(struct ppp_softc *sc) | | | @@ -850,44 +850,44 @@ pppasyncstart(struct ppp_softc *sc) |
850 | /* Call pppstart to start output again if necessary. */ | | 850 | /* Call pppstart to start output again if necessary. */ |
851 | pppstart(tp); | | 851 | pppstart(tp); |
852 | | | 852 | |
853 | /* | | 853 | /* |
854 | * This timeout is needed for operation on a pseudo-tty, | | 854 | * This timeout is needed for operation on a pseudo-tty, |
855 | * because the pty code doesn't call pppstart after it has | | 855 | * because the pty code doesn't call pppstart after it has |
856 | * drained the t_outq. | | 856 | * drained the t_outq. |
857 | */ | | 857 | */ |
858 | if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) { | | 858 | if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) { |
859 | callout_reset(&sc->sc_timo_ch, 1, ppp_timeout, sc); | | 859 | callout_reset(&sc->sc_timo_ch, 1, ppp_timeout, sc); |
860 | sc->sc_flags |= SC_TIMEOUT; | | 860 | sc->sc_flags |= SC_TIMEOUT; |
861 | } | | 861 | } |
862 | | | 862 | |
863 | mutex_spin_exit(&tty_lock); | | 863 | ttyunlock(tp); |
864 | } | | 864 | } |
865 | | | 865 | |
866 | /* | | 866 | /* |
867 | * This gets called when a received packet is placed on | | 867 | * This gets called when a received packet is placed on |
868 | * the inq, at splsoftnet. | | 868 | * the inq, at splsoftnet. |
869 | */ | | 869 | */ |
870 | static void | | 870 | static void |
871 | pppasyncctlp(struct ppp_softc *sc) | | 871 | pppasyncctlp(struct ppp_softc *sc) |
872 | { | | 872 | { |
873 | struct tty *tp; | | 873 | struct tty *tp; |
874 | | | 874 | |
875 | /* Put a placeholder byte in canq for ttselect()/ttnread(). */ | | 875 | /* Put a placeholder byte in canq for ttselect()/ttnread(). */ |
876 | mutex_spin_enter(&tty_lock); | | | |
877 | tp = (struct tty *) sc->sc_devp; | | 876 | tp = (struct tty *) sc->sc_devp; |
| | | 877 | ttylock(tp); |
878 | putc(0, &tp->t_canq); | | 878 | putc(0, &tp->t_canq); |
879 | ttwakeup(tp); | | 879 | ttwakeup(tp); |
880 | mutex_spin_exit(&tty_lock); | | 880 | ttyunlock(tp); |
881 | } | | 881 | } |
882 | | | 882 | |
883 | /* | | 883 | /* |
884 | * Start output on async tty interface. If the transmit queue | | 884 | * Start output on async tty interface. If the transmit queue |
885 | * has drained sufficiently, arrange for pppasyncstart to be | | 885 | * has drained sufficiently, arrange for pppasyncstart to be |
886 | * called later at splsoftnet. | | 886 | * called later at splsoftnet. |
887 | * Called at spltty or higher. | | 887 | * Called at spltty or higher. |
888 | */ | | 888 | */ |
889 | static int | | 889 | static int |
890 | pppstart(struct tty *tp) | | 890 | pppstart(struct tty *tp) |
891 | { | | 891 | { |
892 | struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc; | | 892 | struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc; |
893 | | | 893 | |
| @@ -922,30 +922,30 @@ pppstart(struct tty *tp) | | | @@ -922,30 +922,30 @@ pppstart(struct tty *tp) |
922 | | | 922 | |
923 | return 0; | | 923 | return 0; |
924 | } | | 924 | } |
925 | | | 925 | |
926 | /* | | 926 | /* |
927 | * Timeout routine - try to start some more output. | | 927 | * Timeout routine - try to start some more output. |
928 | */ | | 928 | */ |
929 | static void | | 929 | static void |
930 | ppp_timeout(void *x) | | 930 | ppp_timeout(void *x) |
931 | { | | 931 | { |
932 | struct ppp_softc *sc = (struct ppp_softc *) x; | | 932 | struct ppp_softc *sc = (struct ppp_softc *) x; |
933 | struct tty *tp = (struct tty *) sc->sc_devp; | | 933 | struct tty *tp = (struct tty *) sc->sc_devp; |
934 | | | 934 | |
935 | mutex_spin_enter(&tty_lock); | | 935 | ttylock(tp); |
936 | sc->sc_flags &= ~SC_TIMEOUT; | | 936 | sc->sc_flags &= ~SC_TIMEOUT; |
937 | pppstart(tp); | | 937 | pppstart(tp); |
938 | mutex_spin_exit(&tty_lock); | | 938 | ttyunlock(tp); |
939 | } | | 939 | } |
940 | | | 940 | |
941 | /* | | 941 | /* |
942 | * Allocate enough mbuf to handle current MRU. | | 942 | * Allocate enough mbuf to handle current MRU. |
943 | */ | | 943 | */ |
944 | static void | | 944 | static void |
945 | pppgetm(struct ppp_softc *sc) | | 945 | pppgetm(struct ppp_softc *sc) |
946 | { | | 946 | { |
947 | struct mbuf *m, **mp; | | 947 | struct mbuf *m, **mp; |
948 | int len; | | 948 | int len; |
949 | | | 949 | |
950 | mp = &sc->sc_m; | | 950 | mp = &sc->sc_m; |
951 | for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){ | | 951 | for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){ |