Annotation of 42BSD/sys/vaxuba/vp.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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