xref: /csrg-svn/sys/kern/tty_bk.c (revision 7629)
1 /*	tty_bk.c	4.2	82/08/01	*/
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 
17 /*
18  * Line discipline for Berkeley network.
19  *
20  * This supplies single lines to a user level program
21  * with a minimum of fuss.  Lines are newline terminated.
22  *
23  * This discipline requires that tty device drivers call
24  * the line specific l_ioctl routine from their ioctl routines,
25  * assigning the result to cmd so that we can refuse most tty specific
26  * ioctls which are unsafe because we have ambushed the
27  * teletype input queues, overlaying them with other information.
28  */
29 
30 /*
31  * Open as networked discipline.  Called when discipline changed
32  * with ioctl, this assigns a buffer to the line for input, and
33  * changing the interpretation of the information in the tty structure.
34  */
35 /*ARGSUSED*/
36 bkopen(dev, tp)
37 	dev_t dev;
38 	register struct tty *tp;
39 {
40 	register struct buf *bp;
41 
42 	if (u.u_error)
43 		return;		/* paranoia */
44 	if (tp->t_line == NETLDISC) {
45 		u.u_error = EBUSY;		/* sometimes the network */
46 		return;				/* ... opens /dev/tty */
47 	}
48 	bp = geteblk(1024);
49 	flushtty(tp, FREAD|FWRITE);
50 	tp->t_bufp = bp;
51 	tp->t_cp = (char *)bp->b_un.b_addr;
52 	tp->t_inbuf = 0;
53 	tp->t_rec = 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 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)
88 register struct tty *tp;
89 {
90 	register int i;
91 	register s;
92 
93 	if ((tp->t_state&TS_CARR_ON)==0)
94 		return (-1);
95 	s = spl5();
96 	while (tp->t_rec == 0 && tp->t_line == NETLDISC)
97 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
98 	splx(s);
99 	if (tp->t_line != NETLDISC)
100 		return (-1);
101 	i = MIN(tp->t_inbuf, (int)u.u_count);
102 	if (copyout(tp->t_bufp->b_un.b_addr, u.u_base, (unsigned)i)) {
103 		u.u_error = EFAULT;
104 		return (-1);
105 	}
106 	u.u_count -= i;
107 	u.u_base += i;
108 	u.u_offset += i;
109 	tp->t_cp = (char *)tp->t_bufp->b_un.b_addr;
110 	tp->t_inbuf = 0;
111 	tp->t_rec = 0;
112 	return (0);
113 }
114 
115 /*
116  * Low level character input routine.
117  * Stuff the character in the buffer, and wake up the top
118  * half after setting t_rec if this completes the record
119  * or if the buffer is (ick!) full.
120  *
121  * Thisis where the formatting should get done to allow
122  * 8 character data paths through escapes.
123  *
124  * This rutine should be expanded in-line in the receiver
125  * interrupt routine of the dh-11 to make it run as fast as possible.
126  */
127 bkinput(c, tp)
128 register c;
129 register struct tty *tp;
130 {
131 
132 	if (tp->t_rec)
133 		return;
134 	*tp->t_cp++ = c;
135 	if (++tp->t_inbuf == 1024 || c == '\n') {
136 		tp->t_rec = 1;
137 		wakeup((caddr_t)&tp->t_rawq);
138 	}
139 }
140 
141 /*
142  * This routine is called whenever a ioctl is about to be performed
143  * and gets a chance to reject the ioctl.  We reject all teletype
144  * oriented ioctl's except those which set the discipline, and
145  * those which get parameters (gtty and get special characters).
146  */
147 /*ARGSUSED*/
148 bkioctl(tp, cmd, data, flag)
149 	struct tty *tp;
150 	caddr_t data;
151 {
152 
153 	if ((cmd>>8) != 't')
154 		return (cmd);
155 	switch (cmd) {
156 
157 	case TIOCSETD:
158 	case TIOCGETD:
159 	case TIOCGETP:
160 	case TIOCGETC:
161 		return (cmd);
162 	}
163 	u.u_error = ENOTTY;
164 	return (0);
165 }
166 #endif
167