xref: /original-bsd/sys/kern/tty_bk.c (revision c7ce21e7)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tty_bk.c	7.2 (Berkeley) 07/27/87
7  */
8 
9 #include "bk.h"
10 
11 #if NBK > 0
12 #include "param.h"
13 #include "dir.h"
14 #include "user.h"
15 #include "ioctl.h"
16 #include "tty.h"
17 #include "file.h"
18 #include "buf.h"
19 
20 /*
21  * Line discipline for Berkeley network.
22  *
23  * This supplies single lines to a user level program
24  * with a minimum of fuss.  Lines are newline terminated.
25  *
26  * This discipline requires that tty device drivers call
27  * the line specific l_ioctl routine from their ioctl routines,
28  * assigning the result to cmd so that we can refuse most tty specific
29  * ioctls which are unsafe because we have ambushed the
30  * teletype input queues, overlaying them with other information.
31  */
32 
33 /*
34  * Open as networked discipline.  Called when discipline changed
35  * with ioctl, this assigns a buffer to the line for input, and
36  * changing the interpretation of the information in the tty structure.
37  */
38 /*ARGSUSED*/
39 bkopen(dev, tp)
40 	dev_t dev;
41 	register struct tty *tp;
42 {
43 	register struct buf *bp;
44 
45 	if (tp->t_line == NETLDISC)
46 		return (EBUSY);	/* sometimes the network opens /dev/tty */
47 	bp = geteblk(1024);
48 	ttyflush(tp, FREAD|FWRITE);
49 	tp->t_bufp = bp;
50 	tp->t_cp = (char *)bp->b_un.b_addr;
51 	tp->t_inbuf = 0;
52 	tp->t_rec = 0;
53 	return (0);
54 }
55 
56 /*
57  * Break down... called when discipline changed or from device
58  * close routine.
59  */
60 bkclose(tp)
61 	register struct tty *tp;
62 {
63 	register int s;
64 
65 	s = spl5();
66 	wakeup((caddr_t)&tp->t_rawq);
67 	if (tp->t_bufp) {
68 		brelse(tp->t_bufp);
69 		tp->t_bufp = 0;
70 	} else
71 		printf("bkclose: no buf\n");
72 	tp->t_cp = 0;
73 	tp->t_inbuf = 0;
74 	tp->t_rec = 0;
75 	tp->t_line = 0;		/* paranoid: avoid races */
76 	splx(s);
77 }
78 
79 /*
80  * Read from a network line.
81  * Characters have been buffered in a system buffer and are
82  * now dumped back to the user in one fell swoop, and with a
83  * minimum of fuss.  Note that no input is accepted when a record
84  * is waiting.  Our clearing tp->t_rec here allows further input
85  * to accumulate.
86  */
87 bkread(tp, uio)
88 	register struct tty *tp;
89 	struct uio *uio;
90 {
91 	register int s;
92 	int error;
93 
94 	if ((tp->t_state&TS_CARR_ON)==0)
95 		return (-1);
96 	s = spl5();
97 	while (tp->t_rec == 0 && tp->t_line == NETLDISC)
98 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
99 	splx(s);
100 	if (tp->t_line != NETLDISC)
101 		return (-1);
102 	error = uiomove(tp->t_bufp->b_un.b_addr, tp->t_inbuf, UIO_READ, uio);
103 	tp->t_cp = (char *)tp->t_bufp->b_un.b_addr;
104 	tp->t_inbuf = 0;
105 	tp->t_rec = 0;
106 	return (error);
107 }
108 
109 /*
110  * Low level character input routine.
111  * Stuff the character in the buffer, and wake up the top
112  * half after setting t_rec if this completes the record
113  * or if the buffer is (ick!) full.
114  *
115  * Thisis where the formatting should get done to allow
116  * 8 character data paths through escapes.
117  *
118  * This rutine should be expanded in-line in the receiver
119  * interrupt routine of the dh-11 to make it run as fast as possible.
120  */
121 bkinput(c, tp)
122 register c;
123 register struct tty *tp;
124 {
125 
126 	if (tp->t_rec)
127 		return;
128 	*tp->t_cp++ = c;
129 	if (++tp->t_inbuf == 1024 || c == '\n') {
130 		tp->t_rec = 1;
131 		wakeup((caddr_t)&tp->t_rawq);
132 	}
133 }
134 
135 /*
136  * This routine is called whenever a ioctl is about to be performed
137  * and gets a chance to reject the ioctl.  We reject all teletype
138  * oriented ioctl's except those which set the discipline, and
139  * those which get parameters (gtty and get special characters).
140  */
141 /*ARGSUSED*/
142 bkioctl(tp, cmd, data, flag)
143 	struct tty *tp;
144 	caddr_t data;
145 {
146 
147 	if ((cmd>>8) != 't')
148 		return (-1);
149 	switch (cmd) {
150 
151 	case TIOCSETD:
152 	case TIOCGETD:
153 	case TIOCGETP:
154 	case TIOCGETC:
155 		return (-1);
156 	}
157 	return (ENOTTY);
158 }
159 #endif
160