Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/devlpt.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/devlpt.c 1991/1204
## diff -e /dev/null /n/bootesdump/1991/1204/sys/src/9/safari/devlpt.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"errno.h"

/* Centronix parallel (printer) port */

/* base addresses */
int lptbase[] = {
	0x3bc,	/* lpt1 */
	0x378,	/* lpt2 (sic) */
	0x278	/* lpt3 (sic) */
};
#define NDEV	(sizeof lptbase/sizeof lptbase[0])

/* offsets, and bits in the registers */
enum
{
	/* data latch register */
	Qdlr=		0x0,
	/* printer status register */
	Qpsr=		0x1,
	Fnotbusy=	0x80,
	Fack=		0x40,
	Fpe=		0x20,
	Fselect=	0x10,
	Fnoerror=	0x08,
	/* printer control register */
	Qpcr=		0x2,
	Fie=		0x10,
	Fselectin=	0x08,
	Finitbar=	0x04,
	Faf=		0x02,
	Fstrobe=	0x01,
	/* fake `data register' */
	Qdata=		0x3,
};

static int	lptready(void*);
static void	outch(int, int);
static void	lptintr(Ureg*);

static Rendez	lptrendez;

Dirtab lptdir[]={
	"dlr",		{Qdlr},		1,		0666,
	"psr",		{Qpsr},		5,		0444,
	"pcr",		{Qpcr},		0,		0222,
	"data",		{Qdata},	0,		0222,
};
#define NLPT	(sizeof lptdir/sizeof lptdir[0])

static int
lptgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
	Qid qid;
	char name[NAMELEN];

	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	qid = tab->qid;
	if(qid.path < Qdata)
		qid.path += lptbase[c->dev];
	qid.vers = c->dev;
	sprint(name, "lpt%d%s", c->dev+1, tab->name);
	devdir(c, qid, name, tab->length, eve, tab->perm, dp);
	return 1;
}

void
lptreset(void)
{
	setvec(Parallelvec, lptintr);
}

void
lptinit(void)
{}

Chan*
lptattach(char *spec)
{
	Chan *c;
	int i  = (spec && *spec) ? strtol(spec, 0, 0) : 1;

	if(i < 1 || i > NDEV)
		errors("spec out of range");
	c = devattach('L', spec);
	c->dev = i-1;
	return c;
}

Chan*
lptclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
lptwalk(Chan *c, char *name)
{
	return devwalk(c, name, lptdir, NLPT, lptgen);
}

void
lptstat(Chan *c, char *dp)
{
	devstat(c, dp, lptdir, NLPT, lptgen);
}

Chan*
lptopen(Chan *c, int omode)
{
	return devopen(c, omode, lptdir, NLPT, lptgen);
}

void
lptcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(Eperm);
}

void
lptclose(Chan *c)
{}

void
lptremove(Chan *c)
{
	error(Eperm);
}

void
lptwstat(Chan *c, char *dp)
{
	error(Eperm);
}

long
lptread(Chan *c, void *a, long n)
{
	char str[16]; int size;

	if(c->qid.path == CHDIR)
		return devdirread(c, a, n, lptdir, NLPT, lptgen);
	size = sprint(str, "0x%2.2ux\n", inb(c->qid.path));
	if(c->offset >= size)
		return 0;
	if(c->offset+n > size)
		n = size-c->offset;
	memmove(a, str+c->offset, n);
	return n;
}

long
lptwrite(Chan *c, void *a, long n)
{
	char str[16], *p;
	long base, k;

	if(n <= 0)
		return 0;
	if(c->qid.path != Qdata){
		if(n > sizeof str-1)
			n = sizeof str-1;
		memmove(str, a, n);
		str[n] = 0;
		outb(c->qid.path, strtoul(str, 0, 0));
		return n;
	}
	p = a;
	k = n;
	base = lptbase[c->dev];
	if(waserror()){
		outb(base+Qpcr, Finitbar);
		nexterror();
	}
	while(--k >= 0)
		outch(base, *p++);
	poperror();
	return n;
}

static void
outch(int base, int c)
{
	int status = inb(base+Qpsr);

	if(!(status & Fselect) || !(status & Fnoerror))
		error(Eio);
	if(!(status & Fnotbusy)){
		outb(base+Qpcr, Finitbar|Fie);
		sleep(&lptrendez, lptready, (void *)base);
	}
	outb(base+Qdlr, c);
	outb(base+Qpcr, Finitbar|Fstrobe);
	outb(base+Qpcr, Finitbar);
}

static int
lptready(void *base)
{
	return inb((int)base+Qpsr)&Fnotbusy;
}

static void
lptintr(Ureg *ur)
{
	wakeup(&lptrendez);
}
.
## diffname pc/devlpt.c 1992/0111
## diff -e /n/bootesdump/1991/1204/sys/src/9/safari/devlpt.c /n/bootesdump/1992/0111/sys/src/9/safari/devlpt.c
7c
#include	"../port/error.h"
.
## diffname pc/devlpt.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/safari/devlpt.c /n/bootesdump/1992/0114/sys/src/9/safari/devlpt.c
91c
		error(Ebadarg);
.
## diffname pc/devlpt.c 1992/0205
## diff -e /n/bootesdump/1992/0114/sys/src/9/safari/devlpt.c /n/bootesdump/1992/0205/sys/src/9/safari/devlpt.c
12c
static int lptbase[] = {
.
## diffname pc/devlpt.c 1992/0321
## diff -e /n/bootesdump/1992/0205/sys/src/9/safari/devlpt.c /n/bootesdump/1992/0321/sys/src/9/safari/devlpt.c
2c
#include	"../port/lib.h"
.
## diffname pc/devlpt.c 1992/0711
## diff -e /n/bootesdump/1992/0321/sys/src/9/safari/devlpt.c /n/bootesdump/1992/0711/sys/src/9/safari/devlpt.c
212a
	USED(ur);
.
139a
	USED(c, dp);
.
133a
	USED(c);
.
129c
{
	USED(c);
}
.
123a
	USED(c, name, omode, perm);
.
## diffname pc/devlpt.c 1993/0224
## diff -e /n/bootesdump/1992/0808/sys/src/9/safari/devlpt.c /n/bootesdump/1993/0224/sys/src/9/pc/devlpt.c
89a
	if(!set){
		set = 1;
		setvec(Parallelvec, lptintr);
	}
.
88a
	static int set;
.
77d
## diffname pc/devlpt.c 1994/0324
## diff -e /n/bootesdump/1993/0224/sys/src/9/pc/devlpt.c /n/fornaxdump/1994/0324/sys/src/brazil/pc/devlpt.c
222c
	USED(ur, arg);
.
220c
lptintr(Ureg *ur, void *arg)
.
92c
		setvec(Parallelvec, lptintr, 0);
.
44c
static void	lptintr(Ureg*, void*);
.
13,14c
	0x378,	/* lpt1 */
	0x3bc,	/* lpt2 */
.
## diffname pc/devlpt.c 1994/0331
## diff -e /n/fornaxdump/1994/0324/sys/src/brazil/pc/devlpt.c /n/fornaxdump/1994/0331/sys/src/brazil/pc/devlpt.c
202,206c
	for(tries = 0;; tries++){
		status = inb(base+Qpsr);
		if(!(status & Fselect) || !(status & Fnoerror))
			error(Eio);
		if(status & Fnotbusy)
			break;
		if(tries > 1000){
			outb(base+Qpcr, Finitbar|Fie);
			tsleep(&lptrendez, lptready, (void *)base, MS2HZ);
		}
.
200c
	int status, tries;
.
## diffname pc/devlpt.c 1994/0513
## diff -e /n/fornaxdump/1994/0331/sys/src/brazil/pc/devlpt.c /n/fornaxdump/1994/0513/sys/src/brazil/pc/devlpt.c
90a
		outb(lptbase[i-1]+Qpcr, 0);	/* turn off interrupts */
.
## diffname pc/devlpt.c 1995/0108
## diff -e /n/fornaxdump/1994/0513/sys/src/brazil/pc/devlpt.c /n/fornaxdump/1995/0108/sys/src/brazil/pc/devlpt.c
195a
}

long
lptbwrite(Chan *c, Block *bp, ulong offset)
{
	return devbwrite(c, bp, offset);
.
168a
Block*
lptbread(Chan *c, long n, ulong offset)
{
	return devbread(c, n, offset);
}

.
## diffname pc/devlpt.c 1995/0726
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/pc/devlpt.c /n/fornaxdump/1995/0726/sys/src/brazil/pc/devlpt.c
129d
127c
lptcreate(Chan*, char*, int, ulong)
.
## diffname pc/devlpt.c 1997/0327
## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/pc/devlpt.c /n/emeliedump/1997/0327/sys/src/brazil/pc/devlpt.c
241a

Dev lptdevtab = {
	devreset,
	devinit,
	lptattach,
	devclone,
	lptwalk,
	lptstat,
	lptopen,
	devcreate,
	lptclose,
	lptread,
	devbread,
	lptwrite,
	devbwrite,
	devremove,
	devwstat,
};
.
203,208d
171,176d
168,169c
static long
lptwrite(Chan *c, void *a, long n, ulong)
.
158c
		return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen);
.
141,154d
138,139c
static long
lptread(Chan *c, void *a, long n, ulong)
.
126,132c
static void
.
123c
	return devopen(c, omode, lptdir, nelem(lptdir), lptgen);
.
120c
static Chan*
.
117c
	devstat(c, dp, lptdir, nelem(lptdir), lptgen);
.
114c
static void
.
111c
	return devwalk(c, name, lptdir, nelem(lptdir), lptgen);
.
102,108c
static int
.
93c
		intrenable(VectorLPT, lptintr, 0, BUSUNKNOWN);
.
74,83c
static Chan*
.
54d
## diffname pc/devlpt.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/devlpt.c /n/emeliedump/1997/0408/sys/src/brazil/pc/devlpt.c
195a
	'L',
	"lpt",

.
## diffname pc/devlpt.c 1998/0319
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/pc/devlpt.c /n/emeliedump/1998/0319/sys/src/brazil/pc/devlpt.c
191d
189c
lptintr(Ureg *, void *)
.
133c
lptwrite(Chan *c, void *a, long n, vlong)
.
128c
	memmove(a, str+o, n);
.
126c
	if(o+n > size)
.
124c
	o = c->offset;
	if(o >= size)
.
119c
	char str[16];
	int size;
	ulong o;
.
117c
lptread(Chan *c, void *a, long n, vlong)
.
113d
111c
lptclose(Chan *)
.
## diffname pc/devlpt.c 1998/0825
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/pc/devlpt.c /n/emeliedump/1998/0825/sys/src/brazil/pc/devlpt.c
68c
	sprint(name, "lpt%lud%s", c->dev+1, tab->name);
.
## diffname pc/devlpt.c 1998/0910
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/pc/devlpt.c /n/emeliedump/1998/0910/sys/src/brazil/pc/devlpt.c
83c
		intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN);
.
## diffname pc/devlpt.c 1999/0714
## diff -e /n/emeliedump/1998/0910/sys/src/brazil/pc/devlpt.c /n/emeliedump/1999/0714/sys/src/brazil/pc/devlpt.c
86a
	if(lptallocd[i-1] == 0){
		sprint(name, "lpt%d", i-1);
		if(ioalloc(lptbase[i-1], 3, 0, name) < 0)
			error("lpt port space in use");
		lptallocd[i-1] = 1;
	}
.
77a
	char name[5];
.
17c
#define NDEV	nelem(lptbase)
static int lptallocd[NDEV];
.
## diffname pc/devlpt.c 1999/0819
## diff -e /n/emeliedump/1999/0714/sys/src/brazil/pc/devlpt.c /n/emeliedump/1999/0819/sys/src/brazil/pc/devlpt.c
85c
		intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN, "lpt");
.
## diffname pc/devlpt.c 1999/1230
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/pc/devlpt.c /n/emeliedump/1999/1230/sys/src/9/pc/devlpt.c
61a
	if(i == DEVDOTDOT){
		sprint(name, "#L%lud", c->dev+1);
		devdir(c, (Qid){CHDIR, 0}, name, 0, eve, 0555, dp);
		return 1;
	}
.
## diffname pc/devlpt.c 2000/0813
## diff -e /n/emeliedump/1999/1230/sys/src/9/pc/devlpt.c /n/emeliedump/2000/0813/sys/src/9/pc/devlpt.c
189c
			tsleep(&lptrendez, lptready, (void *)base, 100);
.
187c
		if((status&Fpe)==0 && (status&(Fselect|Fnoerror)) != (Fselect|Fnoerror))
			error(Eio);
		if(tries < 10)
			tsleep(&lptrendez, return0, nil, 1);
		else {
.
183,185c
		if(status&Fnotbusy)
.
181c
	for(tries=0;; tries++) {
.
## diffname pc/devlpt.c 2001/0413
## diff -e /n/emeliedump/2000/0813/sys/src/9/pc/devlpt.c /n/emeliedump/2001/0413/sys/src/9/pc/devlpt.c
98a
		// Detect ECP - if found, put into PS/2 mode to suit style of driver
		ecr = lptbase[i-1] + 0x402;
		if ((inb(ecr) & 3) == 1) {
			outb(ecr, 0x34);
			if (inb(ecr) == 0x35) {
				outb(ecr, (inb(ecr) & 0x1f) | (1 << 5));
				if(ioalloc(ecr, 1, 0, name) < 0)
					error("lpt ecr port space in use");
			}
		}
.
94a
		int ecr;
.
## diffname pc/devlpt.c 2001/0527
## diff -e /n/emeliedump/2001/0413/sys/src/9/pc/devlpt.c /n/emeliedump/2001/0527/sys/src/9/pc/devlpt.c
229d
146c
	if(c->qid.path == Qdir)
.
125c
	return devstat(c, dp, n, lptdir, nelem(lptdir), lptgen);
.
122,123c
static int
lptstat(Chan *c, uchar *dp, int n)
.
119c
	return devwalk(c, nc, name, nname, lptdir, nelem(lptdir), lptgen);
.
116,117c
static Walkqid*
lptwalk(Chan *c, Chan *nc, char **name, int nname)
.
111a
	c->qid.path = Qdir;
.
74,75c
	sprint(up->genbuf, "lpt%lud%s", c->dev+1, tab->name);
	devdir(c, qid, up->genbuf, tab->length, eve, tab->perm, dp);
.
70a
	qid.path &= ~Qdir;
.
66a
	i++; /* skip first element for . itself */
.
63,64c
		mkqid(&qid, Qdir, 0, QTDIR);
		devdir(c, qid, ".", 0, eve, 0555, dp);
.
60d
57c
lptgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
.
50,53c
	".",	{Qdir, 0, QTDIR},	0,	DMDIR|0555,
	"dlr",	{Qdlr},			1,	0666,
	"psr",	{Qpsr},			5,	0444,
	"pcr",	{Qpcr},			0,	0222,
	"data",	{Qdata},		0,	0222,
.
22a
	Qdir=		0x8000,
.
## diffname pc/devlpt.c 2002/0109
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/devlpt.c /n/emeliedump/2002/0109/sys/src/9/pc/devlpt.c
231a
	devshutdown,
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].