1 /* va.c 4.21 83/03/10 */ 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 int vcmd; 265 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 266 267 switch (cmd) { 268 269 case VGETSTATE: 270 *(int *)data = sc->sc_state; 271 break; 272 273 case VSETSTATE: 274 return (vacmd(dev, *(int *)data)); 275 break; 276 277 default: 278 return (ENOTTY); 279 } 280 return (0); 281 } 282 283 vacmd(dev, vcmd) 284 dev_t dev; 285 int vcmd; 286 { 287 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 288 int error = 0; 289 int s, cmd; 290 291 s = spl4(); 292 while (sc->sc_iostate&VAS_DMA) { 293 sc->sc_iostate |= VAS_WANT; 294 sleep((caddr_t)&sc->sc_iostate, VAPRI); 295 } 296 sc->sc_iostate |= VAS_PIO; 297 sc->sc_tocnt = 0; 298 cmd = 0; 299 switch (vcmd) { 300 301 case VPLOT: 302 /* Must turn on plot AND autostep modes. */ 303 if (vadopio(dev, VAPLOT)) 304 error = EIO; 305 cmd = VAAUTOSTEP; 306 break; 307 308 case VPRINT: 309 cmd = VAPRINT; 310 break; 311 312 case VPRINTPLOT: 313 cmd = VAPRINTPLOT; 314 break; 315 } 316 sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; 317 if (cmd && vadopio(dev, cmd)) 318 error = EIO; 319 sc->sc_iostate &= ~VAS_PIO; 320 if (sc->sc_iostate&VAS_WANT) { 321 sc->sc_iostate &= ~VAS_WANT; 322 wakeup((caddr_t)&sc->sc_iostate); 323 } 324 splx(s); 325 return (error); 326 } 327 328 vadopio(dev, cmd) 329 dev_t dev; 330 int cmd; 331 { 332 register struct vadevice *vaaddr = 333 (struct vadevice *)vaminfo[VAUNIT(dev)]->um_addr; 334 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 335 336 sc->sc_info = 0; 337 vaaddr->vacsh = cmd; 338 while ((sc->sc_info&(VA_DONE|VA_ERROR)) == 0) 339 sleep((caddr_t)&sc->sc_info, VAPRI); 340 return (sc->sc_info&VA_ERROR); 341 } 342 343 vatimo(dev) 344 dev_t dev; 345 { 346 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 347 348 if (sc->sc_openf) 349 timeout(vatimo, (caddr_t)dev, hz/2); 350 if (++sc->sc_tocnt < 2) 351 return; 352 sc->sc_tocnt = 0; 353 dprintf("vatimo: calling vaintr\n"); 354 vaintr(dev); 355 } 356 357 /*ARGSUSED*/ 358 vaintr(dev) 359 dev_t dev; 360 { 361 register struct uba_ctlr *um; 362 struct vadevice *vaaddr; 363 struct buf *bp; 364 register int unit = VAUNIT(dev), e; 365 register struct va_softc *sc = &va_softc[unit]; 366 367 um = vaminfo[unit]; 368 vaaddr = (struct vadevice *)um->um_addr; 369 e = vaaddr->vacsw; 370 dprintf("vaintr: um=0x%x, e=0x%x, b_active %d\n", 371 um, e, um->um_tab.b_actf->b_active); 372 if ((e&(VA_DONE|VA_ERROR)) == 0) 373 return; 374 vaaddr->vacsl = 0; 375 if ((e&VA_ERROR) && (e&VA_NPRTIMO)) 376 printf("va%d: npr timeout\n", unit); 377 if (sc->sc_iostate&VAS_PIO) { 378 sc->sc_info = e; 379 wakeup((caddr_t)&sc->sc_info); 380 return; 381 } 382 if (um->um_tab.b_actf->b_active) { 383 bp = um->um_tab.b_actf->b_actf; 384 if (e&VA_ERROR) 385 bp->b_flags |= B_ERROR; 386 if (sc->sc_state&VPRINTPLOT) { 387 sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; 388 vaaddr->vacsh = VAAUTOSTEP; 389 return; 390 } 391 ubadone(um); 392 um->um_tab.b_actf->b_active = 0; 393 um->um_tab.b_actf->b_actf = bp->b_forw; 394 bp->b_active = 0; 395 bp->b_errcnt = 0; 396 bp->b_resid = 0; 397 iodone(bp); 398 } 399 if (um->um_tab.b_actf->b_actf == 0) { 400 sc->sc_iostate &= ~VAS_DMA; 401 if (sc->sc_iostate&VAS_WANT) { 402 sc->sc_iostate &= ~VAS_WANT; 403 wakeup((caddr_t)&sc->sc_iostate); 404 } 405 return; 406 } 407 if (um->um_tab.b_actf->b_active == 0) 408 vastart(um); 409 } 410 411 vaclose(dev) 412 dev_t dev; 413 { 414 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 415 register struct vadevice *vaaddr = 416 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 417 418 sc->sc_openf = 0; 419 sc->sc_state = 0; 420 if (sc->sc_iostate != VAS_IDLE) 421 wakeup((caddr_t)&sc->sc_iostate); 422 sc->sc_iostate = VAS_IDLE; 423 vaaddr->vacsl = 0; 424 vaaddr->vawc = 0; 425 } 426 427 vareset(uban) 428 int uban; 429 { 430 register int va11; 431 register struct uba_ctlr *um; 432 register struct vadevice *vaaddr; 433 register struct va_softc *sc; 434 435 for (va11 = 0; va11 < NVA; va11++, sc++) { 436 if ((um = vaminfo[va11]) == 0 || um->um_ubanum != uban || 437 um->um_alive == 0) 438 continue; 439 sc = &va_softc[um->um_ctlr]; 440 if (sc->sc_openf == 0) 441 continue; 442 printf(" va%d", va11); 443 vaaddr = (struct vadevice *)um->um_addr; 444 vaaddr->vacsl = VA_IENABLE; 445 if (sc->sc_state & VPLOT) { 446 vaaddr->vacsh = VAPLOT; 447 DELAY(10000); 448 vaaddr->vacsh = VAAUTOSTEP; 449 } else if (sc->sc_state & VPRINTPLOT) 450 vaaddr->vacsh = VPRINTPLOT; 451 else 452 vaaddr->vacsh = VAPRINTPLOT; 453 DELAY(10000); 454 sc->sc_iostate = VAS_IDLE; 455 um->um_tab.b_actf->b_active = 0; 456 um->um_tab.b_actf->b_actf = um->um_tab.b_actf->b_actl = 0; 457 if (um->um_ubinfo) { 458 printf("<%d>", (um->um_ubinfo >> 28) & 0xf); 459 um->um_ubinfo = 0; 460 } 461 (void) vastart(um); 462 } 463 } 464 465 vaselect() 466 { 467 468 return (1); 469 } 470 #endif 471