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

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

unix.superglobalmegacorp.com

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