plan 9 kernel history: overview | file list | diff list

1997/0327/pc/devlpt.c (diff list | history)

1991/1204/sys/src/9/pc/devlpt.c:4,101992/0111/sys/src/9/pc/devlpt.c:4,10 (short | long)
1991/1204    
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
#include	"errno.h" 
1992/0111    
#include	"../port/error.h" 
1991/1204    
 
/* Centronix parallel (printer) port */ 
 
1992/0111/sys/src/9/pc/devlpt.c:88,941992/0114/sys/src/9/pc/devlpt.c:88,94 (short | long)
1991/1204    
	int i  = (spec && *spec) ? strtol(spec, 0, 0) : 1; 
 
	if(i < 1 || i > NDEV) 
		errors("spec out of range"); 
1992/0114    
		error(Ebadarg); 
1991/1204    
	c = devattach('L', spec); 
	c->dev = i-1; 
	return c; 
1992/0114/sys/src/9/pc/devlpt.c:9,151992/0205/sys/src/9/pc/devlpt.c:9,15 (short | long)
1991/1204    
/* Centronix parallel (printer) port */ 
 
/* base addresses */ 
int lptbase[] = { 
1992/0205    
static int lptbase[] = { 
1991/1204    
	0x3bc,	/* lpt1 */ 
	0x378,	/* lpt2 (sic) */ 
	0x278	/* lpt3 (sic) */ 
1992/0205/sys/src/9/pc/devlpt.c:1,51992/0321/sys/src/9/pc/devlpt.c:1,5 (short | long)
1991/1204    
#include	"u.h" 
#include	"lib.h" 
1992/0321    
#include	"../port/lib.h" 
1991/1204    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0321/sys/src/9/pc/devlpt.c:121,1361992/0711/sys/src/9/pc/devlpt.c:121,140 (short | long)
1991/1204    
void 
lptcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1992/0711    
	USED(c, name, omode, perm); 
1991/1204    
	error(Eperm); 
} 
 
void 
lptclose(Chan *c) 
{} 
1992/0711    
{ 
	USED(c); 
} 
1991/1204    
 
void 
lptremove(Chan *c) 
{ 
1992/0711    
	USED(c); 
1991/1204    
	error(Eperm); 
} 
 
1992/0321/sys/src/9/pc/devlpt.c:137,1421992/0711/sys/src/9/pc/devlpt.c:141,147
1991/1204    
void 
lptwstat(Chan *c, char *dp) 
{ 
1992/0711    
	USED(c, dp); 
1991/1204    
	error(Eperm); 
} 
 
1992/0321/sys/src/9/pc/devlpt.c:210,2141992/0711/sys/src/9/pc/devlpt.c:215,220
1991/1204    
static void 
lptintr(Ureg *ur) 
{ 
1992/0711    
	USED(ur); 
1991/1204    
	wakeup(&lptrendez); 
} 
1992/0711/sys/src/9/pc/devlpt.c:74,801993/0224/sys/src/9/pc/devlpt.c:74,79 (short | long)
Bug fix?: delay setvec to attach time.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
void 
lptreset(void) 
{ 
	setvec(Parallelvec, lptintr); 
} 
 
void 
1992/0711/sys/src/9/pc/devlpt.c:86,921993/0224/sys/src/9/pc/devlpt.c:85,96
1991/1204    
{ 
	Chan *c; 
	int i  = (spec && *spec) ? strtol(spec, 0, 0) : 1; 
1993/0224    
	static int set; 
1991/1204    
 
1993/0224    
	if(!set){ 
		set = 1; 
		setvec(Parallelvec, lptintr); 
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1991/1204    
	c = devattach('L', spec); 
1993/0224/sys/src/9/pc/devlpt.c:10,171994/0324/sys/src/9/pc/devlpt.c:10,17 (short | long)
New interrupt interface. Bug fix?: swap lpt1, lpt2.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
 
/* base addresses */ 
1992/0205    
static int lptbase[] = { 
1991/1204    
	0x3bc,	/* lpt1 */ 
	0x378,	/* lpt2 (sic) */ 
1994/0324    
	0x378,	/* lpt1 */ 
	0x3bc,	/* lpt2 */ 
1991/1204    
	0x278	/* lpt3 (sic) */ 
}; 
#define NDEV	(sizeof lptbase/sizeof lptbase[0]) 
1993/0224/sys/src/9/pc/devlpt.c:41,471994/0324/sys/src/9/pc/devlpt.c:41,47
1991/1204    
 
static int	lptready(void*); 
static void	outch(int, int); 
static void	lptintr(Ureg*); 
1994/0324    
static void	lptintr(Ureg*, void*); 
1991/1204    
 
static Rendez	lptrendez; 
 
1993/0224/sys/src/9/pc/devlpt.c:89,951994/0324/sys/src/9/pc/devlpt.c:89,95
1991/1204    
 
1993/0224    
	if(!set){ 
		set = 1; 
		setvec(Parallelvec, lptintr); 
1994/0324    
		setvec(Parallelvec, lptintr, 0); 
1993/0224    
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1993/0224/sys/src/9/pc/devlpt.c:217,2241994/0324/sys/src/9/pc/devlpt.c:217,224
1991/1204    
} 
 
static void 
lptintr(Ureg *ur) 
1994/0324    
lptintr(Ureg *ur, void *arg) 
1991/1204    
{ 
1992/0711    
	USED(ur); 
1994/0324    
	USED(ur, arg); 
1991/1204    
	wakeup(&lptrendez); 
} 
1994/0324/sys/src/9/pc/devlpt.c:197,2091994/0331/sys/src/9/pc/devlpt.c:197,214 (short | long)
Loop a bit waiting for printer before going to sleep.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
static void 
outch(int base, int c) 
{ 
	int status = inb(base+Qpsr); 
1994/0331    
	int status, tries; 
1991/1204    
 
	if(!(status & Fselect) || !(status & Fnoerror)) 
		error(Eio); 
	if(!(status & Fnotbusy)){ 
		outb(base+Qpcr, Finitbar|Fie); 
		sleep(&lptrendez, lptready, (void *)base); 
1994/0331    
	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); 
		} 
1991/1204    
	} 
	outb(base+Qdlr, c); 
	outb(base+Qpcr, Finitbar|Fstrobe); 
1994/0331/sys/src/9/pc/devlpt.c:88,931994/0513/sys/src/9/pc/devlpt.c:88,94 (short | long)
Bug fix: turn off interrupts until we want them.
rsc Fri Mar 4 12:44:25 2005
1993/0224    
	static int set; 
1991/1204    
 
1993/0224    
	if(!set){ 
1994/0513    
		outb(lptbase[i-1]+Qpcr, 0);	/* turn off interrupts */ 
1993/0224    
		set = 1; 
1994/0324    
		setvec(Parallelvec, lptintr, 0); 
1993/0224    
	} 
1994/0513/sys/src/9/pc/devlpt.c:166,1711995/0108/sys/src/9/pc/devlpt.c:166,177 (short | long)
Add lptbread, lptbwrite.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
	return n; 
} 
 
1995/0108    
Block* 
lptbread(Chan *c, long n, ulong offset) 
{ 
	return devbread(c, n, offset); 
} 
 
1991/1204    
long 
lptwrite(Chan *c, void *a, long n) 
{ 
1994/0513/sys/src/9/pc/devlpt.c:193,1981995/0108/sys/src/9/pc/devlpt.c:199,210
1991/1204    
		outch(base, *p++); 
	poperror(); 
	return n; 
1995/0108    
} 
 
long 
lptbwrite(Chan *c, Block *bp, ulong offset) 
{ 
	return devbwrite(c, bp, offset); 
1991/1204    
} 
 
static void 
1995/0108/sys/src/9/pc/devlpt.c:124,1321995/0726/sys/src/9/pc/devlpt.c:124,131 (short | long)
Anonymize lptcreate.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
} 
 
void 
lptcreate(Chan *c, char *name, int omode, ulong perm) 
1995/0726    
lptcreate(Chan*, char*, int, ulong) 
1991/1204    
{ 
1992/0711    
	USED(c, name, omode, perm); 
1991/1204    
	error(Eperm); 
} 
 
1995/0726/sys/src/9/pc/devlpt.c:51,571997/0327/sys/src/9/pc/devlpt.c:51,56 (short | long)
Clean up driver. No bug fixes.
Remove NLPT in favor of nelem.
Remove trivial functions in favor of dev*.
Use new intrenable.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
	"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) 
1995/0726/sys/src/9/pc/devlpt.c:71,861997/0327/sys/src/9/pc/devlpt.c:70,76
1991/1204    
	return 1; 
} 
 
void 
lptreset(void) 
{ 
} 
                 
void 
lptinit(void) 
{} 
                 
Chan* 
1997/0327    
static Chan* 
1991/1204    
lptattach(char *spec) 
{ 
	Chan *c; 
1995/0726/sys/src/9/pc/devlpt.c:90,961997/0327/sys/src/9/pc/devlpt.c:80,86
1993/0224    
	if(!set){ 
1994/0513    
		outb(lptbase[i-1]+Qpcr, 0);	/* turn off interrupts */ 
1993/0224    
		set = 1; 
1994/0324    
		setvec(Parallelvec, lptintr, 0); 
1997/0327    
		intrenable(VectorLPT, lptintr, 0, BUSUNKNOWN); 
1993/0224    
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1995/0726/sys/src/9/pc/devlpt.c:99,1611997/0327/sys/src/9/pc/devlpt.c:89,125
1991/1204    
	return c; 
} 
 
Chan* 
lptclone(Chan *c, Chan *nc) 
{ 
	return devclone(c, nc); 
} 
                 
int 
1997/0327    
static int 
1991/1204    
lptwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, lptdir, NLPT, lptgen); 
1997/0327    
	return devwalk(c, name, lptdir, nelem(lptdir), lptgen); 
1991/1204    
} 
 
void 
1997/0327    
static void 
1991/1204    
lptstat(Chan *c, char *dp) 
{ 
	devstat(c, dp, lptdir, NLPT, lptgen); 
1997/0327    
	devstat(c, dp, lptdir, nelem(lptdir), lptgen); 
1991/1204    
} 
 
Chan* 
1997/0327    
static Chan* 
1991/1204    
lptopen(Chan *c, int omode) 
{ 
	return devopen(c, omode, lptdir, NLPT, lptgen); 
1997/0327    
	return devopen(c, omode, lptdir, nelem(lptdir), lptgen); 
1991/1204    
} 
 
void 
1995/0726    
lptcreate(Chan*, char*, int, ulong) 
1991/1204    
{ 
	error(Eperm); 
} 
                 
void 
1997/0327    
static void 
1991/1204    
lptclose(Chan *c) 
1992/0711    
{ 
	USED(c); 
} 
1991/1204    
 
void 
lptremove(Chan *c) 
1997/0327    
static long 
lptread(Chan *c, void *a, long n, ulong) 
1991/1204    
{ 
1992/0711    
	USED(c); 
1991/1204    
	error(Eperm); 
} 
                 
void 
lptwstat(Chan *c, char *dp) 
{ 
1992/0711    
	USED(c, dp); 
1991/1204    
	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); 
1997/0327    
		return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen); 
1991/1204    
	size = sprint(str, "0x%2.2ux\n", inb(c->qid.path)); 
	if(c->offset >= size) 
		return 0; 
1995/0726/sys/src/9/pc/devlpt.c:165,1791997/0327/sys/src/9/pc/devlpt.c:129,137
1991/1204    
	return n; 
} 
 
1995/0108    
Block* 
lptbread(Chan *c, long n, ulong offset) 
1997/0327    
static long 
lptwrite(Chan *c, void *a, long n, ulong) 
1995/0108    
{ 
	return devbread(c, n, offset); 
} 
                 
1991/1204    
long 
lptwrite(Chan *c, void *a, long n) 
{ 
	char str[16], *p; 
	long base, k; 
 
1995/0726/sys/src/9/pc/devlpt.c:200,2111997/0327/sys/src/9/pc/devlpt.c:158,163
1991/1204    
	return n; 
1995/0108    
} 
 
long 
lptbwrite(Chan *c, Block *bp, ulong offset) 
{ 
	return devbwrite(c, bp, offset); 
1991/1204    
} 
                 
static void 
outch(int base, int c) 
{ 
1995/0726/sys/src/9/pc/devlpt.c:239,2411997/0327/sys/src/9/pc/devlpt.c:191,211
1994/0324    
	USED(ur, arg); 
1991/1204    
	wakeup(&lptrendez); 
} 
1997/0327    
 
Dev lptdevtab = { 
	devreset, 
	devinit, 
	lptattach, 
	devclone, 
	lptwalk, 
	lptstat, 
	lptopen, 
	devcreate, 
	lptclose, 
	lptread, 
	devbread, 
	lptwrite, 
	devbwrite, 
	devremove, 
	devwstat, 
}; 
1997/0327/sys/src/9/pc/devlpt.c:193,1981997/0408/sys/src/9/pc/devlpt.c:193,201 (short | long)
Add devchar and name to Dev structure.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
} 
1997/0327    
 
Dev lptdevtab = { 
1997/0408    
	'L', 
	"lpt", 
 
1997/0327    
	devreset, 
	devinit, 
	lptattach, 
1997/0408/sys/src/9/pc/devlpt.c:108,1361998/0319/sys/src/9/pc/devlpt.c:108,138 (short | long)
Change dev read and write to use vlong offset. Formatting edits.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
} 
 
1997/0327    
static void 
1991/1204    
lptclose(Chan *c) 
1998/0319    
lptclose(Chan *) 
1992/0711    
{ 
	USED(c); 
} 
1991/1204    
 
1997/0327    
static long 
lptread(Chan *c, void *a, long n, ulong) 
1998/0319    
lptread(Chan *c, void *a, long n, vlong) 
1991/1204    
{ 
	char str[16]; int size; 
1998/0319    
	char str[16]; 
	int size; 
	ulong o; 
1991/1204    
 
	if(c->qid.path == CHDIR) 
1997/0327    
		return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen); 
1991/1204    
	size = sprint(str, "0x%2.2ux\n", inb(c->qid.path)); 
	if(c->offset >= size) 
1998/0319    
	o = c->offset; 
	if(o >= size) 
1991/1204    
		return 0; 
	if(c->offset+n > size) 
1998/0319    
	if(o+n > size) 
1991/1204    
		n = size-c->offset; 
	memmove(a, str+c->offset, n); 
1998/0319    
	memmove(a, str+o, n); 
1991/1204    
	return n; 
} 
 
1997/0327    
static long 
lptwrite(Chan *c, void *a, long n, ulong) 
1998/0319    
lptwrite(Chan *c, void *a, long n, vlong) 
1995/0108    
{ 
1991/1204    
	char str[16], *p; 
	long base, k; 
1997/0408/sys/src/9/pc/devlpt.c:186,1941998/0319/sys/src/9/pc/devlpt.c:188,195
1991/1204    
} 
 
static void 
1994/0324    
lptintr(Ureg *ur, void *arg) 
1998/0319    
lptintr(Ureg *, void *) 
1991/1204    
{ 
1994/0324    
	USED(ur, arg); 
1991/1204    
	wakeup(&lptrendez); 
} 
1997/0327    
 
1998/0319/sys/src/9/pc/devlpt.c:65,711998/0825/sys/src/9/pc/devlpt.c:65,71 (short | long)
Bug fix: print format.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
	if(qid.path < Qdata) 
		qid.path += lptbase[c->dev]; 
	qid.vers = c->dev; 
	sprint(name, "lpt%d%s", c->dev+1, tab->name); 
1998/0825    
	sprint(name, "lpt%lud%s", c->dev+1, tab->name); 
1991/1204    
	devdir(c, qid, name, tab->length, eve, tab->perm, dp); 
	return 1; 
} 
1998/0825/sys/src/9/pc/devlpt.c:80,861998/0910/sys/src/9/pc/devlpt.c:80,86 (short | long)
Change VectorLPT to IrqLPT.
rsc Fri Mar 4 12:44:25 2005
1993/0224    
	if(!set){ 
1994/0513    
		outb(lptbase[i-1]+Qpcr, 0);	/* turn off interrupts */ 
1993/0224    
		set = 1; 
1997/0327    
		intrenable(VectorLPT, lptintr, 0, BUSUNKNOWN); 
1998/0910    
		intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN); 
1993/0224    
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1998/0910/sys/src/9/pc/devlpt.c:14,201999/0714/sys/src/9/pc/devlpt.c:14,21 (short | long)
Use ioalloc.
rsc Fri Mar 4 12:44:25 2005
1994/0324    
	0x3bc,	/* lpt2 */ 
1991/1204    
	0x278	/* lpt3 (sic) */ 
}; 
#define NDEV	(sizeof lptbase/sizeof lptbase[0]) 
1999/0714    
#define NDEV	nelem(lptbase) 
static int lptallocd[NDEV]; 
1991/1204    
 
/* offsets, and bits in the registers */ 
enum 
1998/0910/sys/src/9/pc/devlpt.c:75,801999/0714/sys/src/9/pc/devlpt.c:76,82
1991/1204    
{ 
	Chan *c; 
	int i  = (spec && *spec) ? strtol(spec, 0, 0) : 1; 
1999/0714    
	char name[5]; 
1993/0224    
	static int set; 
1991/1204    
 
1993/0224    
	if(!set){ 
1998/0910/sys/src/9/pc/devlpt.c:84,891999/0714/sys/src/9/pc/devlpt.c:86,97
1993/0224    
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1999/0714    
	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; 
	} 
1991/1204    
	c = devattach('L', spec); 
	c->dev = i-1; 
	return c; 
1999/0714/sys/src/9/pc/devlpt.c:82,881999/0819/sys/src/9/pc/devlpt.c:82,88 (short | long)
Add name to intrenable call.
rsc Fri Mar 4 12:44:25 2005
1993/0224    
	if(!set){ 
1994/0513    
		outb(lptbase[i-1]+Qpcr, 0);	/* turn off interrupts */ 
1993/0224    
		set = 1; 
1998/0910    
		intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN); 
1999/0819    
		intrenable(IrqLPT, lptintr, 0, BUSUNKNOWN, "lpt"); 
1993/0224    
	} 
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1999/0819/sys/src/9/pc/devlpt.c:59,641999/1230/sys/src/9/pc/devlpt.c:59,69 (short | long)
Handle DEVDOTDOT. (Big bug fix.)
rsc Fri Mar 4 12:44:25 2005
1991/1204    
	Qid qid; 
	char name[NAMELEN]; 
 
1999/1230    
	if(i == DEVDOTDOT){ 
		sprint(name, "#L%lud", c->dev+1); 
		devdir(c, (Qid){CHDIR, 0}, name, 0, eve, 0555, dp); 
		return 1; 
	} 
1991/1204    
	if(tab==0 || i>=ntab) 
		return -1; 
	tab += i; 
1999/1230/sys/src/9/pc/devlpt.c:178,1922000/0813/sys/src/9/pc/devlpt.c:178,194 (short | long)
Bug fix: only error out if Fpe is not set.
Performance fix: use tsleep to sleep for the first 10 milliseconds instead of looping.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
{ 
1994/0331    
	int status, tries; 
1991/1204    
 
1994/0331    
	for(tries = 0;; tries++){ 
2000/0813    
	for(tries=0;; tries++) { 
1994/0331    
		status = inb(base+Qpsr); 
		if(!(status & Fselect) || !(status & Fnoerror)) 
			error(Eio); 
		if(status & Fnotbusy) 
2000/0813    
		if(status&Fnotbusy) 
1994/0331    
			break; 
		if(tries > 1000){ 
2000/0813    
		if((status&Fpe)==0 && (status&(Fselect|Fnoerror)) != (Fselect|Fnoerror)) 
			error(Eio); 
		if(tries < 10) 
			tsleep(&lptrendez, return0, nil, 1); 
		else { 
1994/0331    
			outb(base+Qpcr, Finitbar|Fie); 
			tsleep(&lptrendez, lptready, (void *)base, MS2HZ); 
2000/0813    
			tsleep(&lptrendez, lptready, (void *)base, 100); 
1994/0331    
		} 
1991/1204    
	} 
	outb(base+Qdlr, c); 
2000/0813/sys/src/9/pc/devlpt.c:92,1012001/0413/sys/src/9/pc/devlpt.c:92,112 (short | long)
Handle ECP parallel ports.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
	if(i < 1 || i > NDEV) 
1992/0114    
		error(Ebadarg); 
1999/0714    
	if(lptallocd[i-1] == 0){ 
2001/0413    
		int ecr; 
1999/0714    
		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; 
2001/0413    
		// 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"); 
			} 
		} 
1999/0714    
	} 
1991/1204    
	c = devattach('L', spec); 
	c->dev = i-1; 
2001/0413/sys/src/9/pc/devlpt.c:20,252001/0527/sys/src/9/pc/devlpt.c:20,26 (short | long)
Convert to 9P2000.
rsc Fri Mar 4 12:44:25 2005
1991/1204    
/* offsets, and bits in the registers */ 
enum 
{ 
2001/0527    
	Qdir=		0x8000, 
1991/1204    
	/* data latch register */ 
	Qdlr=		0x0, 
	/* printer status register */ 
2001/0413/sys/src/9/pc/devlpt.c:47,782001/0527/sys/src/9/pc/devlpt.c:48,81
1991/1204    
static Rendez	lptrendez; 
 
Dirtab lptdir[]={ 
	"dlr",		{Qdlr},		1,		0666, 
	"psr",		{Qpsr},		5,		0444, 
	"pcr",		{Qpcr},		0,		0222, 
	"data",		{Qdata},	0,		0222, 
2001/0527    
	".",	{Qdir, 0, QTDIR},	0,	DMDIR|0555, 
	"dlr",	{Qdlr},			1,	0666, 
	"psr",	{Qpsr},			5,	0444, 
	"pcr",	{Qpcr},			0,	0222, 
	"data",	{Qdata},		0,	0222, 
1991/1204    
}; 
 
static int 
lptgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
2001/0527    
lptgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp) 
1991/1204    
{ 
	Qid qid; 
	char name[NAMELEN]; 
 
1999/1230    
	if(i == DEVDOTDOT){ 
		sprint(name, "#L%lud", c->dev+1); 
		devdir(c, (Qid){CHDIR, 0}, name, 0, eve, 0555, dp); 
2001/0527    
		mkqid(&qid, Qdir, 0, QTDIR); 
		devdir(c, qid, ".", 0, eve, 0555, dp); 
1999/1230    
		return 1; 
	} 
2001/0527    
	i++; /* skip first element for . itself */ 
1991/1204    
	if(tab==0 || i>=ntab) 
		return -1; 
	tab += i; 
	qid = tab->qid; 
2001/0527    
	qid.path &= ~Qdir; 
1991/1204    
	if(qid.path < Qdata) 
		qid.path += lptbase[c->dev]; 
	qid.vers = c->dev; 
1998/0825    
	sprint(name, "lpt%lud%s", c->dev+1, tab->name); 
1991/1204    
	devdir(c, qid, name, tab->length, eve, tab->perm, dp); 
2001/0527    
	sprint(up->genbuf, "lpt%lud%s", c->dev+1, tab->name); 
	devdir(c, qid, up->genbuf, tab->length, eve, tab->perm, dp); 
1991/1204    
	return 1; 
} 
 
2001/0413/sys/src/9/pc/devlpt.c:109,1282001/0527/sys/src/9/pc/devlpt.c:112,132
2001/0413    
		} 
1999/0714    
	} 
1991/1204    
	c = devattach('L', spec); 
2001/0527    
	c->qid.path = Qdir; 
1991/1204    
	c->dev = i-1; 
	return c; 
} 
 
1997/0327    
static int 
1991/1204    
lptwalk(Chan *c, char *name) 
2001/0527    
static Walkqid* 
lptwalk(Chan *c, Chan *nc, char **name, int nname) 
1991/1204    
{ 
1997/0327    
	return devwalk(c, name, lptdir, nelem(lptdir), lptgen); 
2001/0527    
	return devwalk(c, nc, name, nname, lptdir, nelem(lptdir), lptgen); 
1991/1204    
} 
 
1997/0327    
static void 
1991/1204    
lptstat(Chan *c, char *dp) 
2001/0527    
static int 
lptstat(Chan *c, uchar *dp, int n) 
1991/1204    
{ 
1997/0327    
	devstat(c, dp, lptdir, nelem(lptdir), lptgen); 
2001/0527    
	return devstat(c, dp, n, lptdir, nelem(lptdir), lptgen); 
1991/1204    
} 
 
1997/0327    
static Chan* 
2001/0413/sys/src/9/pc/devlpt.c:143,1492001/0527/sys/src/9/pc/devlpt.c:147,153
1998/0319    
	int size; 
	ulong o; 
1991/1204    
 
	if(c->qid.path == CHDIR) 
2001/0527    
	if(c->qid.path == Qdir) 
1997/0327    
		return devdirread(c, a, n, lptdir, nelem(lptdir), lptgen); 
1991/1204    
	size = sprint(str, "0x%2.2ux\n", inb(c->qid.path)); 
1998/0319    
	o = c->offset; 
2001/0413/sys/src/9/pc/devlpt.c:226,2322001/0527/sys/src/9/pc/devlpt.c:230,235
1997/0327    
	devreset, 
	devinit, 
	lptattach, 
	devclone, 
	lptwalk, 
	lptstat, 
	lptopen, 
2001/0527/sys/src/9/pc/devlpt.c:229,2342002/0109/sys/src/9/pc/devlpt.c:229,235 (short | long)
Add devshutdown.
rsc Fri Mar 4 12:44:25 2005
1997/0408    
 
1997/0327    
	devreset, 
	devinit, 
2002/0109    
	devshutdown, 
1997/0327    
	lptattach, 
	lptwalk, 
	lptstat, 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)