From 6de9a332d1a870912b7d3353655929265ba2982b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 4 Dec 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-12-04 --- pc/devlpt.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++ port/ipdat.h | 2 +- 2 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 pc/devlpt.c diff --git a/pc/devlpt.c b/pc/devlpt.c new file mode 100644 index 0000000000000000000000000000000000000000..9148f3f7f748af592954de787f4cf10ca17cb51b --- /dev/null +++ b/pc/devlpt.c @@ -0,0 +1,214 @@ +#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); +} diff --git a/port/ipdat.h b/port/ipdat.h index 82445d815211835c4be1d2c71b2852e2228c7fa1..96fbc5501aba4c4f81984d4c55648542b839dae3 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -309,7 +309,7 @@ struct Ipconv #define MSS_LENGTH 4 #define MSL2 10 #define MSPTICK 200 -#define DEF_MSS 1024 +#define DEF_MSS 512 #define DEF_RTT 1000 #define TCPOOB_HADDATA 1 #define TCPOOB_HAVEDATA 2