|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993-1990 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Parallel port printer driver v1.0
28: * All rights reserved.
29: */
30:
31: #if NLPR > 0
32:
33: #include <mach/std_types.h>
34: #include <sys/types.h>
1.1.1.2 ! root 35: #include <kern/printf.h>
! 36: #include <kern/mach_clock.h>
1.1 root 37: #include <sys/time.h>
38: #include <device/conf.h>
1.1.1.2 ! root 39: #include <device/device_types.h>
1.1 root 40: #include <device/tty.h>
41: #include <device/io_req.h>
42:
43: #include <i386/ipl.h>
44: #include <i386/pio.h>
45: #include <chips/busses.h>
1.1.1.2 ! root 46: #include <i386at/autoconf.h>
1.1 root 47: #include <i386at/lprreg.h>
48:
49:
50: /*
51: * Driver information for auto-configuration stuff.
52: */
53:
1.1.1.2 ! root 54: int lprprobe();
! 55: void lprstop();
! 56: void lprintr(), lprstart();
1.1 root 57: void lprattach(struct bus_device *);
1.1.1.2 ! root 58: int lprgetstat(), lprsetstat();
! 59: void lprpr_addr();
1.1 root 60:
61: struct bus_device *lprinfo[NLPR]; /* ??? */
62:
63: static vm_offset_t lpr_std[NLPR] = { 0 };
64: static struct bus_device *lpr_info[NLPR];
65: struct bus_driver lprdriver = {
66: lprprobe, 0, lprattach, 0, lpr_std, "lpr", lpr_info, 0, 0, 0};
67:
68: struct tty lpr_tty[NLPR];
69:
70: int lpr_alive[NLPR];
71:
1.1.1.2 ! root 72: int
1.1 root 73: lprprobe(port, dev)
74: struct bus_device *dev;
75: {
76: u_short addr = (u_short) dev->address;
77: int unit = dev->unit;
78: int ret;
79:
80: if ((unit < 0) || (unit > NLPR)) {
81: printf("com %d out of range\n", unit);
82: return(0);
83: }
84:
85: outb(INTR_ENAB(addr),0x07);
86: outb(DATA(addr),0xaa);
87: ret = inb(DATA(addr)) == 0xaa;
88: if (ret) {
89: if (lpr_alive[unit]) {
90: printf("lpr: Multiple alive entries for unit %d.\n", unit);
91: printf("lpr: Ignoring entry with address = %x .\n", addr);
92: ret = 0;
93: } else
94: lpr_alive[unit]++;
95: }
96: return(ret);
97: }
98:
99: void lprattach(struct bus_device *dev)
100: {
101: u_char unit = dev->unit;
102: u_short addr = (u_short) dev->address;
103:
104: take_dev_irq(dev);
1.1.1.2 ! root 105: printf(", port = %lx, spl = %ld, pic = %d.",
1.1 root 106: dev->address, dev->sysdep, dev->sysdep1);
107: lprinfo[unit] = dev;
108:
109: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) & 0x0f);
110:
111: return;
112: }
113:
1.1.1.2 ! root 114: int
1.1 root 115: lpropen(dev, flag, ior)
116: int dev;
117: int flag;
118: io_req_t ior;
119: {
120: int unit = minor(dev);
121: struct bus_device *isai;
122: struct tty *tp;
123: u_short addr;
124:
125: if (unit >= NLPR || (isai = lprinfo[unit]) == 0 || isai->alive == 0)
1.1.1.2 ! root 126: return (D_NO_SUCH_DEVICE);
1.1 root 127: tp = &lpr_tty[unit];
128: addr = (u_short) isai->address;
129: tp->t_dev = dev;
130: tp->t_addr = *(caddr_t *)&addr;
131: tp->t_oproc = lprstart;
132: tp->t_state |= TS_WOPEN;
133: tp->t_stop = lprstop;
134: tp->t_getstat = lprgetstat;
135: tp->t_setstat = lprsetstat;
136: if ((tp->t_state & TS_ISOPEN) == 0)
137: ttychars(tp);
138: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) | 0x10);
139: tp->t_state |= TS_CARR_ON;
140: return (char_open(dev, tp, flag, ior));
141: }
142:
1.1.1.2 ! root 143: void
1.1 root 144: lprclose(dev, flag)
145: int dev;
146: int flag;
147: {
148: int unit = minor(dev);
149: struct tty *tp = &lpr_tty[unit];
150: u_short addr = (u_short) lprinfo[unit]->address;
151:
152: ttyclose(tp);
153: if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) {
154: outb(INTR_ENAB(addr), inb(INTR_ENAB(addr)) & 0x0f);
155: tp->t_state &= ~TS_BUSY;
156: }
157: }
158:
1.1.1.2 ! root 159: int
1.1 root 160: lprread(dev, ior)
161: int dev;
162: io_req_t ior;
163: {
164: return char_read(&lpr_tty[minor(dev)], ior);
165: }
166:
1.1.1.2 ! root 167: int
1.1 root 168: lprwrite(dev, ior)
169: int dev;
170: io_req_t ior;
171: {
172: return char_write(&lpr_tty[minor(dev)], ior);
173: }
174:
1.1.1.2 ! root 175: int
1.1 root 176: lprportdeath(dev, port)
177: dev_t dev;
178: mach_port_t port;
179: {
1.1.1.2 ! root 180: return (tty_portdeath(&lpr_tty[minor(dev)], (ipc_port_t)port));
1.1 root 181: }
182:
183: io_return_t
184: lprgetstat(dev, flavor, data, count)
185: dev_t dev;
186: int flavor;
187: int *data; /* pointer to OUT array */
1.1.1.2 ! root 188: natural_t *count; /* out */
1.1 root 189: {
190: io_return_t result = D_SUCCESS;
191: int unit = minor(dev);
192:
193: switch (flavor) {
194: default:
195: result = tty_get_status(&lpr_tty[unit], flavor, data, count);
196: break;
197: }
198: return (result);
199: }
200:
201: io_return_t
202: lprsetstat(dev, flavor, data, count)
203: dev_t dev;
204: int flavor;
205: int * data;
1.1.1.2 ! root 206: natural_t count;
1.1 root 207: {
208: io_return_t result = D_SUCCESS;
209: int unit = minor(dev);
210:
211: switch (flavor) {
212: default:
213: result = tty_set_status(&lpr_tty[unit], flavor, data, count);
214: /* if (result == D_SUCCESS && flavor == TTY_STATUS)
215: lprparam(unit);
216: */ return (result);
217: }
218: return (D_SUCCESS);
219: }
220:
1.1.1.2 ! root 221: void lprintr(unit)
1.1 root 222: int unit;
223: {
224: register struct tty *tp = &lpr_tty[unit];
225:
226: if ((tp->t_state & TS_ISOPEN) == 0)
227: return;
228:
229: tp->t_state &= ~TS_BUSY;
230: if (tp->t_state&TS_FLUSH)
231: tp->t_state &=~TS_FLUSH;
232: tt_write_wakeup(tp);
233: lprstart(tp);
234: }
235:
1.1.1.2 ! root 236: void lprstart(tp)
1.1 root 237: struct tty *tp;
238: {
239: spl_t s = spltty();
240: u_short addr = (natural_t) tp->t_addr;
241: int status = inb(STATUS(addr));
242: char nch;
243:
244: if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) {
245: splx(s);
1.1.1.2 ! root 246: return;
1.1 root 247: }
248:
249: if (status & 0x20) {
250: printf("Printer out of paper!\n");
251: splx(s);
1.1.1.2 ! root 252: return;
1.1 root 253: }
254:
255: if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
256: tt_write_wakeup(tp);
257: }
258: if (tp->t_outq.c_cc == 0) {
259: splx(s);
1.1.1.2 ! root 260: return;
1.1 root 261: }
262: nch = getc(&tp->t_outq);
263: if ((tp->t_flags & LITOUT) == 0 && (nch & 0200)) {
1.1.1.2 ! root 264: timeout((timer_func_t *)ttrstrt, (char *)tp, (nch & 0x7f) + 6);
1.1 root 265: tp->t_state |= TS_TIMEOUT;
266: return;
267: }
268: outb(DATA(addr), nch);
269: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) | 0x01);
270: outb(INTR_ENAB(addr),inb(INTR_ENAB(addr)) & 0x1e);
271: tp->t_state |= TS_BUSY;
272: splx(s);
1.1.1.2 ! root 273: return;
1.1 root 274: }
275:
1.1.1.2 ! root 276: void
1.1 root 277: lprstop(tp, flags)
278: register struct tty *tp;
279: int flags;
280: {
281: if ((tp->t_state & TS_BUSY) && (tp->t_state & TS_TTSTOP) == 0)
282: tp->t_state |= TS_FLUSH;
283: }
1.1.1.2 ! root 284: int
1.1 root 285: lprpr(unit)
286: {
287: lprpr_addr(lprinfo[unit]->address);
288: return 0;
289: }
290:
1.1.1.2 ! root 291: void
1.1 root 292: lprpr_addr(addr)
293: {
294: printf("DATA(%x) %x, STATUS(%x) %x, INTR_ENAB(%x) %x\n",
295: DATA(addr), inb(DATA(addr)),
296: STATUS(addr), inb(STATUS(addr)),
297: INTR_ENAB(addr), inb(INTR_ENAB(addr)));
298: }
1.1.1.2 ! root 299: #endif /* NLPR */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.