|
|
1.1 ! root 1: /* lp.c 6.1 83/07/29 */ ! 2: ! 3: #include "lp.h" ! 4: #if NLP > 0 ! 5: /* ! 6: * LP-11 Line printer driver ! 7: * ! 8: * This driver has been modified to work on printers where ! 9: * leaving IENABLE set would cause continuous interrupts. ! 10: */ ! 11: #include "../machine/pte.h" ! 12: ! 13: #include "../h/param.h" ! 14: #include "../h/dir.h" ! 15: #include "../h/user.h" ! 16: #include "../h/buf.h" ! 17: #include "../h/systm.h" ! 18: #include "../h/map.h" ! 19: #include "../h/uio.h" ! 20: #include "../h/tty.h" ! 21: #include "../h/kernel.h" ! 22: ! 23: #include "../vaxuba/ubavar.h" ! 24: ! 25: #define LPPRI (PZERO+8) ! 26: #define IENABLE 0100 ! 27: #define DONE 0200 ! 28: #define ERROR 0100000 ! 29: #define LPLWAT 650 ! 30: #define LPHWAT 800 ! 31: ! 32: #define MAXCOL 132 ! 33: #define CAP 1 ! 34: ! 35: #define LPUNIT(dev) (minor(dev) >> 3) ! 36: ! 37: struct lpdevice { ! 38: short lpsr; ! 39: short lpbuf; ! 40: }; ! 41: ! 42: struct lp_softc { ! 43: struct clist sc_outq; ! 44: int sc_state; ! 45: int sc_physcol; ! 46: int sc_logcol; ! 47: int sc_physline; ! 48: char sc_flags; ! 49: short sc_maxcol; ! 50: int sc_lpchar; ! 51: struct buf *sc_inbuf; ! 52: } lp_softc[NLP]; ! 53: ! 54: struct uba_device *lpinfo[NLP]; ! 55: ! 56: int lpprobe(), lpattach(), lptout(); ! 57: u_short lpstd[] = { 0177514 }; ! 58: struct uba_driver lpdriver = ! 59: { lpprobe, 0, lpattach, 0, lpstd, "lp", lpinfo }; ! 60: ! 61: /* bits for state */ ! 62: #define OPEN 1 /* device is open */ ! 63: #define TOUT 2 /* timeout is active */ ! 64: #define MOD 4 /* device state has been modified */ ! 65: #define ASLP 8 /* awaiting draining of printer */ ! 66: ! 67: int lptout(); ! 68: ! 69: lpattach(ui) ! 70: struct uba_device *ui; ! 71: { ! 72: register struct lp_softc *sc; ! 73: ! 74: sc = &lp_softc[ui->ui_unit]; ! 75: sc->sc_lpchar = -1; ! 76: if (ui->ui_flags) ! 77: sc->sc_maxcol = ui->ui_flags; ! 78: else ! 79: sc->sc_maxcol = MAXCOL; ! 80: } ! 81: ! 82: lpprobe(reg) ! 83: caddr_t reg; ! 84: { ! 85: register int br, cvec; /* value-result */ ! 86: register struct lpdevice *lpaddr = (struct lpdevice *)reg; ! 87: #ifdef lint ! 88: br = 0; cvec = br; br = cvec; ! 89: lpintr(0); ! 90: #endif ! 91: ! 92: lpaddr->lpsr = IENABLE; ! 93: DELAY(5); ! 94: lpaddr->lpsr = 0; ! 95: return (sizeof (struct lpdevice)); ! 96: } ! 97: ! 98: /*ARGSUSED*/ ! 99: lpopen(dev, flag) ! 100: dev_t dev; ! 101: int flag; ! 102: { ! 103: register int unit; ! 104: register struct lpdevice *lpaddr; ! 105: register struct lp_softc *sc; ! 106: register struct uba_device *ui; ! 107: ! 108: if ((unit = LPUNIT(dev)) >= NLP || ! 109: (sc = &lp_softc[unit])->sc_state&OPEN || ! 110: (ui = lpinfo[unit]) == 0 || ui->ui_alive == 0) ! 111: return (ENXIO); ! 112: lpaddr = (struct lpdevice *)ui->ui_addr; ! 113: if (lpaddr->lpsr&ERROR) ! 114: return (EIO); ! 115: sc->sc_state |= OPEN; ! 116: sc->sc_inbuf = geteblk(512); ! 117: sc->sc_flags = minor(dev) & 07; ! 118: (void) spl4(); ! 119: if ((sc->sc_state&TOUT) == 0) { ! 120: sc->sc_state |= TOUT; ! 121: timeout(lptout, (caddr_t)dev, 10*hz); ! 122: } ! 123: (void) spl0(); ! 124: lpcanon(dev, '\f'); ! 125: return (0); ! 126: } ! 127: ! 128: /*ARGSUSED*/ ! 129: lpclose(dev, flag) ! 130: dev_t dev; ! 131: int flag; ! 132: { ! 133: register struct lp_softc *sc = &lp_softc[LPUNIT(dev)]; ! 134: ! 135: lpcanon(dev, '\f'); ! 136: brelse(sc->sc_inbuf); ! 137: sc->sc_state &= ~OPEN; ! 138: } ! 139: ! 140: lpwrite(dev, uio) ! 141: dev_t dev; ! 142: struct uio *uio; ! 143: { ! 144: register unsigned n; ! 145: register char *cp; ! 146: register struct lp_softc *sc = &lp_softc[LPUNIT(dev)]; ! 147: int error; ! 148: ! 149: while (n = min(512, (unsigned)uio->uio_resid)) { ! 150: cp = sc->sc_inbuf->b_un.b_addr; ! 151: error = uiomove(cp, (int)n, UIO_WRITE, uio); ! 152: if (error) ! 153: return (error); ! 154: do ! 155: lpcanon(dev, *cp++); ! 156: while (--n); ! 157: } ! 158: return (0); ! 159: } ! 160: ! 161: lpcanon(dev, c) ! 162: dev_t dev; ! 163: register int c; ! 164: { ! 165: register int logcol, physcol; ! 166: register struct lp_softc *sc = &lp_softc[LPUNIT(dev)]; ! 167: ! 168: if (sc->sc_flags&CAP) { ! 169: register c2; ! 170: ! 171: if (c>='a' && c<='z') ! 172: c += 'A'-'a'; else ! 173: switch (c) { ! 174: ! 175: case '{': ! 176: c2 = '('; ! 177: goto esc; ! 178: ! 179: case '}': ! 180: c2 = ')'; ! 181: goto esc; ! 182: ! 183: case '`': ! 184: c2 = '\''; ! 185: goto esc; ! 186: ! 187: case '|': ! 188: c2 = '!'; ! 189: goto esc; ! 190: ! 191: case '~': ! 192: c2 = '^'; ! 193: ! 194: esc: ! 195: lpcanon(dev, c2); ! 196: sc->sc_logcol--; ! 197: c = '-'; ! 198: } ! 199: } ! 200: logcol = sc->sc_logcol; ! 201: physcol = sc->sc_physcol; ! 202: if (c == ' ') ! 203: logcol++; ! 204: else switch(c) { ! 205: ! 206: case '\t': ! 207: logcol = (logcol+8) & ~7; ! 208: break; ! 209: ! 210: case '\f': ! 211: if (sc->sc_physline == 0 && physcol == 0) ! 212: break; ! 213: /* fall into ... */ ! 214: ! 215: case '\n': ! 216: lpoutput(dev, c); ! 217: if (c == '\f') ! 218: sc->sc_physline = 0; ! 219: else ! 220: sc->sc_physline++; ! 221: physcol = 0; ! 222: /* fall into ... */ ! 223: ! 224: case '\r': ! 225: logcol = 0; ! 226: (void) spl4(); ! 227: lpintr(LPUNIT(dev)); ! 228: (void) spl0(); ! 229: break; ! 230: ! 231: case '\b': ! 232: if (logcol > 0) ! 233: logcol--; ! 234: break; ! 235: ! 236: default: ! 237: if (logcol < physcol) { ! 238: lpoutput(dev, '\r'); ! 239: physcol = 0; ! 240: } ! 241: if (logcol < sc->sc_maxcol) { ! 242: while (logcol > physcol) { ! 243: lpoutput(dev, ' '); ! 244: physcol++; ! 245: } ! 246: lpoutput(dev, c); ! 247: physcol++; ! 248: } ! 249: logcol++; ! 250: } ! 251: if (logcol > 1000) /* ignore long lines */ ! 252: logcol = 1000; ! 253: sc->sc_logcol = logcol; ! 254: sc->sc_physcol = physcol; ! 255: } ! 256: ! 257: lpoutput(dev, c) ! 258: dev_t dev; ! 259: int c; ! 260: { ! 261: register struct lp_softc *sc = &lp_softc[LPUNIT(dev)]; ! 262: ! 263: if (sc->sc_outq.c_cc >= LPHWAT) { ! 264: (void) spl4(); ! 265: lpintr(LPUNIT(dev)); /* unchoke */ ! 266: while (sc->sc_outq.c_cc >= LPHWAT) { ! 267: sc->sc_state |= ASLP; /* must be ERROR */ ! 268: sleep((caddr_t)sc, LPPRI); ! 269: } ! 270: (void) spl0(); ! 271: } ! 272: while (putc(c, &sc->sc_outq)) ! 273: sleep((caddr_t)&lbolt, LPPRI); ! 274: } ! 275: ! 276: lpintr(lp11) ! 277: int lp11; ! 278: { ! 279: register int n; ! 280: register struct lp_softc *sc = &lp_softc[lp11]; ! 281: register struct uba_device *ui = lpinfo[lp11]; ! 282: register struct lpdevice *lpaddr = (struct lpdevice *)ui->ui_addr; ! 283: ! 284: lpaddr->lpsr &= ~IENABLE; ! 285: n = sc->sc_outq.c_cc; ! 286: if (sc->sc_lpchar < 0) ! 287: sc->sc_lpchar = getc(&sc->sc_outq); ! 288: while ((lpaddr->lpsr&DONE) && sc->sc_lpchar >= 0) { ! 289: lpaddr->lpbuf = sc->sc_lpchar; ! 290: sc->sc_lpchar = getc(&sc->sc_outq); ! 291: } ! 292: sc->sc_state |= MOD; ! 293: if (sc->sc_outq.c_cc > 0 && (lpaddr->lpsr&ERROR)==0) ! 294: lpaddr->lpsr |= IENABLE; /* ok and more to do later */ ! 295: if (n>LPLWAT && sc->sc_outq.c_cc<=LPLWAT && sc->sc_state&ASLP) { ! 296: sc->sc_state &= ~ASLP; ! 297: wakeup((caddr_t)sc); /* top half should go on */ ! 298: } ! 299: } ! 300: ! 301: lptout(dev) ! 302: dev_t dev; ! 303: { ! 304: register struct lp_softc *sc; ! 305: register struct uba_device *ui; ! 306: register struct lpdevice *lpaddr; ! 307: ! 308: sc = &lp_softc[LPUNIT(dev)]; ! 309: ui = lpinfo[LPUNIT(dev)]; ! 310: lpaddr = (struct lpdevice *) ui->ui_addr; ! 311: if ((sc->sc_state&MOD) != 0) { ! 312: sc->sc_state &= ~MOD; /* something happened */ ! 313: timeout(lptout, (caddr_t)dev, 2*hz); /* so don't sweat */ ! 314: return; ! 315: } ! 316: if ((sc->sc_state&OPEN) == 0) { ! 317: sc->sc_state &= ~TOUT; /* no longer open */ ! 318: lpaddr->lpsr = 0; ! 319: return; ! 320: } ! 321: if (sc->sc_outq.c_cc && (lpaddr->lpsr&DONE) && (lpaddr->lpsr&ERROR)==0) ! 322: lpintr(LPUNIT(dev)); /* ready to go */ ! 323: timeout(lptout, (caddr_t)dev, 10*hz); ! 324: } ! 325: ! 326: lpreset(uban) ! 327: int uban; ! 328: { ! 329: register struct uba_device *ui; ! 330: register struct lpdevice *lpaddr; ! 331: register int unit; ! 332: ! 333: for (unit = 0; unit < NLP; unit++) { ! 334: if ((ui = lpinfo[unit]) == 0 || ui->ui_ubanum != uban || ! 335: ui->ui_alive == 0) ! 336: continue; ! 337: printf(" lp%d", unit); ! 338: lpaddr = (struct lpdevice *)ui->ui_addr; ! 339: lpaddr->lpsr |= IENABLE; ! 340: } ! 341: } ! 342: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.