SysIII/usr/src/uts/vax/io/dl.c

Compare this file to the similar file:
Show the results in this format:

/*
 *   DL-11E driver
 */
#include "sys/param.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/file.h"
#include "sys/tty.h"
#include "sys/conf.h"
#include "sys/sysinfo.h"

struct device *dl_addr[];
int	dl_cnt;
struct tty dl_tty[];
char	partab[];

#define	DTR	02
#define	RTS	04
#define	DSIE	040
#define	IE	0100
#define	RCVDONE	0200
#define	CARRIER	010000
#define	DSCHG	0100000
#define	XBRK	01

#define	FERROR	020000

struct device {
	short	rcsr, rbuf;
	short	tcsr, tbuf;
};

dlopen(dev, flag)
{
	register struct device *addr;
	register struct tty *tp;
	extern dlproc();

	if(dev >= dl_cnt) {
		u.u_error = ENXIO;
		return;
	}
	tp = &dl_tty[dev];
	addr = dl_addr[dev];
	if ((tp->t_state&(ISOPEN|WOPEN)) == 0) {
		ttinit(tp);
		tp->t_proc = dlproc;
		addr->rcsr |= IE;
		addr->tcsr |= IE;
	}
	spl4();
	addr->rcsr |= DSIE|RTS|DTR;
	if (addr->rcsr & CARRIER)
		tp->t_state |= CARR_ON;
	if (!(flag&FNDELAY))
	while ((tp->t_state&CARR_ON)==0) {
		tp->t_state |= WOPEN;
		sleep((caddr_t)&tp->t_canq, TTIPRI);
	}
	(*linesw[tp->t_line].l_open)(tp);
	spl0();
}

dlclose(dev)
{
	register struct tty *tp;

	tp = &dl_tty[dev];
	(*linesw[tp->t_line].l_close)(tp);
	if (tp->t_cflag&HUPCL)
		dl_addr[dev]->rcsr &= ~(RTS|DTR);
}

dlread(dev)
{
	register struct tty *tp;

	tp = &dl_tty[dev];
	(*linesw[tp->t_line].l_read)(tp);
}

dlwrite(dev)
{
	register struct tty *tp;

	tp = &dl_tty[dev];
	(*linesw[tp->t_line].l_write)(tp);
}

dlxint(dev)
{
	register struct tty *tp;
	register struct device *addr;

	tp = &dl_tty[dev];
	addr = dl_addr[dev];
	if (addr->tcsr&DONE) {
		tp->t_state &= ~BUSY;
		if (tp->t_state & TTXON) {
			addr->tbuf = CSTART;
			tp->t_state &= ~TTXON;
		} else if (tp->t_state & TTXOFF) {
			addr->tbuf = CSTOP;
			tp->t_state &= ~TTXOFF;
		} else
			dlproc(tp, T_OUTPUT);
	}
}

dlrint(dev)
{
	register int c;
	register struct device *addr;
	register struct tty *tp;

	tp = &dl_tty[dev];
	addr = dl_addr[dev];
	c = addr->rcsr;
	if (c&DSCHG) {
		if (c&CARRIER) {
			if ((tp->t_state&CARR_ON)==0) {
				wakeup(&tp->t_canq);
				tp->t_state |= CARR_ON;
			}
		} else {
			if (tp->t_state&CARR_ON) {
				if (tp->t_state&ISOPEN) {
					signal(tp->t_pgrp, SIGHUP);
					addr->rcsr &= ~(RTS|DTR);
					ttyflush(tp, (FREAD|FWRITE));
				}
				tp->t_state &= ~CARR_ON;
			}
		}
	} else if (c&RCVDONE) {
		c = addr->rbuf;
		(*linesw[tp->t_line].l_input)(tp, c, 0);
	}
}

dlioctl(dev, cmd, arg, mode)
{
	register struct tty *tp;

	tp = &dl_tty[dev];
	if (ttiocom(tp, cmd, arg, mode))
		if ((tp->t_cflag&CBAUD) == 0)
			dl_addr[dev]->rcsr &= ~(RTS|DTR);
}

dlproc(tp, cmd)
register struct tty *tp;
{
	register c;
	register struct device *addr;

	extern ttrstrt();

	addr = dl_addr[tp - dl_tty];
	switch (cmd) {

	case T_TIME:
		tp->t_state &= ~TIMEOUT;
		addr->tcsr &= ~XBRK;
		goto start;

	case T_WFLUSH:
	case T_RESUME:
		tp->t_state &= ~TTSTOP;
		goto start;

	case T_OUTPUT:
	start:
		if (tp->t_state&(TIMEOUT|TTSTOP|BUSY))
			break;
		if (tp->t_state&TTIOW && tp->t_outq.c_cc==0) {
			tp->t_state &= ~TTIOW;
			wakeup((caddr_t)&tp->t_oflag);
		}
		while ((c=getc(&tp->t_outq)) >= 0) {
			if (tp->t_oflag&OPOST && c == 0200) {
				if ((c = getc(&tp->t_outq)) < 0)
					break;
				if (c > 0200) {
					tp->t_state |= TIMEOUT;
					timeout(ttrstrt, (caddr_t)tp, (c&0177));
					break;
				}
			}
			tp->t_state |= BUSY;
	/* parity ? */
			addr->tbuf = c;
			break;
		}
		if (tp->t_state&OASLP && tp->t_outq.c_cc<=ttlowat[tp->t_cflag&CBAUD]) {
			tp->t_state &= ~OASLP;
			wakeup((caddr_t)&tp->t_outq);
		}
		break;

	case T_SUSPEND:
		tp->t_state |= TTSTOP;
		break;

	case T_BLOCK:
		tp->t_state &= ~TTXON;
		tp->t_state |= TBLOCK;
		if (tp->t_state&BUSY)
			tp->t_state |= TTXOFF;
		else
			addr->tbuf = CSTOP;
		break;

	case T_RFLUSH:
		if (!(tp->t_state&TBLOCK))
			break;
	case T_UNBLOCK:
		tp->t_state &= ~(TTXOFF|TBLOCK);
		if (tp->t_state&BUSY)
			tp->t_state |= TTXON;
		else
			addr->tbuf = CSTART;
		break;

	case T_BREAK:
		addr->tcsr |= XBRK;
		tp->t_state |= TIMEOUT;
		timeout(ttrstrt, tp, HZ/4);
		break;
	}
}

dlclr()
{
	register dev;
	register struct device *addr;
	register struct tty *tp;

	for (dev = 0; dev < dl_cnt; dev++) {
		tp = &dl_tty[dev];
		if ((tp->t_state&(ISOPEN|WOPEN)) == 0)
			continue;
		addr = dl_addr[dev];
		addr->rcsr |= IE|DSIE|RTS|DTR;
		addr->tcsr |= IE;
		tp->t_state &= ~BUSY;
		dlproc(tp, T_OUTPUT);
	}
}