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