Annotation of 43BSDReno/sys/vaxuba/vp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  *
                      6:  *     @(#)vp.c        7.4 (Berkeley) 4/3/90
                      7:  */
                      8: 
                      9: #include "vp.h"
                     10: #if NVP > 0
                     11: /*
                     12:  * Versatec matrix printer/plotter
                     13:  * dma interface driver
                     14:  *
                     15:  * SETUP NOTES:
                     16:  *     Set up both print and plot interrupts to go through the same vector
                     17:  *     (or kludge probe to reset second vector to first;
                     18:  *     default 174/200 is already handled).
                     19:  *     Give the address of the plcsr register in the config specification
                     20:  */
                     21: #include "machine/pte.h"
                     22: 
                     23: #include "param.h"
                     24: #include "user.h"
                     25: #include "buf.h"
                     26: #include "systm.h"
                     27: #include "map.h"
                     28: #include "ioctl.h"
                     29: #include "vcmd.h"
                     30: #include "uio.h"
                     31: #include "kernel.h"
                     32: 
                     33: #include "ubavar.h"
                     34: #include "ubareg.h"
                     35: 
                     36: unsigned minvpph();
                     37: 
                     38: #define        VPPRI   (PZERO-1)
                     39: 
                     40: struct vpdevice {
                     41:        short   plbcr;
                     42:        short   pbxaddr;
                     43:        short   prbcr;
                     44:        u_short pbaddr;
                     45:        short   plcsr;
                     46:        short   plbuf;
                     47:        short   prcsr;
                     48:        u_short prbuf;
                     49: };
                     50: 
                     51: #define        VP_ERROR        0100000
                     52: #define        VP_DTCINTR      0040000
                     53: #define        VP_DMAACT       0020000
                     54: #define        VP_READY        0000200
                     55: #define        VP_IENABLE      0000100
                     56: #define        VP_TERMCOM      0000040
                     57: #define        VP_FFCOM        0000020
                     58: #define        VP_EOTCOM       0000010
                     59: #define        VP_CLRCOM       0000004
                     60: #define        VP_RESET        0000002
                     61: #define        VP_SPP          0000001
                     62: 
                     63: struct vp_softc {
                     64:        int     sc_state;
                     65:        int     sc_count;
                     66:        int     sc_bufp;
                     67:        struct  buf *sc_bp;
                     68:        int     sc_ubinfo;
                     69: } vp_softc[NVP];
                     70: 
                     71: /* sc_state bits */
                     72: #define        VPSC_BUSY       0001000
                     73: #define        VPSC_MODE       0000700
                     74: #define        VPSC_SPP        0000400
                     75: #define        VPSC_PLOT       0000200
                     76: #define        VPSC_PRINT      0000100
                     77: #define        VPSC_CMNDS      0000076
                     78: #define        VPSC_OPEN       0000001
                     79: 
                     80: struct uba_device *vpdinfo[NVP];
                     81: 
                     82: #define        VPUNIT(dev)     (minor(dev))
                     83: 
                     84: struct buf rvpbuf[NVP];
                     85: 
                     86: int    vpprobe(), vpattach();
                     87: struct uba_device *vpdinfo[NVP];
                     88: u_short        vpstd[] = { 0777500, 0 };
                     89: struct uba_driver vpdriver =
                     90:     { vpprobe, 0, vpattach, 0, vpstd, "vp", vpdinfo };
                     91: 
                     92: vpprobe(reg)
                     93:        caddr_t reg;
                     94: {
                     95:        register int br, cvec;          /* value-result */
                     96:        register struct vpdevice *vpaddr = (struct vpdevice *)(reg-010);
                     97: 
                     98: #ifdef lint
                     99:        br = 0; cvec = br; br = cvec;
                    100:        vpintr(0);
                    101: #endif
                    102:        vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
                    103:        vpaddr->pbaddr = 0;
                    104:        vpaddr->pbxaddr = 0;
                    105:        vpaddr->prbcr = 1;
                    106:        DELAY(10000);
                    107:        vpaddr->prcsr = 0;
                    108:        /* GET INTERRUPT AT SECOND VECTOR BUT WANT FIRST */
                    109:        if (cvec == 0200) {
                    110:                printf("vp reset vec from 200 to 174\n");
                    111:                cvec = 0174;
                    112:        }
                    113:        return (sizeof (struct vpdevice));
                    114: }
                    115: 
                    116: /*ARGSUSED*/
                    117: vpattach(ui)
                    118:        struct uba_device *ui;
                    119: {
                    120: 
                    121:        ui->ui_addr -= 010;
                    122:        ui->ui_physaddr -= 010;
                    123: }
                    124: 
                    125: vpopen(dev)
                    126:        dev_t dev;
                    127: {
                    128:        register struct vp_softc *sc;
                    129:        register struct vpdevice *vpaddr;
                    130:        register struct uba_device *ui;
                    131: 
                    132:        if (VPUNIT(dev) >= NVP ||
                    133:            ((sc = &vp_softc[minor(dev)])->sc_state&VPSC_OPEN) ||
                    134:            (ui = vpdinfo[VPUNIT(dev)]) == 0 || ui->ui_alive == 0)
                    135:                return (ENXIO);
                    136:        vpaddr = (struct vpdevice *)ui->ui_addr;
                    137:        sc->sc_state = VPSC_OPEN|VPSC_PRINT | VP_CLRCOM|VP_RESET;
                    138:        sc->sc_count = 0;
                    139:        vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
                    140:        vptimo(dev);
                    141:        while (sc->sc_state & VPSC_CMNDS) {
                    142:                (void) spl4();
                    143:                if (vpwait(dev)) {
                    144:                        (void) vpclose(dev);
                    145:                        return (EIO);
                    146:                }
                    147:                vpstart(dev);
                    148:                (void) spl0();
                    149:        }
                    150:        return (0);
                    151: }
                    152: 
                    153: vpstrategy(bp)
                    154:        register struct buf *bp;
                    155: {
                    156:        register int e;
                    157:        register struct vp_softc *sc = &vp_softc[VPUNIT(bp->b_dev)];
                    158:        register struct uba_device *ui = vpdinfo[VPUNIT(bp->b_dev)];
                    159:        register struct vpdevice *vpaddr = (struct vpdevice *)ui->ui_addr;
                    160: 
                    161:        (void) spl4();
                    162:        while (sc->sc_state & VPSC_BUSY)
                    163:                sleep((caddr_t)sc, VPPRI);
                    164:        sc->sc_state |= VPSC_BUSY;
                    165:        sc->sc_bp = bp;
                    166:        sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
                    167:        if (e = vpwait(bp->b_dev))
                    168:                goto brkout;
                    169:        sc->sc_count = bp->b_bcount;
                    170:        vpstart(bp->b_dev);
                    171:        while (((sc->sc_state&VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr) & VP_DMAACT)
                    172:                sleep((caddr_t)sc, VPPRI);
                    173:        sc->sc_count = 0;
                    174:        if ((sc->sc_state&VPSC_MODE) == VPSC_SPP)
                    175:                sc->sc_state = (sc->sc_state &~ VPSC_MODE) | VPSC_PLOT;
                    176:        (void) spl0();
                    177: brkout:
                    178:        ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
                    179:        sc->sc_state &= ~VPSC_BUSY;
                    180:        sc->sc_bp = 0;
                    181:        if (e)
                    182:                bp->b_flags |= B_ERROR;
                    183:        iodone(bp);
                    184:        wakeup((caddr_t)sc);
                    185: }
                    186: 
                    187: int    vpblock = 16384;
                    188: 
                    189: unsigned
                    190: minvpph(bp)
                    191:        struct buf *bp;
                    192: {
                    193: 
                    194:        if (bp->b_bcount > vpblock)
                    195:                bp->b_bcount = vpblock;
                    196: }
                    197: 
                    198: /*ARGSUSED*/
                    199: vpwrite(dev, uio)
                    200:        dev_t dev;
                    201:        struct uio *uio;
                    202: {
                    203: 
                    204:        if (VPUNIT(dev) >= NVP)
                    205:                return (ENXIO);
                    206:        return (physio(vpstrategy, &rvpbuf[VPUNIT(dev)], dev, B_WRITE,
                    207:                    minvpph, uio));
                    208: }
                    209: 
                    210: vpwait(dev)
                    211:        dev_t dev;
                    212: {
                    213:        register struct vpdevice *vpaddr =
                    214:            (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
                    215:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    216:        register int e;
                    217: 
                    218:        for (;;) {
                    219:                e = (sc->sc_state & VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr;
                    220:                if (e & (VP_READY|VP_ERROR))
                    221:                        break;
                    222:                sleep((caddr_t)sc, VPPRI);
                    223:        }
                    224:        /* I WISH I COULD TELL WHETHER AN ERROR INDICATED AN NPR TIMEOUT */
                    225:        return (e & VP_ERROR);
                    226: }
                    227: 
                    228: vpstart(dev)
                    229:        dev_t;
                    230: {
                    231:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    232:        register struct vpdevice *vpaddr =
                    233:            (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
                    234:        short bit;
                    235: 
                    236:        if (sc->sc_count) {
                    237:                vpaddr->pbaddr = sc->sc_ubinfo;
                    238:                vpaddr->pbxaddr = (sc->sc_ubinfo>>12)&0x30;
                    239:                if (sc->sc_state & (VPSC_PRINT|VPSC_SPP))
                    240:                        vpaddr->prbcr = sc->sc_count;
                    241:                else
                    242:                        vpaddr->plbcr = sc->sc_count;
                    243:                return;
                    244:        }
                    245:        for (bit = 1; bit != 0; bit <<= 1)
                    246:                if (sc->sc_state&bit&VPSC_CMNDS) {
                    247:                        vpaddr->plcsr |= bit;
                    248:                        sc->sc_state &= ~bit;
                    249:                        return;
                    250:                }
                    251: }
                    252: 
                    253: /*ARGSUSED*/
                    254: vpioctl(dev, cmd, data, flag)
                    255:        dev_t dev;
                    256:        int cmd;
                    257:        register caddr_t data;
                    258:        int flag;
                    259: {
                    260:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    261:        register struct vpdevice *vpaddr =
                    262:            (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
                    263: 
                    264:        switch (cmd) {
                    265: 
                    266:        case VGETSTATE:
                    267:                *(int *)data = sc->sc_state;
                    268:                return (0);
                    269: 
                    270:        case VSETSTATE:
                    271:                sc->sc_state =
                    272:                    (sc->sc_state & ~VPSC_MODE) |
                    273:                    ((*(int *)data) & (VPSC_MODE|VPSC_CMNDS));
                    274:                break;
                    275: 
                    276:        default:
                    277:                return (ENOTTY);
                    278:        }
                    279:        (void) spl4();
                    280:        (void) vpwait(dev);
                    281:        if (sc->sc_state&VPSC_SPP)
                    282:                vpaddr->plcsr |= VP_SPP;
                    283:        else
                    284:                vpaddr->plcsr &= ~VP_SPP;
                    285:        sc->sc_count = 0;
                    286:        while (sc->sc_state & VPSC_CMNDS) {
                    287:                (void) vpwait(dev);
                    288:                vpstart(dev);
                    289:        }
                    290:        (void) spl0();
                    291:        return (0);
                    292: }
                    293: 
                    294: vptimo(dev)
                    295:        dev_t dev;
                    296: {
                    297:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    298: 
                    299:        if (sc->sc_state&VPSC_OPEN)
                    300:                timeout(vptimo, (caddr_t)dev, hz/10);
                    301:        vpintr(dev);
                    302: }
                    303: 
                    304: /*ARGSUSED*/
                    305: vpintr(dev)
                    306:        dev_t dev;
                    307: {
                    308:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    309: 
                    310:        wakeup((caddr_t)sc);
                    311: }
                    312: 
                    313: vpclose(dev)
                    314:        dev_t dev;
                    315: {
                    316:        register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
                    317:        register struct vpdevice *vpaddr =
                    318:            (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
                    319: 
                    320:        sc->sc_state = 0;
                    321:        sc->sc_count = 0;
                    322:        vpaddr->plcsr = 0;
                    323:        return (0);
                    324: }
                    325: 
                    326: vpreset(uban)
                    327:        int uban;
                    328: {
                    329:        register int vp11;
                    330:        register struct uba_device *ui;
                    331:        register struct vp_softc *sc = vp_softc;
                    332:        register struct vpdevice *vpaddr;
                    333: 
                    334:        for (vp11 = 0; vp11 < NVP; vp11++, sc++) {
                    335:                if ((ui = vpdinfo[vp11]) == 0 || ui->ui_alive == 0 ||
                    336:                    ui->ui_ubanum != uban || (sc->sc_state&VPSC_OPEN) == 0)
                    337:                        continue;
                    338:                printf(" vp%d", vp11);
                    339:                vpaddr = (struct vpdevice *)ui->ui_addr;
                    340:                vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
                    341:                if ((sc->sc_state & VPSC_BUSY) == 0)
                    342:                        continue;
                    343:                sc->sc_ubinfo = 0;
                    344:                sc->sc_count = sc->sc_bp->b_bcount;
                    345:                vpstart(sc->sc_bp->b_dev);
                    346:        }
                    347: }
                    348: 
                    349: vpselect()
                    350: {
                    351:        return (1);
                    352: }
                    353: #endif

unix.superglobalmegacorp.com

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