1 /* va.c 4.13 82/05/19 */ 2 3 #include "va.h" 4 #if NVA > 0 5 /* 6 * Varian printer plotter 7 */ 8 #include "../h/param.h" 9 #include "../h/dir.h" 10 #include "../h/user.h" 11 #include "../h/buf.h" 12 #include "../h/systm.h" 13 #include "../h/map.h" 14 #include "../h/pte.h" 15 #include "../h/ubareg.h" 16 #include "../h/ubavar.h" 17 #include "../h/vcmd.h" 18 19 unsigned minvaph(); 20 21 #define VAPRI (PZERO-1) 22 23 struct vadevice { 24 u_short vaba; /* buffer address */ 25 short vawc; /* word count (2's complement) */ 26 union { 27 short Vacsw; /* control status as word */ 28 struct { /* control status as bytes */ 29 char Vacsl; 30 char Vacsh; 31 } vacsr; 32 } vacs; 33 short vadata; /* programmed i/o data buffer */ 34 }; 35 36 #define vacsw vacs.Vacsw 37 #define vacsh vacs.vacsr.Vacsh 38 #define vacsl vacs.vacsr.Vacsl 39 40 /* vacsw bits */ 41 #define VA_ERROR 0100000 /* some error has occurred */ 42 #define VA_NPRTIMO 0001000 /* DMA timeout error */ 43 #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ 44 #define VA_DONE 0000200 45 #define VA_IENABLE 0000100 /* interrupt enable */ 46 #define VA_SUPPLIESLOW 0000004 47 #define VA_BOTOFFORM 0000002 48 #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ 49 50 /* vacsh command bytes */ 51 #define VAPLOT 0000340 52 #define VAPRINT 0000100 53 #define VAPRINTPLOT 0000160 54 #define VAAUTOSTEP 0000244 55 #define VANOAUTOSTEP 0000045 56 #define VAFORMFEED 0000263 57 #define VASLEW 0000265 58 #define VASTEP 0000064 59 60 struct va_softc { 61 char sc_openf; 62 char sc_busy; 63 int sc_state; 64 int sc_wc; 65 struct buf *sc_bp; 66 int sc_ubinfo; 67 } va_softc[NVA]; 68 69 #define VAUNIT(dev) (minor(dev)) 70 71 struct buf rvabuf[NVA]; 72 73 int vaprobe(), vaattach(); 74 struct uba_device *vadinfo[NVA]; 75 u_short vastd[] = { 0764000, 0 }; 76 struct uba_driver vadriver = 77 { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; 78 79 vaprobe(reg) 80 caddr_t reg; 81 { 82 register int br, cvec; /* value-result */ 83 register struct vadevice *vaaddr = (struct vadevice *)reg; 84 85 #ifdef lint 86 br = 0; cvec = br; br = cvec; 87 vaintr(0); 88 #endif 89 vaaddr->vacsl = VA_IENABLE; 90 vaaddr->vaba = 0; 91 vaaddr->vacsh = VAPLOT; 92 vaaddr->vacsl = 0; 93 vaaddr->vawc = -1; 94 DELAY(100000); 95 vaaddr->vacsl = 0; 96 } 97 98 /*ARGSUSED*/ 99 vaattach(ui) 100 struct uba_device *ui; 101 { 102 103 } 104 105 vaopen(dev) 106 dev_t dev; 107 { 108 register struct va_softc *sc; 109 register struct vadevice *vaaddr; 110 register struct uba_device *ui; 111 112 if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || 113 (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { 114 u.u_error = ENXIO; 115 return; 116 } 117 vaaddr = (struct vadevice *)ui->ui_addr; 118 sc->sc_openf = 1; 119 vaaddr->vawc = 0; 120 sc->sc_wc = 0; 121 sc->sc_state = 0; 122 vaaddr->vacsl = VA_IENABLE; 123 vatimo(dev); 124 vacmd(dev, VPRINT); 125 if (u.u_error) 126 vaclose(dev); 127 } 128 129 vastrategy(bp) 130 register struct buf *bp; 131 { 132 register int e; 133 register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; 134 register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; 135 register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; 136 137 (void) spl4(); 138 while (sc->sc_busy) 139 sleep((caddr_t)sc, VAPRI); 140 sc->sc_busy = 1; 141 sc->sc_bp = bp; 142 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); 143 if (e = vawait(bp->b_dev)) 144 goto brkout; 145 sc->sc_wc = -(bp->b_bcount/2); 146 vastart(bp->b_dev); 147 e = vawait(bp->b_dev); 148 sc->sc_wc = 0; 149 if (sc->sc_state & VPRINTPLOT) { 150 sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; 151 vaaddr->vacsh = VAAUTOSTEP; 152 e |= vawait(bp->b_dev); 153 } 154 (void) spl0(); 155 brkout: 156 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 157 sc->sc_bp = 0; 158 sc->sc_busy = 0; 159 iodone(bp); 160 if (e) 161 u.u_error = EIO; 162 wakeup((caddr_t)sc); 163 } 164 165 int vablock = 16384; 166 167 unsigned 168 minvaph(bp) 169 struct buf *bp; 170 { 171 172 if (bp->b_bcount > vablock) 173 bp->b_bcount = vablock; 174 } 175 176 /*ARGSUSED*/ 177 vawrite(dev) 178 dev_t dev; 179 { 180 181 physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph); 182 } 183 184 vawait(dev) 185 dev_t dev; 186 { 187 register struct vadevice *vaaddr = 188 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 189 register int e; 190 191 while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) 192 sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); 193 if (e & VA_NPRTIMO) 194 printf("va%d: npr timeout\n", VAUNIT(dev)); 195 return (e & VA_ERROR); 196 } 197 198 vastart(dev) 199 dev_t; 200 { 201 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 202 register struct vadevice *vaaddr = 203 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 204 205 if (sc->sc_wc == 0) 206 return; 207 vaaddr->vaba = sc->sc_ubinfo; 208 vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; 209 vaaddr->vawc = sc->sc_wc; 210 } 211 212 /*ARGSUSED*/ 213 vaioctl(dev, cmd, addr, flag) 214 register caddr_t addr; 215 { 216 register int vcmd; 217 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 218 219 switch (cmd) { 220 221 case VGETSTATE: 222 (void) suword(addr, sc->sc_state); 223 return; 224 225 case VSETSTATE: 226 vcmd = fuword(addr); 227 if (vcmd == -1) { 228 u.u_error = EFAULT; 229 return; 230 } 231 vacmd(dev, vcmd); 232 return; 233 234 default: 235 u.u_error = ENOTTY; 236 return; 237 } 238 } 239 240 vacmd(dev, vcmd) 241 dev_t dev; 242 int vcmd; 243 { 244 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 245 register struct vadevice *vaaddr = 246 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 247 248 (void) spl4(); 249 (void) vawait(dev); 250 switch (vcmd) { 251 252 case VPLOT: 253 /* Must turn on plot AND autostep modes. */ 254 vaaddr->vacsh = VAPLOT; 255 if (vawait(dev)) 256 u.u_error = EIO; 257 vaaddr->vacsh = VAAUTOSTEP; 258 break; 259 260 case VPRINT: 261 vaaddr->vacsh = VAPRINT; 262 break; 263 264 case VPRINTPLOT: 265 vaaddr->vacsh = VAPRINTPLOT; 266 break; 267 } 268 sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; 269 if (vawait(dev)) 270 u.u_error = EIO; 271 (void) spl0(); 272 } 273 274 vatimo(dev) 275 dev_t dev; 276 { 277 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 278 279 if (sc->sc_openf) 280 timeout(vatimo, (caddr_t)dev, hz/10); 281 vaintr(dev); 282 } 283 284 /*ARGSUSED*/ 285 vaintr(dev) 286 dev_t dev; 287 { 288 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 289 290 wakeup((caddr_t)sc); 291 } 292 293 vaclose(dev) 294 dev_t dev; 295 { 296 register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 297 register struct vadevice *vaaddr = 298 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 299 300 sc->sc_openf = 0; 301 sc->sc_busy = 0; 302 sc->sc_state = 0; 303 sc->sc_ubinfo = 0; 304 vaaddr->vacsl = 0; 305 } 306 307 vareset(uban) 308 int uban; 309 { 310 register int va11; 311 register struct uba_device *ui; 312 register struct va_softc *sc = va_softc; 313 register struct vadevice *vaaddr; 314 315 for (va11 = 0; va11 < NVA; va11++, sc++) { 316 if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || 317 ui->ui_ubanum != uban || sc->sc_openf == 0) 318 continue; 319 printf(" va%d", va11); 320 vaaddr = (struct vadevice *)ui->ui_addr; 321 vaaddr->vacsl = VA_IENABLE; 322 if (sc->sc_state & VPLOT) { 323 vaaddr->vacsh = VAPLOT; 324 DELAY(10000); 325 vaaddr->vacsh = VAAUTOSTEP; 326 } else if (sc->sc_state & VPRINTPLOT) 327 vaaddr->vacsh = VPRINTPLOT; 328 else 329 vaaddr->vacsh = VAPRINTPLOT; 330 DELAY(10000); 331 if (sc->sc_busy == 0) 332 continue; 333 if (sc->sc_ubinfo) { 334 printf("<%d>", (sc->sc_ubinfo>>28)&0xf); 335 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 336 } 337 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); 338 sc->sc_wc = -(sc->sc_bp->b_bcount/2); 339 vastart(sc->sc_bp->b_dev); 340 } 341 } 342 343 vaselect() 344 { 345 return (1); 346 } 347 #endif 348