1*288Sbill /* vp.c 3.4 06/22/80 */ 244Sbill 344Sbill #include "../h/param.h" 444Sbill #include "../h/dir.h" 544Sbill #include "../h/user.h" 644Sbill #include "../h/buf.h" 744Sbill #include "../h/systm.h" 844Sbill #include "../h/map.h" 944Sbill #include "../h/pte.h" 1044Sbill #include "../h/uba.h" 1144Sbill 1244Sbill /* 1344Sbill * Versatec matrix printer/plotter 1444Sbill * dma interface driver 1544Sbill */ 1644Sbill int vpbdp = 1; 1744Sbill 1844Sbill unsigned minvpph(); 1944Sbill 2044Sbill #define VPPRI (PZERO-1) 2144Sbill 2244Sbill struct vpregs { 2344Sbill short plbcr; 2444Sbill short fill; 2544Sbill short prbcr; 2644Sbill unsigned short pbaddr; 2744Sbill short plcsr; 2844Sbill short plbuf; 2944Sbill short prcsr; 3044Sbill unsigned short prbuf; 3144Sbill }; 3244Sbill 3344Sbill #define VPADDR ((struct vpregs *)(UBA0_DEV + 0177500)) 3444Sbill 3544Sbill #define ERROR 0100000 3644Sbill #define DTCINTR 040000 3744Sbill #define DMAACT 020000 3844Sbill #define READY 0200 3944Sbill #define IENABLE 0100 4044Sbill #define TERMCOM 040 4144Sbill #define FFCOM 020 4244Sbill #define EOTCOM 010 4344Sbill #define CLRCOM 04 4444Sbill #define RESET 02 4544Sbill #define SPP 01 4644Sbill 4744Sbill struct { 4844Sbill int vp_state; 4944Sbill int vp_count; 5044Sbill int vp_bufp; 51*288Sbill struct buf *vp_bp; 5244Sbill } vp11; 5344Sbill int vp_ubinfo; 5444Sbill 5544Sbill struct buf rvpbuf; 5644Sbill 5744Sbill #define VISOPEN 01 5844Sbill #define CMNDS 076 5944Sbill #define MODE 0700 6044Sbill #define PRINT 0100 6144Sbill #define PLOT 0200 6244Sbill #define PPLOT 0400 6344Sbill #define VBUSY 01000 6444Sbill 6544Sbill vpopen() 6644Sbill { 6744Sbill 6844Sbill if (vp11.vp_state & VISOPEN) { 6944Sbill u.u_error = ENXIO; 7044Sbill return; 7144Sbill } 7244Sbill vp11.vp_state = VISOPEN | PRINT | CLRCOM | RESET; 7344Sbill vp11.vp_count = 0; 7444Sbill VPADDR->prcsr = IENABLE | DTCINTR; 7544Sbill vptimo(); 7644Sbill while (vp11.vp_state & CMNDS) { 77134Sbill (void) spl4(); 7844Sbill if (vperror(READY)) { 7944Sbill vpclose(); 8044Sbill u.u_error = EIO; 8144Sbill return; 8244Sbill } 8344Sbill vpstart(); 84134Sbill (void) spl0(); 8544Sbill } 8644Sbill } 8744Sbill 8844Sbill vpstrategy(bp) 8944Sbill register struct buf *bp; 9044Sbill { 9144Sbill register int e; 9244Sbill 93134Sbill (void) spl4(); 9444Sbill while (vp11.vp_state & VBUSY) 9544Sbill sleep((caddr_t)&vp11, VPPRI); 9644Sbill vp11.vp_state |= VBUSY; 97*288Sbill vp11.vp_bp = bp; 9844Sbill vp_ubinfo = ubasetup(bp, vpbdp); 9944Sbill vp11.vp_bufp = vp_ubinfo & 0x3ffff; 10044Sbill if (e = vperror(READY)) 10144Sbill goto brkout; 10244Sbill vp11.vp_count = bp->b_bcount; 10344Sbill vpstart(); 10444Sbill while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT) 10544Sbill sleep((caddr_t)&vp11, VPPRI); 10644Sbill vp11.vp_count = 0; 10744Sbill vp11.vp_bufp = 0; 10844Sbill if ((vp11.vp_state&MODE) == PPLOT) 10944Sbill vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT; 110134Sbill (void) spl0(); 11144Sbill brkout: 11244Sbill ubafree(vp_ubinfo), vp_ubinfo = 0; 11344Sbill vp11.vp_state &= ~VBUSY; 114*288Sbill vp11.vp_bp = 0; 11544Sbill iodone(bp); 11644Sbill if (e) 11744Sbill u.u_error = EIO; 11844Sbill wakeup((caddr_t)&vp11); 11944Sbill } 12044Sbill 12144Sbill int vpblock = 16384; 12244Sbill 12344Sbill unsigned 12444Sbill minvpph(bp) 12544Sbill struct buf *bp; 12644Sbill { 12744Sbill 12844Sbill if (bp->b_bcount > vpblock) 12944Sbill bp->b_bcount = vpblock; 13044Sbill } 13144Sbill 13244Sbill /*ARGSUSED*/ 13344Sbill vpwrite(dev) 13444Sbill { 13544Sbill 13644Sbill physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph); 13744Sbill } 13844Sbill 13944Sbill vperror(bit) 14044Sbill { 14144Sbill register int state, e; 14244Sbill 14344Sbill state = vp11.vp_state & PLOT; 14444Sbill while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0) 14544Sbill sleep((caddr_t)&vp11, VPPRI); 14644Sbill return (e & ERROR); 14744Sbill } 14844Sbill 14944Sbill vpstart() 15044Sbill { 15144Sbill register short bit; 15244Sbill 15344Sbill if (vp11.vp_count) { 15444Sbill VPADDR->pbaddr = vp11.vp_bufp; 15544Sbill if (vp11.vp_state & (PRINT|PPLOT)) 15644Sbill VPADDR->prbcr = vp11.vp_count; 15744Sbill else 15844Sbill VPADDR->plbcr = vp11.vp_count; 15944Sbill return; 16044Sbill } 16144Sbill for (bit = 1; bit != 0; bit <<= 1) 16244Sbill if (vp11.vp_state&bit&CMNDS) { 16344Sbill VPADDR->plcsr |= bit; 16444Sbill vp11.vp_state &= ~bit; 16544Sbill return; 16644Sbill } 16744Sbill } 16844Sbill 16944Sbill /*ARGSUSED*/ 17044Sbill vpioctl(dev, cmd, addr, flag) 17144Sbill register caddr_t addr; 17244Sbill { 17344Sbill register int m; 17444Sbill 17544Sbill switch (cmd) { 17644Sbill 17744Sbill case ('v'<<8)+0: 178134Sbill (void) suword(addr, vp11.vp_state); 17944Sbill return; 18044Sbill 18144Sbill case ('v'<<8)+1: 18244Sbill m = fuword(addr); 18344Sbill if (m == -1) { 18444Sbill u.u_error = EFAULT; 18544Sbill return; 18644Sbill } 18744Sbill vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); 18844Sbill break; 18944Sbill 19044Sbill default: 19144Sbill u.u_error = ENOTTY; 19244Sbill return; 19344Sbill } 194134Sbill (void) spl4(); 195134Sbill (void) vperror(READY); 19644Sbill if (vp11.vp_state&PPLOT) 19744Sbill VPADDR->plcsr |= SPP; 19844Sbill else 19944Sbill VPADDR->plcsr &= ~SPP; 20044Sbill vp11.vp_count = 0; 20144Sbill while (CMNDS & vp11.vp_state) { 202134Sbill (void) vperror(READY); 20344Sbill vpstart(); 20444Sbill } 205134Sbill (void) spl0(); 20644Sbill } 20744Sbill 20844Sbill vptimo() 20944Sbill { 21044Sbill 21144Sbill if (vp11.vp_state&VISOPEN) 21244Sbill timeout(vptimo, (caddr_t)0, HZ/10); 21344Sbill vpintr(0); 21444Sbill } 21544Sbill 21644Sbill /*ARGSUSED*/ 21744Sbill vpintr(dev) 21844Sbill { 21944Sbill 22044Sbill wakeup((caddr_t)&vp11); 22144Sbill } 22244Sbill 22344Sbill vpclose() 22444Sbill { 22544Sbill 22644Sbill vp11.vp_state = 0; 22744Sbill vp11.vp_count = 0; 22844Sbill vp11.vp_bufp = 0; 22944Sbill VPADDR->plcsr = 0; 23044Sbill } 231*288Sbill 232*288Sbill vpreset() 233*288Sbill { 234*288Sbill 235*288Sbill if ((vp11.vp_state & VISOPEN) == 0) 236*288Sbill return; 237*288Sbill printf(" vp"); 238*288Sbill VPADDR->prcsr = IENABLE | DTCINTR; 239*288Sbill if ((vp11.vp_state & VBUSY) == 0) 240*288Sbill return; 241*288Sbill if (vp_ubinfo) { 242*288Sbill printf("<%d>", (vp_ubinfo>>28)&0xf); 243*288Sbill ubafree(vp_ubinfo), vp_ubinfo = 0; 244*288Sbill } 245*288Sbill vp11.vp_bufp = vp_ubinfo & 0x3ffff; 246*288Sbill vp11.vp_count = vp11.vp_bp->b_bcount; 247*288Sbill vpstart(); 248*288Sbill } 249