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