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

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

/*
 *	Console/LSI interface
 */
#include "sys/param.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/tty.h"
#include "sys/buf.h"
#include "sys/systm.h"
#include "sys/cons.h"
#include "sys/conf.h"
#include "sys/sysinfo.h"
#include "sys/mtpr.h"

struct	tty con_tty;

struct	floppy	{
	struct buf *	f_buf;
	unsigned char *	f_ptr;
	short	f_cnt;
	short	f_sec;
	short	f_trk;
	char	f_state;
	char	f_errcnt;
} con_flp;

int	conproc();
int	ttrstrt();
char	partab[];

#define	CONSOLE	0
#define	FLOPPY	1

#define	FSIDLE	1
#define	FSRWC	3
#define	FSSEC	4
#define	FSTRK	5
#define	FSRDATA	6
#define	FSXDATA	7
#define	FSDONE	8
#define	FSABORT	10

conopen(dev, flag)
dev_t dev;
{
	if (dev == CONSOLE) {
		register struct tty *tp;
	
		tp = &con_tty;
		tp->t_proc = conproc;
		if ((tp->t_state&ISOPEN) == 0) {
			ttinit(tp);
			tp->t_state = ISOPEN|CARR_ON;
			tp->t_iflag |= ICRNL;
			tp->t_oflag |= OPOST|ONLCR|TAB3;
			tp->t_lflag |= ISIG|ICANON|ECHO|ECHOK;
			mtpr(RXCS, C_IE);
			mtpr(TXCS, C_IE);
		}
		(*linesw[tp->t_line].l_open)(tp);
	} else if (dev == FLOPPY) {
		register struct floppy *fp;

		fp = &con_flp;
		if (fp->f_state)
			u.u_error = ENXIO;
		else {
			fp->f_state = FSIDLE;
			fp->f_buf = geteblk();
			fp->f_buf->b_flags = 0;
		}
	} else
		u.u_error = ENXIO;
}

conclose(dev)
dev_t dev;
{
	if (dev == CONSOLE) {
		register struct tty *tp;

		tp = &con_tty;
		(*linesw[tp->t_line].l_close)(tp);
		tp->t_state = 0;
	} else if (dev == FLOPPY) {
		brelse(con_flp.f_buf);
		con_flp.f_state = 0;
	}
}

conread(dev)
dev_t dev;
{
	if (dev == CONSOLE) {
		ttread(&con_tty);
	} else if (dev == FLOPPY) {
		confpio(B_READ);
	}
}

conwrite(dev)
dev_t dev;
{
	if (dev == CONSOLE) {
		ttwrite(&con_tty);
	} else if (dev == FLOPPY) {
		confpio(B_WRITE);
	}
}

conxint(dev)
{
	register struct tty *tp;

	sysinfo.xmtint++;
	tp = &con_tty;
	if (mfpr(TXCS) & C_DONE) {
		tp->t_state &= ~BUSY;
		conproc(tp, T_OUTPUT);
	}
}

conrint(dev)
{
	register struct tty *tp;
	register c;

	sysinfo.rcvint++;
	tp = &con_tty;
	while (mfpr(RXCS) & C_DONE) {
		c = mfpr(RXDB);
		if ((c & C_CID) == 0)
			(*linesw[tp->t_line].l_input)(tp, c, 0);
		else
			confrcv(c);
	}
}

conioctl(dev, cmd, arg, mode)
{
	if (dev == CONSOLE)
		ttiocom(&con_tty, cmd, arg, mode);
}

conproc(tp, cmd)
register struct tty *tp;
{
	register c;

	switch (cmd) {

	case T_TIME:
		tp->t_state &= ~TIMEOUT;
		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 ? */
			mtpr(TXDB, c & C_DATA);
			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);
		}
		if ((tp->t_state&BUSY) == 0 && con_flp.f_state > FSIDLE)
			confxmt();
		break;

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

	case T_BLOCK:
		tp->t_state |= TBLOCK;
		break;

	case T_RFLUSH:
	case T_UNBLOCK:
		tp->t_state &= ~TBLOCK;
		break;
	}
}

putchar(c)
register c;
{
	register s;

	while((mfpr(TXCS) & C_DONE) == 0)
		;
	if(c == 0)
		return;
	s = mfpr(TXCS);
	mtpr(TXCS,0);
	mtpr(TXDB, c & C_DATA);
	if(c == '\n') {
		putchar('\r');
	}
	putchar(0);
	mtpr(TXCS, s);
}

confpio(rw)
{
	register struct floppy *fp = &con_flp;
	register struct buf *bp;
	register cnt;

	bp = fp->f_buf;
	spl4();
	while (bp->b_flags&B_BUSY)
		sleep((caddr_t)&con_flp, PRIBIO);
	bp->b_flags = B_BUSY;
	spl0();
	while (u.u_count) {
		bp->b_blkno = u.u_offset/FSIZE;
		if (bp->b_blkno >= (FTRK-1)*FSEC || u.u_offset%FSIZE) {
			u.u_error = ENXIO;
			break;
		}
		cnt = min(FSIZE, u.u_count);
		if (rw == B_WRITE) {
			iomove(bp->b_un.b_addr, cnt, B_WRITE);
			if (u.u_error)
				break;
		}
		fp->f_errcnt = 0;
		bp->b_flags |= rw;
		bp->b_flags &= ~B_DONE;
		{
			register sec,trk;

			trk = bp->b_blkno/FSEC;
			sec = bp->b_blkno%FSEC;
			sec = (sec*2 + (sec>=13) + trk*6)%26;
			fp->f_trk = F_DATA | (trk + 1);
			fp->f_sec = F_DATA | (sec + 1);
		}
		spl4();
		fp->f_state = FSRWC;
		conproc(&con_tty, T_OUTPUT);
		while ((bp->b_flags&B_DONE) == 0)
			sleep((caddr_t)bp, PRIBIO);
		spl0();
		if (bp->b_flags&B_ERROR) {
			u.u_error = EIO;
			break;
		}
		if (rw == B_READ) {
			iomove(bp->b_un.b_addr, cnt, B_READ);
			if (u.u_error)
				break;
		}
	}
	bp->b_flags = 0;
	wakeup((caddr_t)&con_flp);
}

confxmt()
{
	register struct floppy *fp = &con_flp;
	register struct buf *bp;

	bp = fp->f_buf;
	switch(fp->f_state) {
	case FSRWC:
		fp->f_cnt = FSIZE;
		fp->f_ptr = (unsigned char *)bp->b_un.b_addr;
		mtpr(TXDB, bp->b_flags&B_READ?F_READ:F_WRITE);
		fp->f_state = FSSEC;
		break;
	case FSSEC:
		mtpr(TXDB, fp->f_sec);
		fp->f_state = FSTRK;
		break;
	case FSTRK:
		mtpr(TXDB, fp->f_trk);
		fp->f_state = bp->b_flags&B_READ?FSDONE:FSXDATA;
		break;
	case FSXDATA:
		mtpr(TXDB, F_DATA|(int)*fp->f_ptr++);
		if (--fp->f_cnt == 0)
			fp->f_state = FSDONE;
		break;
	case FSABORT:
		mtpr(TXDB, F_CAN);
		if (++fp->f_errcnt <= 8) {
			fp->f_state = FSRWC;
		} else {
			bp->b_flags |= B_ERROR|B_DONE;
			fp->f_state = FSIDLE;
			wakeup(bp);
		}
		break;
	default:
		return;
	}
	con_tty.t_state |= BUSY;
}

confrcv(c)
register c;
{
	register struct floppy *fp = &con_flp;
	register struct buf *bp;

	bp = fp->f_buf;
	switch (c & C_CID) {
	case F_DATA:
		if (fp->f_state != FSRDATA) {
			fp->f_state = FSABORT;
			break;
		}
		*fp->f_ptr++ = c & C_DATA;
		if (--fp->f_cnt == 0) {
			fp->f_state = FSIDLE;
			bp->b_flags |= B_DONE;
			wakeup(bp);
		}
		break;
	case F_FFC:
		if (fp->f_state != FSDONE || (c & C_DATA)) {
			fp->f_state = FSABORT;
			break;
		}
		if (bp->b_flags&B_READ) {
			fp->f_state = FSRDATA;
		} else {
			fp->f_state = FSIDLE;
			bp->b_flags |= B_DONE;
			wakeup(bp);
		}
		break;
	case F_FLP:
		fp->f_state = FSABORT;
		break;
	}
	if (fp->f_state == FSABORT)
		conproc(&con_tty, T_OUTPUT);
}

conclr()
{
	register struct tty *tp;

	tp = &con_tty;
	if((tp->t_state&ISOPEN) == 0)
		return;
	mtpr(RXCS, C_IE);
	mtpr(TXCS, C_IE);
	tp->t_state &= ~BUSY;
	conproc(tp, T_OUTPUT);
}