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

1.1       root        1: /*     va.c    6.1     83/07/29        */
                      2: 
                      3: #include "va.h"
                      4: #if NVA > 0
                      5: /*
                      6:  * Varian printer plotter
                      7:  */
                      8: #include "../machine/pte.h"
                      9: 
                     10: #include "../h/param.h"
                     11: #include "../h/dir.h"
                     12: #include "../h/user.h"
                     13: #include "../h/buf.h"
                     14: #include "../h/systm.h"
                     15: #include "../h/map.h"
                     16: #include "../h/ioctl.h"
                     17: #include "../h/vcmd.h"
                     18: #include "../h/uio.h"
                     19: #include "../h/kernel.h"
                     20: 
                     21: #include "../vaxuba/ubareg.h"
                     22: #include "../vaxuba/ubavar.h"
                     23: 
                     24: int    vadebug = 0;
                     25: #define        dprintf if(vadebug)printf
                     26: 
                     27: unsigned minvaph();
                     28: 
                     29: #define        VAPRI   (PZERO-1)
                     30: 
                     31: struct vadevice {
                     32:        u_short vaba;                   /* buffer address */
                     33:        short   vawc;                   /* word count (2's complement) */
                     34:        union {
                     35:                short   Vacsw;          /* control status as word */
                     36:                struct {                /* control status as bytes */
                     37:                        char Vacsl;
                     38:                        char Vacsh;
                     39:                } vacsr;
                     40:        } vacs;
                     41:        short   vadata;                 /* programmed i/o data buffer */
                     42: };
                     43: 
                     44: #define        vacsw   vacs.Vacsw
                     45: #define        vacsh   vacs.vacsr.Vacsh
                     46: #define        vacsl   vacs.vacsr.Vacsl
                     47: 
                     48: /* vacsw bits */
                     49: #define        VA_ERROR        0100000         /* some error has occurred */
                     50: #define        VA_NPRTIMO      0001000         /* DMA timeout error */
                     51: #define        VA_NOTREADY     0000400         /* something besides NPRTIMO */
                     52: #define        VA_DONE         0000200
                     53: #define        VA_IENABLE      0000100         /* interrupt enable */
                     54: #define        VA_DMAGO        0000010         /* DMA go bit */
                     55: #define        VA_DMAGO        0000010         /* DMA go bit */
                     56: #define        VA_SUPPLIESLOW  0000004
                     57: #define        VA_BOTOFFORM    0000002
                     58: #define        VA_BYTEREVERSE  0000001         /* reverse byte order in words */
                     59: 
                     60: /* vacsh command bytes */
                     61: #define        VAPLOT          0000340
                     62: #define        VAPRINT         0000100
                     63: #define        VAPRINTPLOT     0000160
                     64: #define        VAAUTOSTEP      0000244
                     65: #define        VANOAUTOSTEP    0000045
                     66: #define        VAFORMFEED      0000263
                     67: #define        VASLEW          0000265
                     68: #define        VASTEP          0000064
                     69: 
                     70: struct va_softc {
                     71:        u_char  sc_openf;               /* exclusive open flag */
                     72:        u_char  sc_iostate;             /* kind of I/O going on */
                     73: #define        VAS_IDLE        0       /* no I/O, free */
                     74: #define        VAS_PIO         1       /* programmed I/O */
                     75: #define        VAS_DMA         2       /* DMA, block pio */
                     76: #define        VAS_WANT        4       /* wakeup when iostate changes */
                     77:        short   sc_tocnt;               /* time out counter */
                     78:        short   sc_info;                /* csw passed from vaintr */
                     79:        int     sc_state;               /* print/plot state of device */
                     80: } va_softc[NVA];
                     81: 
                     82: #define        VAUNIT(dev)     (minor(dev))
                     83: 
                     84: struct buf rvabuf[NVA];
                     85: 
                     86: int    vaprobe(), vaslave(), vaattach(), vadgo();
                     87: struct uba_device *vadinfo[NVA];
                     88: struct uba_ctlr *vaminfo[NVA];
                     89: struct buf vabhdr[NVA];
                     90: u_short        vastd[] = { 0764000, 0 };
                     91: struct uba_driver vadriver =
                     92:     { vaprobe, vaslave, vaattach, vadgo, vastd, "vz", vadinfo, "va", vaminfo };
                     93: 
                     94: vaprobe(reg)
                     95:        caddr_t reg;
                     96: {
                     97:        register int br, cvec;          /* value-result */
                     98:        register struct vadevice *vaaddr = (struct vadevice *)reg;
                     99: 
                    100: #ifdef lint
                    101:        br = 0; cvec = br; br = cvec;
                    102:        vaintr(0);
                    103: #endif
                    104: #ifndef UCBVAX
                    105:        vaaddr->vacsl = VA_IENABLE;
                    106:        vaaddr->vaba = 0;
                    107:        vaaddr->vacsh = VAPLOT;
                    108:        vaaddr->vacsl = VA_IENABLE|VA_DMAGO;
                    109:        vaaddr->vawc = -1;
                    110:        DELAY(10000);
                    111:        vaaddr->vacsl = 0;
                    112:        vaaddr->vawc = 0;
                    113: #else
                    114:        br=0x14;
                    115:        cvec=0170;
                    116: #endif
                    117:        return (sizeof (struct vadevice));
                    118: }
                    119: 
                    120: /*ARGSUSED*/
                    121: vaslave(ui, reg)
                    122:        struct uba_device *ui;
                    123:        caddr_t reg;
                    124: {
                    125: 
                    126:        ui->ui_dk = 0;
                    127:        return (ui->ui_unit <= 0);
                    128: }
                    129: 
                    130: /*ARGSUSED*/
                    131: vaattach(ui)
                    132:        struct uba_device *ui;
                    133: {
                    134: 
                    135:        ui->ui_mi->um_tab.b_actf = &vabhdr[ui->ui_unit];
                    136: }
                    137: 
                    138: vaopen(dev)
                    139:        dev_t dev;
                    140: {
                    141:        register struct va_softc *sc;
                    142:        register struct vadevice *vaaddr;
                    143:        register struct uba_device *ui;
                    144:        int error;
                    145:        int unit = VAUNIT(dev);
                    146: 
                    147:        if (unit >= NVA || (sc = &va_softc[unit])->sc_openf ||
                    148:            (ui = vadinfo[unit]) == 0 || ui->ui_alive == 0)
                    149:                return (ENXIO);
                    150:        vaaddr = (struct vadevice *)ui->ui_addr;
                    151:        sc->sc_openf = 1;
                    152:        vaaddr->vawc = 0;
                    153:        sc->sc_state = 0;
                    154:        sc->sc_tocnt = 0;
                    155:        sc->sc_iostate = VAS_IDLE;
                    156:        vaaddr->vacsl = VA_IENABLE;
                    157:        vatimo(dev);
                    158:        error = vacmd(dev, VPRINT);
                    159:        if (error)
                    160:                vaclose(dev);
                    161:        return (error);
                    162: }
                    163: 
                    164: vastrategy(bp)
                    165:        register struct buf *bp;
                    166: {
                    167:        register struct uba_device *ui;
                    168:        register struct uba_ctlr *um;
                    169:        int s;
                    170: 
                    171:        dprintf("vastrategy(%x)\n", bp);
                    172:        ui = vadinfo[VAUNIT(bp->b_dev)];
                    173:        if (ui == 0 || ui->ui_alive == 0) {
                    174:                bp->b_flags |= B_ERROR;
                    175:                iodone(bp);
                    176:                return;
                    177:        }
                    178:        s = spl4();
                    179:        um = ui->ui_mi;
                    180:        bp->b_actf = NULL;
                    181:        if (um->um_tab.b_actf->b_actf == NULL)
                    182:                um->um_tab.b_actf->b_actf = bp;
                    183:        else {
                    184:                printf("bp = 0x%x, um->um_tab.b_actf->b_actf = 0x%x\n",
                    185:                        bp, um->um_tab.b_actf->b_actf);
                    186:                panic("vastrategy");
                    187:                um->um_tab.b_actf->b_actl->b_forw = bp;
                    188:        }
                    189:        um->um_tab.b_actf->b_actl = bp;
                    190:        bp = um->um_tab.b_actf;
                    191:        dprintf("vastrategy: bp=%x actf=%x active=%d\n",
                    192:                bp, bp->b_actf, bp->b_active);
                    193:        if (bp->b_actf && bp->b_active == 0)
                    194:                (void) vastart(um);
                    195:        splx(s);
                    196: }
                    197: 
                    198: int    vablock = 16384;
                    199: 
                    200: unsigned
                    201: minvaph(bp)
                    202:        struct buf *bp;
                    203: {
                    204: 
                    205:        if (bp->b_bcount > vablock)
                    206:                bp->b_bcount = vablock;
                    207: }
                    208: 
                    209: /*ARGSUSED*/
                    210: vawrite(dev, uio)
                    211:        dev_t dev;
                    212:        struct uio *uio;
                    213: {
                    214: 
                    215:        if (VAUNIT(dev) > NVA)
                    216:                return (ENXIO);
                    217:        return (physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE,
                    218:                    minvaph, uio));
                    219: }
                    220: 
                    221: vastart(um)
                    222:        register struct uba_ctlr *um;
                    223: {
                    224:        struct buf *bp;
                    225:        struct vadevice *vaaddr;
                    226:        register struct va_softc *sc;
                    227:        int unit;
                    228: 
                    229:        dprintf("vastart(%x), bp=%x\n", um, um->um_tab.b_actf->b_actf);
                    230:        if ((bp = um->um_tab.b_actf->b_actf) == NULL)
                    231:                return;
                    232:        unit = VAUNIT(bp->b_dev);
                    233:        sc = &va_softc[unit];
                    234:        sc->sc_tocnt = 0;
                    235:        while (sc->sc_iostate&VAS_PIO) {
                    236:                sc->sc_iostate |= VAS_WANT;
                    237:                sleep((caddr_t)&sc->sc_iostate, VAPRI);
                    238:        }
                    239:        sc->sc_iostate |= VAS_DMA;
                    240:        vaaddr = (struct vadevice *)um->um_addr;
                    241:        vaaddr->vacsl = 0;
                    242:        vaaddr->vawc = -(bp->b_bcount / 2);
                    243:        um->um_cmd = VA_DMAGO | VA_IENABLE;
                    244:        (void) ubago(vadinfo[unit]);
                    245: }
                    246: 
                    247: vadgo(um)
                    248:        register struct uba_ctlr *um;
                    249: {
                    250:        register struct vadevice *vaaddr = (struct vadevice *)um->um_addr;
                    251:        register struct buf *bp;
                    252: 
                    253:        bp = um->um_tab.b_actf;
                    254:        va_softc[VAUNIT(bp->b_actf->b_dev)].sc_tocnt = 0;
                    255:        bp->b_active++;
                    256:        vaaddr->vaba = um->um_ubinfo;
                    257:        vaaddr->vacsl = ((um->um_ubinfo >> 12) & 0x30) | um->um_cmd;
                    258: }
                    259: 
                    260: /*ARGSUSED*/
                    261: vaioctl(dev, cmd, data, flag)
                    262:        register caddr_t data;
                    263: {
                    264:        register struct va_softc *sc = &va_softc[VAUNIT(dev)];
                    265: 
                    266:        switch (cmd) {
                    267: 
                    268:        case VGETSTATE:
                    269:                *(int *)data = sc->sc_state;
                    270:                break;
                    271: 
                    272:        case VSETSTATE:
                    273:                return (vacmd(dev, *(int *)data));
                    274: 
                    275:        default:
                    276:                return (ENOTTY);
                    277:        }
                    278:        return (0);
                    279: }
                    280: 
                    281: vacmd(dev, vcmd)
                    282:        dev_t dev;
                    283:        int vcmd;
                    284: {
                    285:        register struct va_softc *sc = &va_softc[VAUNIT(dev)];
                    286:        int error = 0;
                    287:        int s, cmd;
                    288: 
                    289:        s = spl4();
                    290:        while (sc->sc_iostate&VAS_DMA) {
                    291:                sc->sc_iostate |= VAS_WANT;
                    292:                sleep((caddr_t)&sc->sc_iostate, VAPRI);
                    293:        }
                    294:        sc->sc_iostate |= VAS_PIO;
                    295:        sc->sc_tocnt = 0;
                    296:        cmd = 0;
                    297:        switch (vcmd) {
                    298: 
                    299:        case VPLOT:
                    300:                /* Must turn on plot AND autostep modes. */
                    301:                if (vadopio(dev, VAPLOT))
                    302:                        error = EIO;
                    303:                cmd = VAAUTOSTEP;
                    304:                break;
                    305: 
                    306:        case VPRINT:
                    307:                cmd = VAPRINT;
                    308:                break;
                    309: 
                    310:        case VPRINTPLOT:
                    311:                cmd = VAPRINTPLOT;
                    312:                break;
                    313:        }
                    314:        sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
                    315:        if (cmd && vadopio(dev, cmd))
                    316:                error = EIO;
                    317:        sc->sc_iostate &= ~VAS_PIO;
                    318:        if (sc->sc_iostate&VAS_WANT) {
                    319:                sc->sc_iostate &= ~VAS_WANT;
                    320:                wakeup((caddr_t)&sc->sc_iostate);
                    321:        }
                    322:        splx(s);
                    323:        return (error);
                    324: }
                    325: 
                    326: vadopio(dev, cmd)
                    327:        dev_t dev;
                    328:        int cmd;
                    329: {
                    330:        register struct vadevice *vaaddr =
                    331:            (struct vadevice *)vaminfo[VAUNIT(dev)]->um_addr;
                    332:        register struct va_softc *sc = &va_softc[VAUNIT(dev)];
                    333: 
                    334:        sc->sc_info = 0;
                    335:        vaaddr->vacsh = cmd;
                    336:        while ((sc->sc_info&(VA_DONE|VA_ERROR)) == 0)
                    337:                sleep((caddr_t)&sc->sc_info, VAPRI);
                    338:        return (sc->sc_info&VA_ERROR);
                    339: }
                    340: 
                    341: vatimo(dev)
                    342:        dev_t dev;
                    343: {
                    344:        register struct va_softc *sc = &va_softc[VAUNIT(dev)];
                    345: 
                    346:        if (sc->sc_openf)
                    347:                timeout(vatimo, (caddr_t)dev, hz/2);
                    348:        if (++sc->sc_tocnt < 2)
                    349:                return;
                    350:        sc->sc_tocnt = 0;
                    351:        dprintf("vatimo: calling vaintr\n");
                    352:        vaintr(dev);
                    353: }
                    354: 
                    355: /*ARGSUSED*/
                    356: vaintr(dev)
                    357:        dev_t dev;
                    358: {
                    359:        register struct uba_ctlr *um;
                    360:        struct vadevice *vaaddr;
                    361:        struct buf *bp;
                    362:        register int unit = VAUNIT(dev), e;
                    363:        register struct va_softc *sc = &va_softc[unit];
                    364: 
                    365:        um = vaminfo[unit];
                    366:        vaaddr = (struct vadevice *)um->um_addr;
                    367:        e = vaaddr->vacsw;
                    368:        dprintf("vaintr: um=0x%x, e=0x%x, b_active %d\n",
                    369:                um, e, um->um_tab.b_actf->b_active);
                    370:        if ((e&(VA_DONE|VA_ERROR)) == 0)
                    371:                return;
                    372:        vaaddr->vacsl = 0;
                    373:        if ((e&VA_ERROR) && (e&VA_NPRTIMO))
                    374:                printf("va%d: npr timeout\n", unit);
                    375:        if (sc->sc_iostate&VAS_PIO) {
                    376:                sc->sc_info = e;
                    377:                wakeup((caddr_t)&sc->sc_info);
                    378:                return;
                    379:        }
                    380:        if (um->um_tab.b_actf->b_active) {
                    381:                bp = um->um_tab.b_actf->b_actf;
                    382:                if (e&VA_ERROR)
                    383:                        bp->b_flags |= B_ERROR;
                    384:                if (sc->sc_state&VPRINTPLOT) {
                    385:                        sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
                    386:                        vaaddr->vacsh = VAAUTOSTEP;
                    387:                        return;
                    388:                }
                    389:                ubadone(um);
                    390:                um->um_tab.b_actf->b_active = 0;
                    391:                um->um_tab.b_actf->b_actf = bp->b_forw;
                    392:                bp->b_active = 0;
                    393:                bp->b_errcnt = 0;
                    394:                bp->b_resid = 0;
                    395:                iodone(bp);
                    396:        }
                    397:        if (um->um_tab.b_actf->b_actf == 0) {
                    398:                sc->sc_iostate &= ~VAS_DMA;
                    399:                if (sc->sc_iostate&VAS_WANT) {
                    400:                        sc->sc_iostate &= ~VAS_WANT;
                    401:                        wakeup((caddr_t)&sc->sc_iostate);
                    402:                }
                    403:                return;
                    404:        }
                    405:        if (um->um_tab.b_actf->b_active == 0)
                    406:                vastart(um);
                    407: }
                    408: 
                    409: vaclose(dev)
                    410:        dev_t dev;
                    411: {
                    412:        register struct va_softc *sc = &va_softc[VAUNIT(dev)];
                    413:        register struct vadevice *vaaddr =
                    414:            (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
                    415: 
                    416:        sc->sc_openf = 0;
                    417:        sc->sc_state = 0;
                    418:        if (sc->sc_iostate != VAS_IDLE)
                    419:                wakeup((caddr_t)&sc->sc_iostate);
                    420:        sc->sc_iostate = VAS_IDLE;
                    421:        vaaddr->vacsl = 0;
                    422:        vaaddr->vawc = 0;
                    423: }
                    424: 
                    425: vareset(uban)
                    426:        int uban;
                    427: {
                    428:        register int va11;
                    429:        register struct uba_ctlr *um;
                    430:        register struct vadevice *vaaddr;
                    431:        register struct va_softc *sc;
                    432: 
                    433:        for (va11 = 0; va11 < NVA; va11++, sc++) {
                    434:                if ((um = vaminfo[va11]) == 0 || um->um_ubanum != uban ||
                    435:                    um->um_alive == 0)
                    436:                        continue;
                    437:                sc = &va_softc[um->um_ctlr];
                    438:                if (sc->sc_openf == 0)
                    439:                        continue;
                    440:                printf(" va%d", va11);
                    441:                vaaddr = (struct vadevice *)um->um_addr;
                    442:                vaaddr->vacsl = VA_IENABLE;
                    443:                if (sc->sc_state & VPLOT) {
                    444:                        vaaddr->vacsh = VAPLOT;
                    445:                        DELAY(10000);
                    446:                        vaaddr->vacsh = VAAUTOSTEP;
                    447:                } else if (sc->sc_state & VPRINTPLOT)
                    448:                        vaaddr->vacsh = VPRINTPLOT;
                    449:                else
                    450:                        vaaddr->vacsh = VAPRINTPLOT;
                    451:                DELAY(10000);
                    452:                sc->sc_iostate = VAS_IDLE;
                    453:                um->um_tab.b_actf->b_active = 0;
                    454:                um->um_tab.b_actf->b_actf = um->um_tab.b_actf->b_actl = 0;
                    455:                if (um->um_ubinfo) {
                    456:                        printf("<%d>", (um->um_ubinfo >> 28) & 0xf);
                    457:                        um->um_ubinfo = 0;
                    458:                }
                    459:                (void) vastart(um);
                    460:        }
                    461: }
                    462: 
                    463: vaselect()
                    464: {
                    465: 
                    466:        return (1);
                    467: }
                    468: #endif

unix.superglobalmegacorp.com

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