1 /* vp.c 3.4 06/22/80 */ 2 3 #include "../h/param.h" 4 #include "../h/dir.h" 5 #include "../h/user.h" 6 #include "../h/buf.h" 7 #include "../h/systm.h" 8 #include "../h/map.h" 9 #include "../h/pte.h" 10 #include "../h/uba.h" 11 12 /* 13 * Versatec matrix printer/plotter 14 * dma interface driver 15 */ 16 int vpbdp = 1; 17 18 unsigned minvpph(); 19 20 #define VPPRI (PZERO-1) 21 22 struct vpregs { 23 short plbcr; 24 short fill; 25 short prbcr; 26 unsigned short pbaddr; 27 short plcsr; 28 short plbuf; 29 short prcsr; 30 unsigned short prbuf; 31 }; 32 33 #define VPADDR ((struct vpregs *)(UBA0_DEV + 0177500)) 34 35 #define ERROR 0100000 36 #define DTCINTR 040000 37 #define DMAACT 020000 38 #define READY 0200 39 #define IENABLE 0100 40 #define TERMCOM 040 41 #define FFCOM 020 42 #define EOTCOM 010 43 #define CLRCOM 04 44 #define RESET 02 45 #define SPP 01 46 47 struct { 48 int vp_state; 49 int vp_count; 50 int vp_bufp; 51 struct buf *vp_bp; 52 } vp11; 53 int vp_ubinfo; 54 55 struct buf rvpbuf; 56 57 #define VISOPEN 01 58 #define CMNDS 076 59 #define MODE 0700 60 #define PRINT 0100 61 #define PLOT 0200 62 #define PPLOT 0400 63 #define VBUSY 01000 64 65 vpopen() 66 { 67 68 if (vp11.vp_state & VISOPEN) { 69 u.u_error = ENXIO; 70 return; 71 } 72 vp11.vp_state = VISOPEN | PRINT | CLRCOM | RESET; 73 vp11.vp_count = 0; 74 VPADDR->prcsr = IENABLE | DTCINTR; 75 vptimo(); 76 while (vp11.vp_state & CMNDS) { 77 (void) spl4(); 78 if (vperror(READY)) { 79 vpclose(); 80 u.u_error = EIO; 81 return; 82 } 83 vpstart(); 84 (void) spl0(); 85 } 86 } 87 88 vpstrategy(bp) 89 register struct buf *bp; 90 { 91 register int e; 92 93 (void) spl4(); 94 while (vp11.vp_state & VBUSY) 95 sleep((caddr_t)&vp11, VPPRI); 96 vp11.vp_state |= VBUSY; 97 vp11.vp_bp = bp; 98 vp_ubinfo = ubasetup(bp, vpbdp); 99 vp11.vp_bufp = vp_ubinfo & 0x3ffff; 100 if (e = vperror(READY)) 101 goto brkout; 102 vp11.vp_count = bp->b_bcount; 103 vpstart(); 104 while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT) 105 sleep((caddr_t)&vp11, VPPRI); 106 vp11.vp_count = 0; 107 vp11.vp_bufp = 0; 108 if ((vp11.vp_state&MODE) == PPLOT) 109 vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT; 110 (void) spl0(); 111 brkout: 112 ubafree(vp_ubinfo), vp_ubinfo = 0; 113 vp11.vp_state &= ~VBUSY; 114 vp11.vp_bp = 0; 115 iodone(bp); 116 if (e) 117 u.u_error = EIO; 118 wakeup((caddr_t)&vp11); 119 } 120 121 int vpblock = 16384; 122 123 unsigned 124 minvpph(bp) 125 struct buf *bp; 126 { 127 128 if (bp->b_bcount > vpblock) 129 bp->b_bcount = vpblock; 130 } 131 132 /*ARGSUSED*/ 133 vpwrite(dev) 134 { 135 136 physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph); 137 } 138 139 vperror(bit) 140 { 141 register int state, e; 142 143 state = vp11.vp_state & PLOT; 144 while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0) 145 sleep((caddr_t)&vp11, VPPRI); 146 return (e & ERROR); 147 } 148 149 vpstart() 150 { 151 register short bit; 152 153 if (vp11.vp_count) { 154 VPADDR->pbaddr = vp11.vp_bufp; 155 if (vp11.vp_state & (PRINT|PPLOT)) 156 VPADDR->prbcr = vp11.vp_count; 157 else 158 VPADDR->plbcr = vp11.vp_count; 159 return; 160 } 161 for (bit = 1; bit != 0; bit <<= 1) 162 if (vp11.vp_state&bit&CMNDS) { 163 VPADDR->plcsr |= bit; 164 vp11.vp_state &= ~bit; 165 return; 166 } 167 } 168 169 /*ARGSUSED*/ 170 vpioctl(dev, cmd, addr, flag) 171 register caddr_t addr; 172 { 173 register int m; 174 175 switch (cmd) { 176 177 case ('v'<<8)+0: 178 (void) suword(addr, vp11.vp_state); 179 return; 180 181 case ('v'<<8)+1: 182 m = fuword(addr); 183 if (m == -1) { 184 u.u_error = EFAULT; 185 return; 186 } 187 vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); 188 break; 189 190 default: 191 u.u_error = ENOTTY; 192 return; 193 } 194 (void) spl4(); 195 (void) vperror(READY); 196 if (vp11.vp_state&PPLOT) 197 VPADDR->plcsr |= SPP; 198 else 199 VPADDR->plcsr &= ~SPP; 200 vp11.vp_count = 0; 201 while (CMNDS & vp11.vp_state) { 202 (void) vperror(READY); 203 vpstart(); 204 } 205 (void) spl0(); 206 } 207 208 vptimo() 209 { 210 211 if (vp11.vp_state&VISOPEN) 212 timeout(vptimo, (caddr_t)0, HZ/10); 213 vpintr(0); 214 } 215 216 /*ARGSUSED*/ 217 vpintr(dev) 218 { 219 220 wakeup((caddr_t)&vp11); 221 } 222 223 vpclose() 224 { 225 226 vp11.vp_state = 0; 227 vp11.vp_count = 0; 228 vp11.vp_bufp = 0; 229 VPADDR->plcsr = 0; 230 } 231 232 vpreset() 233 { 234 235 if ((vp11.vp_state & VISOPEN) == 0) 236 return; 237 printf(" vp"); 238 VPADDR->prcsr = IENABLE | DTCINTR; 239 if ((vp11.vp_state & VBUSY) == 0) 240 return; 241 if (vp_ubinfo) { 242 printf("<%d>", (vp_ubinfo>>28)&0xf); 243 ubafree(vp_ubinfo), vp_ubinfo = 0; 244 } 245 vp11.vp_bufp = vp_ubinfo & 0x3ffff; 246 vp11.vp_count = vp11.vp_bp->b_bcount; 247 vpstart(); 248 } 249