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

unix.superglobalmegacorp.com

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