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

Defined functions

minvaph defined in line 206; used 2 times
vaattach defined in line 137; used 2 times
vaclose defined in line 415; used 1 times
vacmd defined in line 287; used 2 times
vadgo defined in line 253; used 2 times
vadopio defined in line 332; used 2 times
vaintr defined in line 362; used 2 times
vaioctl defined in line 267; never used
vaopen defined in line 144; never used
vaprobe defined in line 100; used 2 times
vareset defined in line 431; never used
vaselect defined in line 469; never used
vaslave defined in line 127; used 2 times
vastart defined in line 227; used 3 times
vastrategy defined in line 170; used 1 times
vatimo defined in line 347; used 2 times
vawrite defined in line 216; never used

Defined variables

rvabuf defined in line 90; used 1 times
va_softc defined in line 86; used 10 times
vabhdr defined in line 95; used 1 times
vablock defined in line 204; used 2 times
vadebug defined in line 30; used 1 times
  • in line 31
vadinfo defined in line 93; used 5 times
vadriver defined in line 97; never used
vaminfo defined in line 94; used 4 times
vastd defined in line 96; used 1 times
  • in line 98

Defined struct's

va_softc defined in line 76; used 18 times
vadevice defined in line 37; used 34 times

Defined macros

VAAUTOSTEP defined in line 70; used 3 times
VAFORMFEED defined in line 72; never used
VANOAUTOSTEP defined in line 71; never used
VAPLOT defined in line 67; used 3 times
VAPRI defined in line 35; used 3 times
VAPRINT defined in line 68; used 1 times
VAPRINTPLOT defined in line 69; used 2 times
VASLEW defined in line 73; never used
VASTEP defined in line 74; never used
VAS_DMA defined in line 81; used 3 times
VAS_IDLE defined in line 79; used 4 times
VAS_PIO defined in line 80; used 4 times
VAS_WANT defined in line 82; used 6 times
VAUNIT defined in line 88; used 14 times
VA_BOTOFFORM defined in line 63; never used
VA_BYTEREVERSE defined in line 64; never used
VA_DMAGO defined in line 61; used 2 times
VA_DONE defined in line 58; used 2 times
VA_ERROR defined in line 55; used 5 times
VA_IENABLE defined in line 59; used 5 times
VA_NOTREADY defined in line 57; never used
VA_NPRTIMO defined in line 56; used 1 times
VA_SUPPLIESLOW defined in line 62; never used
dprintf defined in line 31; used 5 times
vacsh defined in line 51; used 7 times
vacsl defined in line 52; used 9 times
vacsw defined in line 50; used 1 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1873
Valid CSS Valid XHTML 1.0 Strict