Annotation of 41BSD/4.0.upgrade/sys/dev/lp.c, revision 1.1.1.1

1.1       root        1: /*     lp.c    4.20    81/07/25        */
                      2: 
                      3: #include "lp.h"
                      4: #if NLP > 0
                      5: /*
                      6:  * LP-11 Line printer driver
                      7:  *
                      8:  * This driver has been modified to work on printers where
                      9:  * leaving IENABLE set would cause continuous interrupts.
                     10:  *
                     11:  * TODO:
                     12:  *     Test driver on multiple printers
                     13:  */
                     14: 
                     15: #include "../h/param.h"
                     16: #include "../h/dir.h"
                     17: #include "../h/user.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/systm.h"
                     20: #include "../h/map.h"
                     21: #include "../h/pte.h"
                     22: #include "../h/ubavar.h"
                     23: #include "../h/ioctl.h"
                     24: #include "../h/tty.h"
                     25: 
                     26: #define        LPPRI   (PZERO+8)
                     27: #define        IENABLE 0100
                     28: #define        DONE    0200
                     29: #define        ERROR   0100000
                     30: #define        LPLWAT  650
                     31: #define        LPHWAT  800
                     32: 
                     33: #define MAXCOL 132
                     34: #define CAP    1
                     35: 
                     36: #define LPUNIT(dev) (minor(dev) >> 3)
                     37: 
                     38: struct lpdevice {
                     39:        short   lpsr;
                     40:        short   lpbuf;
                     41: };
                     42: 
                     43: struct lp_softc {
                     44:        struct  clist sc_outq;
                     45:        int     sc_state;
                     46:        int     sc_physcol;
                     47:        int     sc_logcol;
                     48:        int     sc_physline;
                     49:        char    sc_flags;
                     50:        int     sc_lpchar;
                     51:        struct  buf *sc_inbuf;
                     52: } lp_softc[NLP];
                     53: 
                     54: struct uba_device *lpinfo[NLP];
                     55: 
                     56: int lpprobe(), lpattach(), lptout();
                     57: u_short lpstd[] = { 0177514 };
                     58: struct uba_driver lpdriver =
                     59:        { lpprobe, 0, lpattach, 0, lpstd, "lp", lpinfo };
                     60: 
                     61: /* bits for state */
                     62: #define        OPEN            1       /* device is open */
                     63: #define        TOUT            2       /* timeout is active */
                     64: #define        MOD             4       /* device state has been modified */
                     65: #define        ASLP            8       /* awaiting draining of printer */
                     66: 
                     67: extern lbolt;
                     68: int    lptout();
                     69: 
                     70: lpattach(ui)
                     71:        struct uba_device *ui;
                     72: {
                     73:        register struct lp_softc *sc;
                     74: 
                     75:        sc = &lp_softc[ui->ui_unit];
                     76:        sc->sc_lpchar = -1;
                     77: }
                     78: 
                     79: lpprobe(reg)
                     80:        caddr_t reg;
                     81: {
                     82:        register int br, cvec;                  /* value-result */
                     83:        register struct lpdevice *lpaddr = (struct lpdevice *)reg;
                     84: #ifdef lint
                     85:        br = 0; cvec = br; br = cvec;
                     86: #endif
                     87: 
                     88:        lpaddr->lpsr = IENABLE;
                     89:        DELAY(5);
                     90:        lpaddr->lpsr = 0;
                     91:        return (1);
                     92: }
                     93: 
                     94: /*ARGSUSED*/
                     95: lpopen(dev, flag)
                     96:        dev_t dev;
                     97:        int flag;
                     98: {
                     99:        register int unit;
                    100:        register struct lpdevice *lpaddr;
                    101:        register struct lp_softc *sc;
                    102:        register struct uba_device *ui;
                    103: 
                    104:        if ((unit = LPUNIT(dev)) >= NLP ||
                    105:            (sc = &lp_softc[unit])->sc_state&OPEN ||
                    106:            (ui = lpinfo[unit]) == 0 || ui->ui_alive == 0) {
                    107:                u.u_error = ENXIO;
                    108:                return;
                    109:        }
                    110:        lpaddr = (struct lpdevice *)ui->ui_addr;
                    111:        if (lpaddr->lpsr&ERROR) {
                    112:                u.u_error = EIO;
                    113:                return;
                    114:        }
                    115:        sc->sc_state |= OPEN;
                    116:        sc->sc_inbuf = geteblk();
                    117:        sc->sc_flags = minor(dev) & 07;
                    118:        (void) spl4();
                    119:        if ((sc->sc_state&TOUT) == 0) {
                    120:                sc->sc_state |= TOUT;
                    121:                timeout(lptout, (caddr_t)dev, 10*hz);
                    122:        }
                    123:        (void) spl0();
                    124:        lpcanon(dev, '\f');
                    125: }
                    126: 
                    127: /*ARGSUSED*/
                    128: lpclose(dev, flag)
                    129:        dev_t dev;
                    130:        int flag;
                    131: {
                    132:        register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
                    133: 
                    134:        lpcanon(dev, '\f');
                    135:        brelse(sc->sc_inbuf);
                    136:        sc->sc_state &= ~OPEN;
                    137: }
                    138: 
                    139: lpwrite(dev)
                    140:        dev_t dev;
                    141: {
                    142:        register unsigned n;
                    143:        register char *cp;
                    144:        register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
                    145: 
                    146:        while (n = min(BSIZE, u.u_count)) {
                    147:                cp = sc->sc_inbuf->b_un.b_addr;
                    148:                iomove(cp, n, B_WRITE);
                    149:                do
                    150:                        lpcanon(dev, *cp++);
                    151:                while (--n);
                    152:        }
                    153: }
                    154: 
                    155: lpcanon(dev, c)
                    156:        dev_t dev;
                    157:        register int c;
                    158: {
                    159:        register int logcol, physcol;
                    160:        register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
                    161: 
                    162:        if (sc->sc_flags&CAP) {
                    163:                register c2;
                    164: 
                    165:                if (c>='a' && c<='z')
                    166:                        c += 'A'-'a'; else
                    167:                switch (c) {
                    168: 
                    169:                case '{':
                    170:                        c2 = '(';
                    171:                        goto esc;
                    172: 
                    173:                case '}':
                    174:                        c2 = ')';
                    175:                        goto esc;
                    176: 
                    177:                case '`':
                    178:                        c2 = '\'';
                    179:                        goto esc;
                    180: 
                    181:                case '|':
                    182:                        c2 = '!';
                    183:                        goto esc;
                    184: 
                    185:                case '~':
                    186:                        c2 = '^';
                    187: 
                    188:                esc:
                    189:                        lpcanon(dev, c2);
                    190:                        sc->sc_logcol--;
                    191:                        c = '-';
                    192:                }
                    193:        }
                    194:        logcol = sc->sc_logcol;
                    195:        physcol = sc->sc_physcol;
                    196:        if (c == ' ')
                    197:                logcol++;
                    198:        else switch(c) {
                    199: 
                    200:        case '\t':
                    201:                logcol = (logcol+8) & ~7;
                    202:                break;
                    203: 
                    204:        case '\f':
                    205:                if (sc->sc_physline == 0 && physcol == 0)
                    206:                        break;
                    207:                /* fall into ... */
                    208: 
                    209:        case '\n':
                    210:                lpoutput(dev, c);
                    211:                if (c == '\f')
                    212:                        sc->sc_physline = 0;
                    213:                else
                    214:                        sc->sc_physline++;
                    215:                physcol = 0;
                    216:                /* fall into ... */
                    217: 
                    218:        case '\r':
                    219:                logcol = 0;
                    220:                (void) spl4();
                    221:                lpintr(LPUNIT(dev));
                    222:                (void) spl0();
                    223:                break;
                    224: 
                    225:        case '\b':
                    226:                if (logcol > 0)
                    227:                        logcol--;
                    228:                break;
                    229: 
                    230:        default:
                    231:                if (logcol < physcol) {
                    232:                        lpoutput(dev, '\r');
                    233:                        physcol = 0;
                    234:                }
                    235:                if (logcol < MAXCOL) {
                    236:                        while (logcol > physcol) {
                    237:                                lpoutput(dev, ' ');
                    238:                                physcol++;
                    239:                        }
                    240:                        lpoutput(dev, c);
                    241:                        physcol++;
                    242:                }
                    243:                logcol++;
                    244:        }
                    245:        if (logcol > 1000)      /* ignore long lines  */
                    246:                logcol = 1000;
                    247:        sc->sc_logcol = logcol;
                    248:        sc->sc_physcol = physcol;
                    249: }
                    250: 
                    251: lpoutput(dev, c)
                    252:        dev_t dev;
                    253:        int c;
                    254: {
                    255:        register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
                    256: 
                    257:        if (sc->sc_outq.c_cc >= LPHWAT) {
                    258:                (void) spl4();
                    259:                lpintr(LPUNIT(dev));                            /* unchoke */
                    260:                while (sc->sc_outq.c_cc >= LPHWAT) {
                    261:                        sc->sc_state |= ASLP;           /* must be ERROR */
                    262:                        sleep((caddr_t)sc, LPPRI);
                    263:                }
                    264:                (void) spl0();
                    265:        }
                    266:        while (putc(c, &sc->sc_outq))
                    267:                sleep((caddr_t)&lbolt, LPPRI);
                    268: }
                    269: 
                    270: lpintr(lp11)
                    271:        int lp11;
                    272: {
                    273:        register int n;
                    274:        register struct lp_softc *sc = &lp_softc[lp11];
                    275:        register struct uba_device *ui = lpinfo[lp11];
                    276:        register struct lpdevice *lpaddr = (struct lpdevice *)ui->ui_addr;
                    277: 
                    278:        lpaddr->lpsr &= ~IENABLE;
                    279:        n = sc->sc_outq.c_cc;
                    280:        if (sc->sc_lpchar < 0)
                    281:                sc->sc_lpchar = getc(&sc->sc_outq);
                    282:        while ((lpaddr->lpsr&DONE) && sc->sc_lpchar >= 0) {
                    283:                lpaddr->lpbuf = sc->sc_lpchar;
                    284:                sc->sc_lpchar = getc(&sc->sc_outq);
                    285:        }
                    286:        sc->sc_state |= MOD;
                    287:        if (sc->sc_outq.c_cc > 0 && (lpaddr->lpsr&ERROR)==0)
                    288:                lpaddr->lpsr |= IENABLE;        /* ok and more to do later */
                    289:        if (n>LPLWAT && sc->sc_outq.c_cc<=LPLWAT && sc->sc_state&ASLP) {
                    290:                sc->sc_state &= ~ASLP;
                    291:                wakeup((caddr_t)sc);            /* top half should go on */
                    292:        }
                    293: }
                    294: 
                    295: lptout(dev)
                    296:        dev_t dev;
                    297: {
                    298:        register struct lp_softc *sc;
                    299:        register struct uba_device *ui;
                    300:        register struct lpdevice *lpaddr;
                    301: 
                    302:        sc = &lp_softc[LPUNIT(dev)];
                    303:        ui = lpinfo[LPUNIT(dev)];
                    304:        lpaddr = (struct lpdevice *) ui->ui_addr;
                    305:        if ((sc->sc_state&MOD) != 0) {
                    306:                sc->sc_state &= ~MOD;           /* something happened */
                    307:                timeout(lptout, (caddr_t)dev, 2*hz);    /* so don't sweat */
                    308:                return;
                    309:        }
                    310:        if ((sc->sc_state&OPEN) == 0) {
                    311:                sc->sc_state &= ~TOUT;          /* no longer open */
                    312:                lpaddr->lpsr = 0;
                    313:                return;
                    314:        }
                    315:        if (sc->sc_outq.c_cc && (lpaddr->lpsr&DONE) && (lpaddr->lpsr&ERROR)==0)
                    316:                lpintr(LPUNIT(dev));                    /* ready to go */
                    317:        timeout(lptout, (caddr_t)dev, 10*hz);
                    318: }
                    319: 
                    320: lpreset(uban)
                    321:        int uban;
                    322: {
                    323:        register struct uba_device *ui;
                    324:        register struct lpdevice *lpaddr;
                    325:        register int unit;
                    326: 
                    327:        for (unit = 0; unit < NLP; unit++) {
                    328:                if ((ui = lpinfo[unit]) == 0 || ui->ui_ubanum != uban ||
                    329:                    ui->ui_alive == 0)
                    330:                        continue;
                    331:                printf(" lp%d", unit);
                    332:                lpaddr = (struct lpdevice *)ui->ui_addr;
                    333:                lpaddr->lpsr |= IENABLE;
                    334:        }
                    335: }

unix.superglobalmegacorp.com

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