Annotation of lucent/sys/src/9/pc/devlpt.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "../port/lib.h"
                      3: #include       "mem.h"
                      4: #include       "dat.h"
                      5: #include       "fns.h"
                      6: #include       "io.h"
                      7: #include       "../port/error.h"
                      8: 
                      9: /* Centronix parallel (printer) port */
                     10: 
                     11: /* base addresses */
                     12: static int lptbase[] = {
                     13:        0x3bc,  /* lpt1 */
                     14:        0x378,  /* lpt2 (sic) */
                     15:        0x278   /* lpt3 (sic) */
                     16: };
                     17: #define NDEV   (sizeof lptbase/sizeof lptbase[0])
                     18: 
                     19: /* offsets, and bits in the registers */
                     20: enum
                     21: {
                     22:        /* data latch register */
                     23:        Qdlr=           0x0,
                     24:        /* printer status register */
                     25:        Qpsr=           0x1,
                     26:        Fnotbusy=       0x80,
                     27:        Fack=           0x40,
                     28:        Fpe=            0x20,
                     29:        Fselect=        0x10,
                     30:        Fnoerror=       0x08,
                     31:        /* printer control register */
                     32:        Qpcr=           0x2,
                     33:        Fie=            0x10,
                     34:        Fselectin=      0x08,
                     35:        Finitbar=       0x04,
                     36:        Faf=            0x02,
                     37:        Fstrobe=        0x01,
                     38:        /* fake `data register' */
                     39:        Qdata=          0x3,
                     40: };
                     41: 
                     42: static int     lptready(void*);
                     43: static void    outch(int, int);
                     44: static void    lptintr(Ureg*, void*);
                     45: 
                     46: static Rendez  lptrendez;
                     47: 
                     48: Dirtab lptdir[]={
                     49:        "dlr",          {Qdlr},         1,              0666,
                     50:        "psr",          {Qpsr},         5,              0444,
                     51:        "pcr",          {Qpcr},         0,              0222,
                     52:        "data",         {Qdata},        0,              0222,
                     53: };
                     54: #define NLPT   (sizeof lptdir/sizeof lptdir[0])
                     55: 
                     56: static int
                     57: lptgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
                     58: {
                     59:        Qid qid;
                     60:        char name[NAMELEN];
                     61: 
                     62:        if(tab==0 || i>=ntab)
                     63:                return -1;
                     64:        tab += i;
                     65:        qid = tab->qid;
                     66:        if(qid.path < Qdata)
                     67:                qid.path += lptbase[c->dev];
                     68:        qid.vers = c->dev;
                     69:        sprint(name, "lpt%d%s", c->dev+1, tab->name);
                     70:        devdir(c, qid, name, tab->length, eve, tab->perm, dp);
                     71:        return 1;
                     72: }
                     73: 
                     74: void
                     75: lptreset(void)
                     76: {
                     77: }
                     78: 
                     79: void
                     80: lptinit(void)
                     81: {}
                     82: 
                     83: Chan*
                     84: lptattach(char *spec)
                     85: {
                     86:        Chan *c;
                     87:        int i  = (spec && *spec) ? strtol(spec, 0, 0) : 1;
                     88:        static int set;
                     89: 
                     90:        if(!set){
                     91:                set = 1;
                     92:                setvec(Parallelvec, lptintr, 0);
                     93:        }
                     94:        if(i < 1 || i > NDEV)
                     95:                error(Ebadarg);
                     96:        c = devattach('L', spec);
                     97:        c->dev = i-1;
                     98:        return c;
                     99: }
                    100: 
                    101: Chan*
                    102: lptclone(Chan *c, Chan *nc)
                    103: {
                    104:        return devclone(c, nc);
                    105: }
                    106: 
                    107: int
                    108: lptwalk(Chan *c, char *name)
                    109: {
                    110:        return devwalk(c, name, lptdir, NLPT, lptgen);
                    111: }
                    112: 
                    113: void
                    114: lptstat(Chan *c, char *dp)
                    115: {
                    116:        devstat(c, dp, lptdir, NLPT, lptgen);
                    117: }
                    118: 
                    119: Chan*
                    120: lptopen(Chan *c, int omode)
                    121: {
                    122:        return devopen(c, omode, lptdir, NLPT, lptgen);
                    123: }
                    124: 
                    125: void
                    126: lptcreate(Chan *c, char *name, int omode, ulong perm)
                    127: {
                    128:        USED(c, name, omode, perm);
                    129:        error(Eperm);
                    130: }
                    131: 
                    132: void
                    133: lptclose(Chan *c)
                    134: {
                    135:        USED(c);
                    136: }
                    137: 
                    138: void
                    139: lptremove(Chan *c)
                    140: {
                    141:        USED(c);
                    142:        error(Eperm);
                    143: }
                    144: 
                    145: void
                    146: lptwstat(Chan *c, char *dp)
                    147: {
                    148:        USED(c, dp);
                    149:        error(Eperm);
                    150: }
                    151: 
                    152: long
                    153: lptread(Chan *c, void *a, long n)
                    154: {
                    155:        char str[16]; int size;
                    156: 
                    157:        if(c->qid.path == CHDIR)
                    158:                return devdirread(c, a, n, lptdir, NLPT, lptgen);
                    159:        size = sprint(str, "0x%2.2ux\n", inb(c->qid.path));
                    160:        if(c->offset >= size)
                    161:                return 0;
                    162:        if(c->offset+n > size)
                    163:                n = size-c->offset;
                    164:        memmove(a, str+c->offset, n);
                    165:        return n;
                    166: }
                    167: 
                    168: long
                    169: lptwrite(Chan *c, void *a, long n)
                    170: {
                    171:        char str[16], *p;
                    172:        long base, k;
                    173: 
                    174:        if(n <= 0)
                    175:                return 0;
                    176:        if(c->qid.path != Qdata){
                    177:                if(n > sizeof str-1)
                    178:                        n = sizeof str-1;
                    179:                memmove(str, a, n);
                    180:                str[n] = 0;
                    181:                outb(c->qid.path, strtoul(str, 0, 0));
                    182:                return n;
                    183:        }
                    184:        p = a;
                    185:        k = n;
                    186:        base = lptbase[c->dev];
                    187:        if(waserror()){
                    188:                outb(base+Qpcr, Finitbar);
                    189:                nexterror();
                    190:        }
                    191:        while(--k >= 0)
                    192:                outch(base, *p++);
                    193:        poperror();
                    194:        return n;
                    195: }
                    196: 
                    197: static void
                    198: outch(int base, int c)
                    199: {
                    200:        int status, tries;
                    201: 
                    202:        for(tries = 0;; tries++){
                    203:                status = inb(base+Qpsr);
                    204:                if(!(status & Fselect) || !(status & Fnoerror))
                    205:                        error(Eio);
                    206:                if(status & Fnotbusy)
                    207:                        break;
                    208:                if(tries > 1000){
                    209:                        outb(base+Qpcr, Finitbar|Fie);
                    210:                        tsleep(&lptrendez, lptready, (void *)base, MS2HZ);
                    211:                }
                    212:        }
                    213:        outb(base+Qdlr, c);
                    214:        outb(base+Qpcr, Finitbar|Fstrobe);
                    215:        outb(base+Qpcr, Finitbar);
                    216: }
                    217: 
                    218: static int
                    219: lptready(void *base)
                    220: {
                    221:        return inb((int)base+Qpsr)&Fnotbusy;
                    222: }
                    223: 
                    224: static void
                    225: lptintr(Ureg *ur, void *a)
                    226: {
                    227:        USED(ur, a);
                    228:        wakeup(&lptrendez);
                    229: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.