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