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