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