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

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

/*
 *  Versatec matrix printer/plotter dma interface driver
 */

#include "sys/param.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/buf.h"
#include "sys/systm.h"
#include "sys/ioctl.h"
#include "sys/peri.h"

#define	VPPRI	(PZERO+10)

struct device {
	short	plbcr, pbae, prbcr, pbaddr;
	short	plcsr, plbuf, prcsr, prbuf;
};

struct device *vp_addr[];
int	vp_cnt;

/* status bits */
#define	ERROR	0100000
#define	READY	0200
#define	IENABLE	0100
#define	FFCOM	020
#define	RESET	02
#define	SPP	01

/*states */
#define	PRINT	0100
#define	PLOT	0200
#define	PPLOT	0400

vpopen(dev)
register dev;
{
	register struct vp *vp;
	register short *vpaddr;

	if (dev>=vp_cnt || (vp = &vp_vp[dev])->vp_buf) {
		u.u_error = ENXIO;
		return;
	}
	vpaddr = &(vp_addr[dev]->plcsr);
	*vpaddr = IENABLE|RESET;
	vp->vp_state = PRINT;
	if (vpready(dev)<0) {
		*vpaddr = 0;
		u.u_error = EIO;
		return;
	}
	*vpaddr = IENABLE|FFCOM;
	vp->vp_buf = geteblk();
	vp->vp_offset = vp->vp_count = 0;
}

vpclose(dev)
{
	register struct vp *vp;
	register short *vpaddr;

	vp = &vp_vp[dev];
	vpaddr = &(vp_addr[dev]->plcsr);
	vpready(dev);
	*vpaddr = 0;
	if (vp->vp_buf)
		brelse(vp->vp_buf);
	vp->vp_buf = 0;
}

vpwrite(dev)
register dev;
{
	register struct vp *vp;
	register struct device *vpaddr;
	extern	_sdata;

	vp = &vp_vp[dev];
	vpaddr = vp_addr[dev];
	if (vp->vp_count) {
		u.u_error = EIO;
		return;
	}
	while (u.u_count && u.u_error==0) {
		vp->vp_count = min(256,u.u_count);
		iomove(paddr(vp->vp_buf)+vp->vp_offset, vp->vp_count, B_WRITE);
		if (vpready(dev)<0) {
			u.u_error = EIO;
			vpaddr->plcsr = IENABLE|RESET;
			break;
		}
		vpaddr->pbaddr = (int)(paddr(vp->vp_buf)) - (int)(&_sdata) + vp->vp_offset;
		if (vp->vp_state&PLOT)
			vpaddr->plbcr = vp->vp_count; else
			vpaddr->prbcr = vp->vp_count;
		vp->vp_offset = 256 - vp->vp_offset;
		if (vp->vp_state&PPLOT)
			vp->vp_state = PLOT;
	}
	vp->vp_count = 0;
}

vpready(dev)
{
	register struct vp *vp;
	register short *vpaddr;

	vp = &vp_vp[dev];
	vpaddr = (vp->vp_state&PLOT)?&(vp_addr[dev]->plcsr):
		&(vp_addr[dev]->prcsr);
	spl4();
	while ((*vpaddr&(READY|ERROR))==0)
		sleep(vp, VPPRI);
	spl0();
	return(*vpaddr);
}

vpioctl(dev, cmd, arg, mode)
{
	register struct vp *vp;
	register short *vpaddr;
	register bit;
	int tt[1];

	vp = &vp_vp[dev];
	vpaddr = &(vp_addr[dev]->plcsr);
	switch(cmd) {
	case IOCTYPE:
		u.u_rval1 = LIOC;
		break;
	case LIOCGETS:
	case TIOCGETP:
		u.u_rval1 = vp->vp_state;
		break;
	case TIOCSETP:
		if (copyin(arg, tt, sizeof(tt))) {
			u.u_error = EFAULT;
			return;
		}
		arg = tt[0];
	case LIOCSETS:
		vpready(dev);
		vp->vp_state = arg;
		if (vp->vp_state&PPLOT)
			*vpaddr = IENABLE|SPP; else
			*vpaddr = IENABLE;
		for (bit=2; bit<IENABLE; bit<<=1)
			if (vp->vp_state&bit) {
				vpready(dev);
				*vpaddr |= bit;
				vp->vp_state &= ~bit;
			}
		break;
	default:
		u.u_error = EINVAL;
	}
}

vpintr(dev)
{
	wakeup(&vp_vp[dev]);
}