123388Smckusick /*
229108Smckusick * Copyright (c) 1982, 1986 Regents of the University of California.
323388Smckusick * All rights reserved. The Berkeley software License Agreement
423388Smckusick * specifies the terms and conditions for redistribution.
523388Smckusick *
6*37728Smckusick * @(#)tty_bk.c 7.3 (Berkeley) 05/09/89
723388Smckusick */
87385Sroot
97385Sroot #include "bk.h"
107385Sroot
117385Sroot #if NBK > 0
1217096Sbloom #include "param.h"
1317096Sbloom #include "user.h"
1417096Sbloom #include "ioctl.h"
1517096Sbloom #include "tty.h"
1617096Sbloom #include "file.h"
1717096Sbloom #include "buf.h"
187385Sroot
197385Sroot /*
207385Sroot * Line discipline for Berkeley network.
217385Sroot *
227385Sroot * This supplies single lines to a user level program
237385Sroot * with a minimum of fuss. Lines are newline terminated.
247385Sroot *
257385Sroot * This discipline requires that tty device drivers call
267385Sroot * the line specific l_ioctl routine from their ioctl routines,
277385Sroot * assigning the result to cmd so that we can refuse most tty specific
287385Sroot * ioctls which are unsafe because we have ambushed the
297385Sroot * teletype input queues, overlaying them with other information.
307385Sroot */
317385Sroot
327385Sroot /*
337385Sroot * Open as networked discipline. Called when discipline changed
347385Sroot * with ioctl, this assigns a buffer to the line for input, and
357385Sroot * changing the interpretation of the information in the tty structure.
367385Sroot */
377385Sroot /*ARGSUSED*/
bkopen(dev,tp)387385Sroot bkopen(dev, tp)
397629Ssam dev_t dev;
407629Ssam register struct tty *tp;
417385Sroot {
427385Sroot register struct buf *bp;
437385Sroot
448561Sroot if (tp->t_line == NETLDISC)
458561Sroot return (EBUSY); /* sometimes the network opens /dev/tty */
467385Sroot bp = geteblk(1024);
4712753Ssam ttyflush(tp, FREAD|FWRITE);
487385Sroot tp->t_bufp = bp;
497385Sroot tp->t_cp = (char *)bp->b_un.b_addr;
507385Sroot tp->t_inbuf = 0;
517385Sroot tp->t_rec = 0;
528561Sroot return (0);
537385Sroot }
547385Sroot
557385Sroot /*
567385Sroot * Break down... called when discipline changed or from device
577385Sroot * close routine.
587385Sroot */
bkclose(tp)597385Sroot bkclose(tp)
608561Sroot register struct tty *tp;
617385Sroot {
628561Sroot register int s;
637385Sroot
647385Sroot s = spl5();
657385Sroot wakeup((caddr_t)&tp->t_rawq);
667385Sroot if (tp->t_bufp) {
677385Sroot brelse(tp->t_bufp);
687385Sroot tp->t_bufp = 0;
697385Sroot } else
707385Sroot printf("bkclose: no buf\n");
717385Sroot tp->t_cp = 0;
727385Sroot tp->t_inbuf = 0;
737385Sroot tp->t_rec = 0;
747385Sroot tp->t_line = 0; /* paranoid: avoid races */
757385Sroot splx(s);
767385Sroot }
777385Sroot
787385Sroot /*
797385Sroot * Read from a network line.
807385Sroot * Characters have been buffered in a system buffer and are
817385Sroot * now dumped back to the user in one fell swoop, and with a
827385Sroot * minimum of fuss. Note that no input is accepted when a record
837385Sroot * is waiting. Our clearing tp->t_rec here allows further input
847385Sroot * to accumulate.
857385Sroot */
bkread(tp,uio)867725Sroot bkread(tp, uio)
877725Sroot register struct tty *tp;
887725Sroot struct uio *uio;
897385Sroot {
908590Sroot register int s;
918521Sroot int error;
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);
101*37728Smckusick error = uiomove(tp->t_bufp->b_un.b_addr, tp->t_inbuf, uio);
1027385Sroot tp->t_cp = (char *)tp->t_bufp->b_un.b_addr;
1037385Sroot tp->t_inbuf = 0;
1047385Sroot tp->t_rec = 0;
1058521Sroot return (error);
1067385Sroot }
1077385Sroot
1087385Sroot /*
1097385Sroot * Low level character input routine.
1107385Sroot * Stuff the character in the buffer, and wake up the top
1117385Sroot * half after setting t_rec if this completes the record
1127385Sroot * or if the buffer is (ick!) full.
1137385Sroot *
1147385Sroot * Thisis where the formatting should get done to allow
1157385Sroot * 8 character data paths through escapes.
1167385Sroot *
1177385Sroot * This rutine should be expanded in-line in the receiver
1187385Sroot * interrupt routine of the dh-11 to make it run as fast as possible.
1197385Sroot */
bkinput(c,tp)1207385Sroot bkinput(c, tp)
1217385Sroot register c;
1227385Sroot register struct tty *tp;
1237385Sroot {
1247385Sroot
1257385Sroot if (tp->t_rec)
1267385Sroot return;
1277385Sroot *tp->t_cp++ = c;
1287385Sroot if (++tp->t_inbuf == 1024 || c == '\n') {
1297385Sroot tp->t_rec = 1;
1307385Sroot wakeup((caddr_t)&tp->t_rawq);
1317385Sroot }
1327385Sroot }
1337385Sroot
1347385Sroot /*
1357385Sroot * This routine is called whenever a ioctl is about to be performed
1367385Sroot * and gets a chance to reject the ioctl. We reject all teletype
1377385Sroot * oriented ioctl's except those which set the discipline, and
1387385Sroot * those which get parameters (gtty and get special characters).
1397385Sroot */
1407385Sroot /*ARGSUSED*/
1417629Ssam bkioctl(tp, cmd, data, flag)
1427629Ssam struct tty *tp;
1437629Ssam caddr_t data;
1447385Sroot {
1457385Sroot
1467385Sroot if ((cmd>>8) != 't')
1478561Sroot return (-1);
1487385Sroot switch (cmd) {
1497385Sroot
1507385Sroot case TIOCSETD:
1517385Sroot case TIOCGETD:
1527385Sroot case TIOCGETP:
1537385Sroot case TIOCGETC:
1548561Sroot return (-1);
1557385Sroot }
1568561Sroot return (ENOTTY);
1577385Sroot }
1587385Sroot #endif
159