Annotation of lucent/sys/src/9/pc/devlpt.c, revision 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.