xref: /csrg-svn/sys/kern/tty_bk.c (revision 7629)
1*7629Ssam /*	tty_bk.c	4.2	82/08/01	*/
27385Sroot 
37385Sroot #include "bk.h"
47385Sroot 
57385Sroot #if NBK > 0
67385Sroot #include "../h/param.h"
77385Sroot #include "../h/systm.h"
87385Sroot #include "../h/dir.h"
97385Sroot #include "../h/user.h"
107385Sroot #include "../h/tty.h"
117385Sroot #include "../h/proc.h"
127385Sroot #include "../h/inode.h"
137385Sroot #include "../h/file.h"
147385Sroot #include "../h/conf.h"
157385Sroot #include "../h/buf.h"
167385Sroot 
177385Sroot /*
187385Sroot  * Line discipline for Berkeley network.
197385Sroot  *
207385Sroot  * This supplies single lines to a user level program
217385Sroot  * with a minimum of fuss.  Lines are newline terminated.
227385Sroot  *
237385Sroot  * This discipline requires that tty device drivers call
247385Sroot  * the line specific l_ioctl routine from their ioctl routines,
257385Sroot  * assigning the result to cmd so that we can refuse most tty specific
267385Sroot  * ioctls which are unsafe because we have ambushed the
277385Sroot  * teletype input queues, overlaying them with other information.
287385Sroot  */
297385Sroot 
307385Sroot /*
317385Sroot  * Open as networked discipline.  Called when discipline changed
327385Sroot  * with ioctl, this assigns a buffer to the line for input, and
337385Sroot  * changing the interpretation of the information in the tty structure.
347385Sroot  */
357385Sroot /*ARGSUSED*/
367385Sroot bkopen(dev, tp)
37*7629Ssam 	dev_t dev;
38*7629Ssam 	register struct tty *tp;
397385Sroot {
407385Sroot 	register struct buf *bp;
417385Sroot 
427385Sroot 	if (u.u_error)
437385Sroot 		return;		/* paranoia */
447385Sroot 	if (tp->t_line == NETLDISC) {
457385Sroot 		u.u_error = EBUSY;		/* sometimes the network */
467385Sroot 		return;				/* ... opens /dev/tty */
477385Sroot 	}
487385Sroot 	bp = geteblk(1024);
497385Sroot 	flushtty(tp, FREAD|FWRITE);
507385Sroot 	tp->t_bufp = bp;
517385Sroot 	tp->t_cp = (char *)bp->b_un.b_addr;
527385Sroot 	tp->t_inbuf = 0;
537385Sroot 	tp->t_rec = 0;
547385Sroot }
557385Sroot 
567385Sroot /*
577385Sroot  * Break down... called when discipline changed or from device
587385Sroot  * close routine.
597385Sroot  */
607385Sroot bkclose(tp)
617385Sroot register struct tty *tp;
627385Sroot {
637385Sroot 	register s;
647385Sroot 
657385Sroot 	s = spl5();
667385Sroot 	wakeup((caddr_t)&tp->t_rawq);
677385Sroot 	if (tp->t_bufp) {
687385Sroot 		brelse(tp->t_bufp);
697385Sroot 		tp->t_bufp = 0;
707385Sroot 	} else
717385Sroot 		printf("bkclose: no buf\n");
727385Sroot 	tp->t_cp = 0;
737385Sroot 	tp->t_inbuf = 0;
747385Sroot 	tp->t_rec = 0;
757385Sroot 	tp->t_line = 0;		/* paranoid: avoid races */
767385Sroot 	splx(s);
777385Sroot }
787385Sroot 
797385Sroot /*
807385Sroot  * Read from a network line.
817385Sroot  * Characters have been buffered in a system buffer and are
827385Sroot  * now dumped back to the user in one fell swoop, and with a
837385Sroot  * minimum of fuss.  Note that no input is accepted when a record
847385Sroot  * is waiting.  Our clearing tp->t_rec here allows further input
857385Sroot  * to accumulate.
867385Sroot  */
877385Sroot bkread(tp)
887385Sroot register struct tty *tp;
897385Sroot {
907385Sroot 	register int i;
917385Sroot 	register s;
927385Sroot 
937385Sroot 	if ((tp->t_state&TS_CARR_ON)==0)
947385Sroot 		return (-1);
957385Sroot 	s = spl5();
967385Sroot 	while (tp->t_rec == 0 && tp->t_line == NETLDISC)
977385Sroot 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
987385Sroot 	splx(s);
997385Sroot 	if (tp->t_line != NETLDISC)
1007385Sroot 		return (-1);
1017385Sroot 	i = MIN(tp->t_inbuf, (int)u.u_count);
1027385Sroot 	if (copyout(tp->t_bufp->b_un.b_addr, u.u_base, (unsigned)i)) {
1037385Sroot 		u.u_error = EFAULT;
1047385Sroot 		return (-1);
1057385Sroot 	}
1067385Sroot 	u.u_count -= i;
1077385Sroot 	u.u_base += i;
1087385Sroot 	u.u_offset += i;
1097385Sroot 	tp->t_cp = (char *)tp->t_bufp->b_un.b_addr;
1107385Sroot 	tp->t_inbuf = 0;
1117385Sroot 	tp->t_rec = 0;
1127385Sroot 	return (0);
1137385Sroot }
1147385Sroot 
1157385Sroot /*
1167385Sroot  * Low level character input routine.
1177385Sroot  * Stuff the character in the buffer, and wake up the top
1187385Sroot  * half after setting t_rec if this completes the record
1197385Sroot  * or if the buffer is (ick!) full.
1207385Sroot  *
1217385Sroot  * Thisis where the formatting should get done to allow
1227385Sroot  * 8 character data paths through escapes.
1237385Sroot  *
1247385Sroot  * This rutine should be expanded in-line in the receiver
1257385Sroot  * interrupt routine of the dh-11 to make it run as fast as possible.
1267385Sroot  */
1277385Sroot bkinput(c, tp)
1287385Sroot register c;
1297385Sroot register struct tty *tp;
1307385Sroot {
1317385Sroot 
1327385Sroot 	if (tp->t_rec)
1337385Sroot 		return;
1347385Sroot 	*tp->t_cp++ = c;
1357385Sroot 	if (++tp->t_inbuf == 1024 || c == '\n') {
1367385Sroot 		tp->t_rec = 1;
1377385Sroot 		wakeup((caddr_t)&tp->t_rawq);
1387385Sroot 	}
1397385Sroot }
1407385Sroot 
1417385Sroot /*
1427385Sroot  * This routine is called whenever a ioctl is about to be performed
1437385Sroot  * and gets a chance to reject the ioctl.  We reject all teletype
1447385Sroot  * oriented ioctl's except those which set the discipline, and
1457385Sroot  * those which get parameters (gtty and get special characters).
1467385Sroot  */
1477385Sroot /*ARGSUSED*/
148*7629Ssam bkioctl(tp, cmd, data, flag)
149*7629Ssam 	struct tty *tp;
150*7629Ssam 	caddr_t data;
1517385Sroot {
1527385Sroot 
1537385Sroot 	if ((cmd>>8) != 't')
1547385Sroot 		return (cmd);
1557385Sroot 	switch (cmd) {
1567385Sroot 
1577385Sroot 	case TIOCSETD:
1587385Sroot 	case TIOCGETD:
1597385Sroot 	case TIOCGETP:
1607385Sroot 	case TIOCGETC:
1617385Sroot 		return (cmd);
1627385Sroot 	}
1637385Sroot 	u.u_error = ENOTTY;
1647385Sroot 	return (0);
1657385Sroot }
1667385Sroot #endif
167