|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.