1: /*
   2:  *	SCCS id	@(#)lp.c	2.1 (Berkeley)	10/6/83
   3:  */
   4: 
   5: #include "lp.h"
   6: #if NLP > 0
   7: #include "param.h"
   8: #include <sys/systm.h>
   9: #include <sys/dir.h>
  10: #include <sys/user.h>
  11: #include <sys/tty.h>
  12: #include <sys/lpreg.h>
  13: 
  14: /*
  15:  * LP-11 Line printer driver
  16:  *
  17:  * This driver has been modified to work on printers where
  18:  * leaving LP_IE set would cause continuous interrupts.
  19:  */
  20: 
  21: 
  22: #define LPPRI   (PZERO + 8)
  23: #define LPLWAT  40
  24: #define LPHWAT  400
  25: 
  26: #define MAXCOL  132
  27: #define CAP 1
  28: 
  29: #define LPUNIT(dev) (minor(dev) >> 3)
  30: 
  31: struct lp_softc {
  32:     struct  clist sc_outq;
  33:     int sc_state;
  34:     int sc_physcol;
  35:     int sc_logcol;
  36:     int sc_physline;
  37:     char    sc_flags;
  38:     int sc_lpchar;
  39: } lp_softc[NLP];
  40: 
  41: /* bits for state */
  42: #define OPEN        1   /* device is open */
  43: #define TOUT        2   /* timeout is active */
  44: #define MOD     4   /* device state has been modified */
  45: #define ASLP        8   /* awaiting draining of printer */
  46: 
  47: extern  lbolt;
  48: struct  lpdevice *lp_addr[NLP];
  49: int lptout();
  50: 
  51: lpattach(addr, unit)
  52: struct lpdevice *addr;
  53: {
  54:     if ((unsigned) unit >= NLP)
  55:         return(0);
  56:     lp_addr[unit] = addr;
  57:     return(1);
  58: }
  59: 
  60: /*ARGSUSED*/
  61: lpopen(dev, flag)
  62: dev_t   dev;
  63: int flag;
  64: {
  65:     register int    unit;
  66:     register struct lp_softc *sc;
  67: 
  68:     if (((unit = LPUNIT(dev)) >= NLP) || (lp_addr[unit] == 0)) {
  69:         u.u_error = ENXIO;
  70:         return;
  71:     }
  72:     else
  73:         if ((sc = &lp_softc[unit])->sc_state & OPEN) {
  74:             u.u_error = EBUSY;
  75:             return;
  76:         }
  77:     if (lp_addr[unit]->lpcs & LP_ERR) {
  78:         u.u_error = EIO;
  79:         return;
  80:     }
  81:     sc->sc_state |= OPEN;
  82:     sc->sc_flags = minor(dev) & 07;
  83:     (void) _spl4();
  84:     if ((sc->sc_state & TOUT) == 0) {
  85:         sc->sc_state |= TOUT;
  86:         timeout(lptout, (caddr_t)dev, 10 * hz);
  87:     }
  88:     (void) _spl0();
  89:     lpcanon(dev, '\f');
  90: }
  91: 
  92: /*ARGSUSED*/
  93: lpclose(dev, flag)
  94: dev_t   dev;
  95: int flag;
  96: {
  97:     register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
  98: 
  99:     lpcanon(dev, '\f');
 100:     sc->sc_state &= ~OPEN;
 101: }
 102: 
 103: lpwrite(dev)
 104: dev_t   dev;
 105: {
 106:     register char c;
 107: 
 108:     while (u.u_count) {
 109:         c = fubyte(u.u_base++);
 110:         if (c < 0) {
 111:             u.u_error = EFAULT;
 112:             break;
 113:         }
 114:         u.u_count--;
 115:         lpcanon(dev, c);
 116:     }
 117: }
 118: 
 119: lpcanon(dev, c)
 120: dev_t   dev;
 121: register c;
 122: {
 123:     register logcol, physcol;
 124:     register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
 125: 
 126:     if (sc->sc_flags & CAP) {
 127:         register c2;
 128: 
 129:         if (c >= 'a' && c <= 'z')
 130:             c += 'A'-'a'; else
 131:         switch (c) {
 132: 
 133:             case '{':
 134:                 c2 = '(';
 135:                 goto esc;
 136: 
 137:             case '}':
 138:                 c2 = ')';
 139:                 goto esc;
 140: 
 141:             case '`':
 142:                 c2 = '\'';
 143:                 goto esc;
 144: 
 145:             case '|':
 146:                 c2 = '!';
 147:                 goto esc;
 148: 
 149:             case '~':
 150:                 c2 = '^';
 151: 
 152:             esc:
 153:                 lpcanon(dev, c2);
 154:                 sc->sc_logcol--;
 155:                 c = '-';
 156:         }
 157:     }
 158:     logcol = sc->sc_logcol;
 159:     physcol = sc->sc_physcol;
 160:     if (c == ' ')
 161:         logcol++;
 162:     else switch(c) {
 163: 
 164:         case '\t':
 165:             logcol = (logcol + 8) & ~7;
 166:             break;
 167: 
 168:         case '\f':
 169:             if (sc->sc_physline == 0 && physcol == 0)
 170:                 break;
 171:             /* fall into ... */
 172: 
 173:         case '\n':
 174:             lpoutput(dev, c);
 175:             if (c == '\f')
 176:                 sc->sc_physline = 0;
 177:             else
 178:                 sc->sc_physline++;
 179:             physcol = 0;
 180:             /* fall into ... */
 181: 
 182:         case '\r':
 183:             logcol = 0;
 184:             (void) _spl4();
 185:             lpintr(LPUNIT(dev));
 186:             (void) _spl0();
 187:             break;
 188: 
 189:         case '\b':
 190:             if (logcol > 0)
 191:                 logcol--;
 192:             break;
 193: 
 194:         default:
 195:             if (logcol < physcol) {
 196:                 lpoutput(dev, '\r');
 197:                 physcol = 0;
 198:             }
 199:             if (logcol < MAXCOL) {
 200:                 while (logcol > physcol) {
 201:                     lpoutput(dev, ' ');
 202:                     physcol++;
 203:                 }
 204:                 lpoutput(dev, c);
 205:                 physcol++;
 206:             }
 207:             logcol++;
 208:     }
 209:     if (logcol > 1000)  /* ignore long lines  */
 210:         logcol = 1000;
 211:     sc->sc_logcol = logcol;
 212:     sc->sc_physcol = physcol;
 213: }
 214: 
 215: lpoutput(dev, c)
 216: dev_t   dev;
 217: int c;
 218: {
 219:     register struct lp_softc *sc = &lp_softc[LPUNIT(dev)];
 220: 
 221:     if (sc->sc_outq.c_cc >= LPHWAT) {
 222:         (void) _spl4();
 223:         lpintr(LPUNIT(dev));                /* unchoke */
 224:         while (sc->sc_outq.c_cc >= LPHWAT) {
 225:             sc->sc_state |= ASLP;       /* must be LP_ERR */
 226:             sleep((caddr_t)sc, LPPRI);
 227:         }
 228:         (void) _spl0();
 229:     }
 230:     while (putc(c, &sc->sc_outq))
 231:         sleep((caddr_t)&lbolt, LPPRI);
 232: }
 233: 
 234: lpintr(lp11)
 235: int lp11;
 236: {
 237:     register n;
 238:     register struct lp_softc *sc = &lp_softc[lp11];
 239:     register struct lpdevice *lpaddr;
 240: 
 241:     lpaddr = lp_addr[lp11];
 242:     lpaddr->lpcs &= ~LP_IE;
 243:     n = sc->sc_outq.c_cc;
 244:     if (sc->sc_lpchar < 0)
 245:         sc->sc_lpchar = getc(&sc->sc_outq);
 246:     while ((lpaddr->lpcs & LP_RDY) && sc->sc_lpchar >= 0) {
 247:         lpaddr->lpdb = sc->sc_lpchar;
 248:         sc->sc_lpchar = getc(&sc->sc_outq);
 249:     }
 250:     sc->sc_state |= MOD;
 251:     if (sc->sc_outq.c_cc > 0 && (lpaddr->lpcs & LP_ERR) == 0)
 252:         lpaddr->lpcs |= LP_IE;  /* ok and more to do later */
 253:     if (n > LPLWAT && sc->sc_outq.c_cc <= LPLWAT && sc->sc_state & ASLP) {
 254:         sc->sc_state &= ~ASLP;
 255:         wakeup((caddr_t)sc);        /* top half should go on */
 256:     }
 257: }
 258: 
 259: lptout(dev)
 260: dev_t   dev;
 261: {
 262:     register struct lp_softc *sc;
 263:     register struct lpdevice *lpaddr;
 264: 
 265:     lpaddr = lp_addr[LPUNIT(dev)];
 266:     sc = &lp_softc[LPUNIT(dev)];
 267:     if ((sc->sc_state & MOD) != 0) {
 268:         sc->sc_state &= ~MOD;       /* something happened */
 269:         timeout(lptout, (caddr_t)dev, 2 * hz);  /* so don't sweat */
 270:         return;
 271:     }
 272:     if ((sc->sc_state & OPEN) == 0) {
 273:         sc->sc_state &= ~TOUT;      /* no longer open */
 274:         lpaddr->lpcs = 0;
 275:         return;
 276:     }
 277:     if (sc->sc_outq.c_cc && (lpaddr->lpcs & LP_RDY)
 278:         && (lpaddr->lpcs & LP_ERR) == 0)
 279:         lpintr(LPUNIT(dev));            /* ready to go */
 280:     timeout(lptout, (caddr_t)dev, 10 * hz);
 281: }

Defined functions

lpattach defined in line 51; never used
lpcanon defined in line 119; used 4 times
lpclose defined in line 93; never used
lpintr defined in line 234; used 7 times
lpopen defined in line 61; never used
lpoutput defined in line 215; used 4 times
lptout defined in line 259; used 4 times
lpwrite defined in line 103; never used

Defined variables

lp_addr defined in line 48; used 5 times
lp_softc defined in line 39; used 6 times

Defined struct's

lp_softc defined in line 31; used 12 times

Defined macros

ASLP defined in line 45; used 3 times
CAP defined in line 27; used 1 times
LPHWAT defined in line 24; used 2 times
LPLWAT defined in line 23; used 2 times
  • in line 253(2)
LPPRI defined in line 22; used 2 times
LPUNIT defined in line 29; used 9 times
MAXCOL defined in line 26; used 1 times
MOD defined in line 44; used 3 times
OPEN defined in line 42; used 4 times
TOUT defined in line 43; used 3 times
Last modified: 1983-10-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 964
Valid CSS Valid XHTML 1.0 Strict