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:  *	@(#)vp.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "vp.h"
  10: #if NVP > 0
  11: /*
  12:  * Versatec matrix printer/plotter
  13:  * dma interface driver
  14:  *
  15:  * SETUP NOTES:
  16:  *	Set up both print and plot interrupts to go through the same vector
  17:  *	(or kludge probe to reset second vector to first;
  18:  *	default 174/200 is already handled).
  19:  *	Give the address of the plcsr register in the config specification
  20:  */
  21: #include "../machine/pte.h"
  22: 
  23: #include "param.h"
  24: #include "dir.h"
  25: #include "user.h"
  26: #include "buf.h"
  27: #include "systm.h"
  28: #include "map.h"
  29: #include "ioctl.h"
  30: #include "vcmd.h"
  31: #include "uio.h"
  32: #include "kernel.h"
  33: 
  34: #include "ubavar.h"
  35: #include "ubareg.h"
  36: 
  37: unsigned minvpph();
  38: 
  39: #define VPPRI   (PZERO-1)
  40: 
  41: struct  vpdevice {
  42:     short   plbcr;
  43:     short   pbxaddr;
  44:     short   prbcr;
  45:     u_short pbaddr;
  46:     short   plcsr;
  47:     short   plbuf;
  48:     short   prcsr;
  49:     u_short prbuf;
  50: };
  51: 
  52: #define VP_ERROR    0100000
  53: #define VP_DTCINTR  0040000
  54: #define VP_DMAACT   0020000
  55: #define VP_READY    0000200
  56: #define VP_IENABLE  0000100
  57: #define VP_TERMCOM  0000040
  58: #define VP_FFCOM    0000020
  59: #define VP_EOTCOM   0000010
  60: #define VP_CLRCOM   0000004
  61: #define VP_RESET    0000002
  62: #define VP_SPP      0000001
  63: 
  64: struct vp_softc {
  65:     int sc_state;
  66:     int sc_count;
  67:     int sc_bufp;
  68:     struct  buf *sc_bp;
  69:     int sc_ubinfo;
  70: } vp_softc[NVP];
  71: 
  72: /* sc_state bits */
  73: #define VPSC_BUSY   0001000
  74: #define VPSC_MODE   0000700
  75: #define VPSC_SPP    0000400
  76: #define VPSC_PLOT   0000200
  77: #define VPSC_PRINT  0000100
  78: #define VPSC_CMNDS  0000076
  79: #define VPSC_OPEN   0000001
  80: 
  81: struct  uba_device *vpdinfo[NVP];
  82: 
  83: #define VPUNIT(dev) (minor(dev))
  84: 
  85: struct  buf rvpbuf[NVP];
  86: 
  87: int vpprobe(), vpattach();
  88: struct  uba_device *vpdinfo[NVP];
  89: u_short vpstd[] = { 0777500, 0 };
  90: struct  uba_driver vpdriver =
  91:     { vpprobe, 0, vpattach, 0, vpstd, "vp", vpdinfo };
  92: 
  93: vpprobe(reg)
  94:     caddr_t reg;
  95: {
  96:     register int br, cvec;      /* value-result */
  97:     register struct vpdevice *vpaddr = (struct vpdevice *)(reg-010);
  98: 
  99: #ifdef lint
 100:     br = 0; cvec = br; br = cvec;
 101:     vpintr(0);
 102: #endif
 103:     vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
 104:     vpaddr->pbaddr = 0;
 105:     vpaddr->pbxaddr = 0;
 106:     vpaddr->prbcr = 1;
 107:     DELAY(10000);
 108:     vpaddr->prcsr = 0;
 109:     /* GET INTERRUPT AT SECOND VECTOR BUT WANT FIRST */
 110:     if (cvec == 0200) {
 111:         printf("vp reset vec from 200 to 174\n");
 112:         cvec = 0174;
 113:     }
 114:     return (sizeof (struct vpdevice));
 115: }
 116: 
 117: /*ARGSUSED*/
 118: vpattach(ui)
 119:     struct uba_device *ui;
 120: {
 121: 
 122:     ui->ui_addr -= 010;
 123:     ui->ui_physaddr -= 010;
 124: }
 125: 
 126: vpopen(dev)
 127:     dev_t dev;
 128: {
 129:     register struct vp_softc *sc;
 130:     register struct vpdevice *vpaddr;
 131:     register struct uba_device *ui;
 132: 
 133:     if (VPUNIT(dev) >= NVP ||
 134:         ((sc = &vp_softc[minor(dev)])->sc_state&VPSC_OPEN) ||
 135:         (ui = vpdinfo[VPUNIT(dev)]) == 0 || ui->ui_alive == 0)
 136:         return (ENXIO);
 137:     vpaddr = (struct vpdevice *)ui->ui_addr;
 138:     sc->sc_state = VPSC_OPEN|VPSC_PRINT | VP_CLRCOM|VP_RESET;
 139:     sc->sc_count = 0;
 140:     vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
 141:     vptimo(dev);
 142:     while (sc->sc_state & VPSC_CMNDS) {
 143:         (void) spl4();
 144:         if (vpwait(dev)) {
 145:             vpclose(dev);
 146:             return (EIO);
 147:         }
 148:         vpstart(dev);
 149:         (void) spl0();
 150:     }
 151:     return (0);
 152: }
 153: 
 154: vpstrategy(bp)
 155:     register struct buf *bp;
 156: {
 157:     register int e;
 158:     register struct vp_softc *sc = &vp_softc[VPUNIT(bp->b_dev)];
 159:     register struct uba_device *ui = vpdinfo[VPUNIT(bp->b_dev)];
 160:     register struct vpdevice *vpaddr = (struct vpdevice *)ui->ui_addr;
 161: 
 162:     (void) spl4();
 163:     while (sc->sc_state & VPSC_BUSY)
 164:         sleep((caddr_t)sc, VPPRI);
 165:     sc->sc_state |= VPSC_BUSY;
 166:     sc->sc_bp = bp;
 167:     sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
 168:     if (e = vpwait(bp->b_dev))
 169:         goto brkout;
 170:     sc->sc_count = bp->b_bcount;
 171:     vpstart(bp->b_dev);
 172:     while (((sc->sc_state&VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr) & VP_DMAACT)
 173:         sleep((caddr_t)sc, VPPRI);
 174:     sc->sc_count = 0;
 175:     if ((sc->sc_state&VPSC_MODE) == VPSC_SPP)
 176:         sc->sc_state = (sc->sc_state &~ VPSC_MODE) | VPSC_PLOT;
 177:     (void) spl0();
 178: brkout:
 179:     ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
 180:     sc->sc_state &= ~VPSC_BUSY;
 181:     sc->sc_bp = 0;
 182:     if (e)
 183:         bp->b_flags |= B_ERROR;
 184:     iodone(bp);
 185:     wakeup((caddr_t)sc);
 186: }
 187: 
 188: int vpblock = 16384;
 189: 
 190: unsigned
 191: minvpph(bp)
 192:     struct buf *bp;
 193: {
 194: 
 195:     if (bp->b_bcount > vpblock)
 196:         bp->b_bcount = vpblock;
 197: }
 198: 
 199: /*ARGSUSED*/
 200: vpwrite(dev, uio)
 201:     dev_t dev;
 202:     struct uio *uio;
 203: {
 204: 
 205:     if (VPUNIT(dev) >= NVP)
 206:         return (ENXIO);
 207:     return (physio(vpstrategy, &rvpbuf[VPUNIT(dev)], dev, B_WRITE,
 208:             minvpph, uio));
 209: }
 210: 
 211: vpwait(dev)
 212:     dev_t dev;
 213: {
 214:     register struct vpdevice *vpaddr =
 215:         (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
 216:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 217:     register int e;
 218: 
 219:     for (;;) {
 220:         e = (sc->sc_state & VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr;
 221:         if (e & (VP_READY|VP_ERROR))
 222:             break;
 223:         sleep((caddr_t)sc, VPPRI);
 224:     }
 225:     /* I WISH I COULD TELL WHETHER AN ERROR INDICATED AN NPR TIMEOUT */
 226:     return (e & VP_ERROR);
 227: }
 228: 
 229: vpstart(dev)
 230:     dev_t;
 231: {
 232:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 233:     register struct vpdevice *vpaddr =
 234:         (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
 235:     short bit;
 236: 
 237:     if (sc->sc_count) {
 238:         vpaddr->pbaddr = sc->sc_ubinfo;
 239:         vpaddr->pbxaddr = (sc->sc_ubinfo>>12)&0x30;
 240:         if (sc->sc_state & (VPSC_PRINT|VPSC_SPP))
 241:             vpaddr->prbcr = sc->sc_count;
 242:         else
 243:             vpaddr->plbcr = sc->sc_count;
 244:         return;
 245:     }
 246:     for (bit = 1; bit != 0; bit <<= 1)
 247:         if (sc->sc_state&bit&VPSC_CMNDS) {
 248:             vpaddr->plcsr |= bit;
 249:             sc->sc_state &= ~bit;
 250:             return;
 251:         }
 252: }
 253: 
 254: /*ARGSUSED*/
 255: vpioctl(dev, cmd, data, flag)
 256:     dev_t dev;
 257:     int cmd;
 258:     register caddr_t data;
 259:     int flag;
 260: {
 261:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 262:     register struct vpdevice *vpaddr =
 263:         (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
 264: 
 265:     switch (cmd) {
 266: 
 267:     case VGETSTATE:
 268:         *(int *)data = sc->sc_state;
 269:         return (0);
 270: 
 271:     case VSETSTATE:
 272:         sc->sc_state =
 273:             (sc->sc_state & ~VPSC_MODE) |
 274:             ((*(int *)data) & (VPSC_MODE|VPSC_CMNDS));
 275:         break;
 276: 
 277:     default:
 278:         return (ENOTTY);
 279:     }
 280:     (void) spl4();
 281:     (void) vpwait(dev);
 282:     if (sc->sc_state&VPSC_SPP)
 283:         vpaddr->plcsr |= VP_SPP;
 284:     else
 285:         vpaddr->plcsr &= ~VP_SPP;
 286:     sc->sc_count = 0;
 287:     while (sc->sc_state & VPSC_CMNDS) {
 288:         (void) vpwait(dev);
 289:         vpstart(dev);
 290:     }
 291:     (void) spl0();
 292:     return (0);
 293: }
 294: 
 295: vptimo(dev)
 296:     dev_t dev;
 297: {
 298:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 299: 
 300:     if (sc->sc_state&VPSC_OPEN)
 301:         timeout(vptimo, (caddr_t)dev, hz/10);
 302:     vpintr(dev);
 303: }
 304: 
 305: /*ARGSUSED*/
 306: vpintr(dev)
 307:     dev_t dev;
 308: {
 309:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 310: 
 311:     wakeup((caddr_t)sc);
 312: }
 313: 
 314: vpclose(dev)
 315:     dev_t dev;
 316: {
 317:     register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
 318:     register struct vpdevice *vpaddr =
 319:         (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
 320: 
 321:     sc->sc_state = 0;
 322:     sc->sc_count = 0;
 323:     vpaddr->plcsr = 0;
 324: }
 325: 
 326: vpreset(uban)
 327:     int uban;
 328: {
 329:     register int vp11;
 330:     register struct uba_device *ui;
 331:     register struct vp_softc *sc = vp_softc;
 332:     register struct vpdevice *vpaddr;
 333: 
 334:     for (vp11 = 0; vp11 < NVP; vp11++, sc++) {
 335:         if ((ui = vpdinfo[vp11]) == 0 || ui->ui_alive == 0 ||
 336:             ui->ui_ubanum != uban || (sc->sc_state&VPSC_OPEN) == 0)
 337:             continue;
 338:         printf(" vp%d", vp11);
 339:         vpaddr = (struct vpdevice *)ui->ui_addr;
 340:         vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
 341:         if ((sc->sc_state & VPSC_BUSY) == 0)
 342:             continue;
 343:         sc->sc_ubinfo = 0;
 344:         sc->sc_count = sc->sc_bp->b_bcount;
 345:         vpstart(sc->sc_bp->b_dev);
 346:     }
 347: }
 348: 
 349: vpselect()
 350: {
 351:     return (1);
 352: }
 353: #endif

Defined functions

minvpph defined in line 190; used 2 times
vpattach defined in line 118; used 2 times
vpclose defined in line 314; used 1 times
vpintr defined in line 306; used 2 times
vpioctl defined in line 255; never used
vpopen defined in line 126; never used
vpprobe defined in line 93; used 2 times
vpreset defined in line 326; never used
vpselect defined in line 349; never used
vpstart defined in line 229; used 4 times
vpstrategy defined in line 154; used 1 times
vptimo defined in line 295; used 2 times
vpwait defined in line 211; used 4 times
vpwrite defined in line 200; never used

Defined variables

rvpbuf defined in line 85; used 1 times
vp_softc defined in line 70; used 9 times
vpblock defined in line 188; used 2 times
vpdinfo defined in line 88; used 8 times
vpdriver defined in line 90; never used
vpstd defined in line 89; used 1 times
  • in line 91

Defined struct's

vp_softc defined in line 64; used 18 times
vpdevice defined in line 41; used 34 times

Defined macros

VPPRI defined in line 39; used 3 times
VPSC_BUSY defined in line 73; used 4 times
VPSC_CMNDS defined in line 78; used 4 times
VPSC_MODE defined in line 74; used 4 times
VPSC_OPEN defined in line 79; used 4 times
VPSC_PLOT defined in line 76; used 3 times
VPSC_PRINT defined in line 77; used 2 times
VPSC_SPP defined in line 75; used 3 times
VPUNIT defined in line 83; used 16 times
VP_CLRCOM defined in line 60; used 1 times
VP_DMAACT defined in line 54; used 1 times
VP_DTCINTR defined in line 53; used 3 times
VP_EOTCOM defined in line 59; never used
VP_ERROR defined in line 52; used 2 times
VP_FFCOM defined in line 58; never used
VP_IENABLE defined in line 56; used 3 times
VP_READY defined in line 55; used 1 times
VP_RESET defined in line 61; used 1 times
VP_SPP defined in line 62; used 2 times
VP_TERMCOM defined in line 57; never used
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1749
Valid CSS Valid XHTML 1.0 Strict