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