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