|
|
BSD 4.1
/* bk.c 4.2 11/9/80 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/tty.h"
#include "../h/proc.h"
#include "../h/mx.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/conf.h"
#include "../h/buf.h"
/*
* When running dz's using only SAE (silo alarm) on input
* it is necessary to call dzrint() at clock interrupt time.
* This is unsafe unless spl5()s in tty code are changed to
* spl6()s to block clock interrupts. Note that the dh driver
* currently in use works the same way as the dz, even though
* we could try to more intelligently manage its silo.
* Thus don't take this out if you have no dz's unless you
* change clock.c and dhtimer().
*/
#define spl5 spl6
/*
* Line discipline for Berkeley network.
*
* This supplies single lines to a user level program
* with a minimum of fuss. Lines are newline terminated.
* A later version will implement full 8-bit paths by providing
* an escape sequence to include a newline in a record.
*
* This discipline requires that tty device drivers call
* the line specific l_ioctl routine from their ioctl routines,
* assigning the result to cmd so that we can refuse most tty specific
* ioctls which are unsafe because we have ambushed the
* teletype input queues, overlaying them with other information.
*/
/*
* Open as networked discipline. Called when discipline changed
* with ioctl, this assigns a buffer to the line for input, and
* changing the interpretation of the information in the tty structure.
*/
/*ARGSUSED*/
bkopen(dev, tp)
dev_t dev;
register struct tty *tp;
{
register struct buf *bp;
if (u.u_error)
return; /* paranoia */
if (tp->t_line == NETLDISC) {
u.u_error = EBUSY; /* sometimes the network */
return; /* ... opens /dev/tty */
}
bp = geteblk();
flushtty(tp, FREAD|FWRITE);
tp->t_bufp = bp;
tp->t_cp = (char *)bp->b_un.b_addr;
tp->t_inbuf = 0;
tp->t_rec = 0;
}
/*
* Break down... called when discipline changed or from device
* close routine.
*/
bkclose(tp)
register struct tty *tp;
{
register s;
s = spl5();
wakeup((caddr_t)&tp->t_rawq);
if (tp->t_bufp) {
brelse(tp->t_bufp);
tp->t_bufp = 0;
} else
printf("bkclose: no buf\n");
tp->t_cp = 0;
tp->t_inbuf = 0;
tp->t_rec = 0;
tp->t_line = 0; /* paranoid: avoid races */
splx(s);
}
/*
* Read from a network line.
* Characters have been buffered in a system buffer and are
* now dumped back to the user in one fell swoop, and with a
* minimum of fuss. Note that no input is accepted when a record
* is waiting. Our clearing tp->t_rec here allows further input
* to accumulate.
*/
bkread(tp)
register struct tty *tp;
{
register int i;
register s;
if ((tp->t_state&CARR_ON)==0)
return (-1);
s = spl5();
while (tp->t_rec == 0 && tp->t_line == NETLDISC)
sleep((caddr_t)&tp->t_rawq, TTIPRI);
splx(s);
if (tp->t_line != NETLDISC)
return (-1);
i = MIN(tp->t_inbuf, (int)u.u_count);
if (copyout(tp->t_bufp->b_un.b_addr, u.u_base, (unsigned)i)) {
u.u_error = EFAULT;
return (-1);
}
u.u_count -= i;
u.u_base += i;
u.u_offset += i;
tp->t_cp = (char *)tp->t_bufp->b_un.b_addr;
tp->t_inbuf = 0;
tp->t_rec = 0;
return (0);
}
/*
* Low level character input routine.
* Stuff the character in the buffer, and wake up the top
* half after setting t_rec if this completes the record
* or if the buffer is (ick!) full.
*
* Thisis where the formatting should get done to allow
* 8 character data paths through escapes.
*
* This rutine should be expanded in-line in the receiver
* interrupt routine of the dh-11 to make it run as fast as possible.
*/
bkinput(c, tp)
register c;
register struct tty *tp;
{
if (tp->t_rec)
return;
*tp->t_cp++ = c;
if (++tp->t_inbuf == BSIZE || c == '\n') {
tp->t_rec = 1;
wakeup((caddr_t)&tp->t_rawq);
}
}
/*
* This routine is called whenever a ioctl is about to be performed
* and gets a chance to reject the ioctl. We reject all teletype
* oriented ioctl's except those which set the discipline, and
* those which get parameters (gtty and get special characters).
*/
/*ARGSUSED*/
bkioctl(tp, cmd, addr)
struct tty *tp;
caddr_t addr;
{
if ((cmd>>8) != 't')
return (cmd);
switch (cmd) {
case TIOCSETD:
case TIOCGETD:
case TIOCGETP:
case TIOCGETC:
return (cmd);
}
u.u_error = ENOTTY;
return (0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.