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
Defined variables
Defined struct's
Defined macros
ASLP
defined in line
45; used 3 times
CAP
defined in line
27; used 1 times
LPPRI
defined in line
22; used 2 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