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