Deleted Added
full compact
lpt.c (55205) lpt.c (55939)
1/*
2 * Copyright (c) 1990 William F. Jolitz, TeleMuse
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 34 unchanged lines hidden (view full) ---

43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 *
48 * from: unknown origin, 386BSD 0.1
49 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
50 * From Id: nlpt.c,v 1.14 1999/02/08 13:55:43 des Exp
1/*
2 * Copyright (c) 1990 William F. Jolitz, TeleMuse
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 34 unchanged lines hidden (view full) ---

43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 *
48 * from: unknown origin, 386BSD 0.1
49 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
50 * From Id: nlpt.c,v 1.14 1999/02/08 13:55:43 des Exp
51 * $FreeBSD: head/sys/dev/ppbus/lpt.c 55205 1999-12-29 04:46:21Z peter $
51 * $FreeBSD: head/sys/dev/ppbus/lpt.c 55939 2000-01-14 00:18:06Z nsouch $
52 */
53
54/*
55 * Device Driver for AT parallel printer port
56 * Written by William Jolitz 12/18/90
57 */
58
59/*
60 * Updated for ppbus by Nicolas Souchu
61 * [Mon Jul 28 1997]
62 */
52 */
53
54/*
55 * Device Driver for AT parallel printer port
56 * Written by William Jolitz 12/18/90
57 */
58
59/*
60 * Updated for ppbus by Nicolas Souchu
61 * [Mon Jul 28 1997]
62 */
63#include "lpt.h"
63
64
65#if NLPT > 0
64
65#ifdef _KERNEL
66
66
67#ifdef _KERNEL
68
69#include "opt_lpt.h"
70
67#include <sys/param.h>
68#include <sys/systm.h>
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/module.h>
74#include <sys/bus.h>
69#include <sys/conf.h>
70#include <sys/buf.h>
71#include <sys/kernel.h>
72#include <sys/uio.h>
73#include <sys/syslog.h>
75#include <sys/conf.h>
76#include <sys/buf.h>
77#include <sys/kernel.h>
78#include <sys/uio.h>
79#include <sys/syslog.h>
74#include <sys/malloc.h>
75
76#include <machine/clock.h>
80
81#include <machine/clock.h>
82#include <machine/bus.h>
83#include <machine/resource.h>
84#include <sys/rman.h>
85
77#include <machine/lpt.h>
78#endif
79
80#include <dev/ppbus/ppbconf.h>
81#include <dev/ppbus/ppb_1284.h>
82#include <dev/ppbus/lpt.h>
86#include <machine/lpt.h>
87#endif
88
89#include <dev/ppbus/ppbconf.h>
90#include <dev/ppbus/ppb_1284.h>
91#include <dev/ppbus/lpt.h>
92#include "ppbus_if.h"
93#include <dev/ppbus/ppbio.h>
83
94
84#include "opt_lpt.h"
85
86#ifndef LPT_DEBUG
87#define lprintf(args)
88#else
89#define lprintf(args) \
90 do { \
91 if (lptflag) \
92 printf args; \
93 } while (0)

--- 6 unchanged lines hidden (view full) ---

100#define LPPRI (PZERO+8)
101#define BUFSIZE 1024
102#define BUFSTATSIZE 32
103
104#define LPTUNIT(s) ((s)&0x03)
105#define LPTFLAGS(s) ((s)&0xfc)
106
107struct lpt_data {
95#ifndef LPT_DEBUG
96#define lprintf(args)
97#else
98#define lprintf(args) \
99 do { \
100 if (lptflag) \
101 printf args; \
102 } while (0)

--- 6 unchanged lines hidden (view full) ---

109#define LPPRI (PZERO+8)
110#define BUFSIZE 1024
111#define BUFSTATSIZE 32
112
113#define LPTUNIT(s) ((s)&0x03)
114#define LPTFLAGS(s) ((s)&0xfc)
115
116struct lpt_data {
108 unsigned short lpt_unit;
109
117
110 struct ppb_device lpt_dev;
111
112 short sc_state;
113 /* default case: negative prime, negative ack, handshake strobe,
114 prime once */
115 u_char sc_control;
116 char sc_flags;
117#define LP_POS_INIT 0x04 /* if we are a postive init signal */
118#define LP_POS_ACK 0x08 /* if we are a positive going ack */
119#define LP_NO_PRIME 0x10 /* don't prime the printer at all */

--- 7 unchanged lines hidden (view full) ---

127 char *sc_cp ;
128 u_short sc_irq ; /* IRQ status of port */
129#define LP_HAS_IRQ 0x01 /* we have an irq available */
130#define LP_USE_IRQ 0x02 /* we are using our irq */
131#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */
132#define LP_ENABLE_EXT 0x10 /* we shall use advanced mode when possible */
133 u_char sc_backoff ; /* time to call lptout() again */
134
118 short sc_state;
119 /* default case: negative prime, negative ack, handshake strobe,
120 prime once */
121 u_char sc_control;
122 char sc_flags;
123#define LP_POS_INIT 0x04 /* if we are a postive init signal */
124#define LP_POS_ACK 0x08 /* if we are a positive going ack */
125#define LP_NO_PRIME 0x10 /* don't prime the printer at all */

--- 7 unchanged lines hidden (view full) ---

133 char *sc_cp ;
134 u_short sc_irq ; /* IRQ status of port */
135#define LP_HAS_IRQ 0x01 /* we have an irq available */
136#define LP_USE_IRQ 0x02 /* we are using our irq */
137#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */
138#define LP_ENABLE_EXT 0x10 /* we shall use advanced mode when possible */
139 u_char sc_backoff ; /* time to call lptout() again */
140
141 struct resource *intr_resource; /* interrupt resource */
142 void *intr_cookie; /* interrupt registration cookie */
143
135};
136
144};
145
137static int nlpt = 0;
138#define MAXLPT 8 /* XXX not much better! */
139static struct lpt_data *lptdata[MAXLPT];
140
141#define LPT_NAME "lpt" /* our official name */
142
143static timeout_t lptout;
146#define LPT_NAME "lpt" /* our official name */
147
148static timeout_t lptout;
144static int lpt_port_test(struct lpt_data *sc, u_char data, u_char mask);
145static int lpt_detect(struct lpt_data *sc);
149static int lpt_port_test(device_t dev, u_char data, u_char mask);
150static int lpt_detect(device_t dev);
146
151
147/*
148 * Make ourselves visible as a ppbus driver
149 */
152#define DEVTOSOFTC(dev) \
153 ((struct lpt_data *)device_get_softc(dev))
154#define UNITOSOFTC(unit) \
155 ((struct lpt_data *)devclass_get_softc(lpt_devclass, (unit)))
156#define UNITODEVICE(unit) \
157 (devclass_get_device(lpt_devclass, (unit)))
150
158
151static struct ppb_device *lptprobe(struct ppb_data *ppb);
152static int lptattach(struct ppb_device *dev);
153static void lptintr(int unit);
159static int lpt_probe(device_t dev);
160static int lpt_attach(device_t dev);
154
161
155static void lpt_intr(int unit); /* without spls */
162static void lptintr(device_t dev);
163static void lpt_intr(void *arg); /* without spls */
156
164
157#ifdef _KERNEL
165static devclass_t lpt_devclass;
158
166
159static struct ppb_driver lptdriver = {
160 lptprobe, lptattach, LPT_NAME
167static device_method_t lpt_methods[] = {
168 /* device interface */
169 DEVMETHOD(device_probe, lpt_probe),
170 DEVMETHOD(device_attach, lpt_attach),
171
172 { 0, 0 }
161};
173};
162DATA_SET(ppbdriver_set, lptdriver);
163
174
164#endif
175static driver_t lpt_driver = {
176 "lpt",
177 lpt_methods,
178 sizeof(struct lpt_data),
179};
165
166/* bits for state */
167#define OPEN (1<<0) /* device is open */
168#define ASLP (1<<1) /* awaiting draining of printer */
169#define EERROR (1<<2) /* error was received from printer */
170#define OBUSY (1<<3) /* printer is busy doing output */
171#define LPTOUT (1<<4) /* timeout while not selected */
172#define TOUT (1<<5) /* timeout while not selected */

--- 6 unchanged lines hidden (view full) ---

179/* status masks to interrogate printer status */
180#define RDY_MASK (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR) /* ready ? */
181#define LP_READY (LPS_SEL|LPS_NBSY|LPS_NERR)
182
183/* Printer Ready condition - from lpa.c */
184/* Only used in polling code */
185#define LPS_INVERT (LPS_NBSY | LPS_NACK | LPS_SEL | LPS_NERR)
186#define LPS_MASK (LPS_NBSY | LPS_NACK | LPS_OUT | LPS_SEL | LPS_NERR)
180
181/* bits for state */
182#define OPEN (1<<0) /* device is open */
183#define ASLP (1<<1) /* awaiting draining of printer */
184#define EERROR (1<<2) /* error was received from printer */
185#define OBUSY (1<<3) /* printer is busy doing output */
186#define LPTOUT (1<<4) /* timeout while not selected */
187#define TOUT (1<<5) /* timeout while not selected */

--- 6 unchanged lines hidden (view full) ---

194/* status masks to interrogate printer status */
195#define RDY_MASK (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR) /* ready ? */
196#define LP_READY (LPS_SEL|LPS_NBSY|LPS_NERR)
197
198/* Printer Ready condition - from lpa.c */
199/* Only used in polling code */
200#define LPS_INVERT (LPS_NBSY | LPS_NACK | LPS_SEL | LPS_NERR)
201#define LPS_MASK (LPS_NBSY | LPS_NACK | LPS_OUT | LPS_SEL | LPS_NERR)
187#define NOT_READY(lpt) ((ppb_rstr(&(lpt)->lpt_dev)^LPS_INVERT)&LPS_MASK)
202#define NOT_READY(ppbus) ((ppb_rstr(ppbus)^LPS_INVERT)&LPS_MASK)
188
189#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */
190#define MAX_SPIN 20 /* Max delay for device ready in usecs */
191
192
193static d_open_t lptopen;
194static d_close_t lptclose;
195static d_write_t lptwrite;

--- 14 unchanged lines hidden (view full) ---

210 /* maj */ CDEV_MAJOR,
211 /* dump */ nodump,
212 /* psize */ nopsize,
213 /* flags */ 0,
214 /* bmaj */ -1
215};
216
217static int
203
204#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */
205#define MAX_SPIN 20 /* Max delay for device ready in usecs */
206
207
208static d_open_t lptopen;
209static d_close_t lptclose;
210static d_write_t lptwrite;

--- 14 unchanged lines hidden (view full) ---

225 /* maj */ CDEV_MAJOR,
226 /* dump */ nodump,
227 /* psize */ nopsize,
228 /* flags */ 0,
229 /* bmaj */ -1
230};
231
232static int
218lpt_request_ppbus(struct lpt_data *sc, int how)
233lpt_request_ppbus(device_t dev, int how)
219{
234{
235 device_t ppbus = device_get_parent(dev);
236 struct lpt_data *sc = DEVTOSOFTC(dev);
220 int error;
221
222 if (sc->sc_state & HAVEBUS)
223 return (0);
224
225 /* we have the bus only if the request succeded */
237 int error;
238
239 if (sc->sc_state & HAVEBUS)
240 return (0);
241
242 /* we have the bus only if the request succeded */
226 if ((error = ppb_request_bus(&sc->lpt_dev, how)) == 0)
243 if ((error = ppb_request_bus(ppbus, dev, how)) == 0)
227 sc->sc_state |= HAVEBUS;
228
229 return (error);
230}
231
232static int
244 sc->sc_state |= HAVEBUS;
245
246 return (error);
247}
248
249static int
233lpt_release_ppbus(struct lpt_data *sc)
250lpt_release_ppbus(device_t dev)
234{
251{
235 ppb_release_bus(&sc->lpt_dev);
236 sc->sc_state &= ~HAVEBUS;
252 device_t ppbus = device_get_parent(dev);
253 struct lpt_data *sc = DEVTOSOFTC(dev);
254 int error = 0;
237
255
238 return (0);
256 if ((error = ppb_release_bus(ppbus, dev)) == 0)
257 sc->sc_state &= ~HAVEBUS;
258
259 return (error);
239}
240
241/*
242 * Internal routine to lptprobe to do port tests of one byte value
243 */
244static int
260}
261
262/*
263 * Internal routine to lptprobe to do port tests of one byte value
264 */
265static int
245lpt_port_test(struct lpt_data *sc, u_char data, u_char mask)
266lpt_port_test(device_t ppbus, u_char data, u_char mask)
246{
247 int temp, timeout;
248
249 data = data & mask;
267{
268 int temp, timeout;
269
270 data = data & mask;
250 ppb_wdtr(&sc->lpt_dev, data);
271 ppb_wdtr(ppbus, data);
251 timeout = 10000;
252 do {
253 DELAY(10);
272 timeout = 10000;
273 do {
274 DELAY(10);
254 temp = ppb_rdtr(&sc->lpt_dev) & mask;
275 temp = ppb_rdtr(ppbus) & mask;
255 }
256 while (temp != data && --timeout);
257 lprintf(("out=%x\tin=%x\ttout=%d\n", data, temp, timeout));
258 return (temp == data);
259}
260
261/*
262 * Probe simplified by replacing multiple loops with a hardcoded

--- 38 unchanged lines hidden (view full) ---

301 * 3) Set the data and control ports to a value of 0
302 *
303 * This probe routine has been tested on Epson Lx-800, HP LJ3P,
304 * Epson FX-1170 and C.Itoh 8510RM
305 * printers.
306 * Quick exit on fail added.
307 */
308static int
276 }
277 while (temp != data && --timeout);
278 lprintf(("out=%x\tin=%x\ttout=%d\n", data, temp, timeout));
279 return (temp == data);
280}
281
282/*
283 * Probe simplified by replacing multiple loops with a hardcoded

--- 38 unchanged lines hidden (view full) ---

322 * 3) Set the data and control ports to a value of 0
323 *
324 * This probe routine has been tested on Epson Lx-800, HP LJ3P,
325 * Epson FX-1170 and C.Itoh 8510RM
326 * printers.
327 * Quick exit on fail added.
328 */
329static int
309lpt_detect(struct lpt_data *sc)
330lpt_detect(device_t dev)
310{
331{
332 device_t ppbus = device_get_parent(dev);
333
311 static u_char testbyte[18] = {
312 0x55, /* alternating zeros */
313 0xaa, /* alternating ones */
314 0xfe, 0xfd, 0xfb, 0xf7,
315 0xef, 0xdf, 0xbf, 0x7f, /* walking zero */
316 0x01, 0x02, 0x04, 0x08,
317 0x10, 0x20, 0x40, 0x80 /* walking one */
318 };
319 int i, error, status;
320
321 status = 1; /* assume success */
322
334 static u_char testbyte[18] = {
335 0x55, /* alternating zeros */
336 0xaa, /* alternating ones */
337 0xfe, 0xfd, 0xfb, 0xf7,
338 0xef, 0xdf, 0xbf, 0x7f, /* walking zero */
339 0x01, 0x02, 0x04, 0x08,
340 0x10, 0x20, 0x40, 0x80 /* walking one */
341 };
342 int i, error, status;
343
344 status = 1; /* assume success */
345
323 if ((error = lpt_request_ppbus(sc, PPB_DONTWAIT))) {
346 if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
324 printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
325 status = 0;
326 goto end_probe;
327 }
328
329 for (i = 0; i < 18 && status; i++)
347 printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
348 status = 0;
349 goto end_probe;
350 }
351
352 for (i = 0; i < 18 && status; i++)
330 if (!lpt_port_test(sc, testbyte[i], 0xff)) {
353 if (!lpt_port_test(ppbus, testbyte[i], 0xff)) {
331 status = 0;
332 goto end_probe;
333 }
334
335end_probe:
336 /* write 0's to control and data ports */
354 status = 0;
355 goto end_probe;
356 }
357
358end_probe:
359 /* write 0's to control and data ports */
337 ppb_wdtr(&sc->lpt_dev, 0);
338 ppb_wctr(&sc->lpt_dev, 0);
360 ppb_wdtr(ppbus, 0);
361 ppb_wctr(ppbus, 0);
339
362
340 lpt_release_ppbus(sc);
363 lpt_release_ppbus(dev);
341
342 return (status);
343}
344
345/*
364
365 return (status);
366}
367
368/*
346 * lptprobe()
369 * lpt_probe()
347 */
370 */
348static struct ppb_device *
349lptprobe(struct ppb_data *ppb)
371static int
372lpt_probe(device_t dev)
350{
351 struct lpt_data *sc;
352 static int once;
353
354 if (!once++)
355 cdevsw_add(&lpt_cdevsw);
356
373{
374 struct lpt_data *sc;
375 static int once;
376
377 if (!once++)
378 cdevsw_add(&lpt_cdevsw);
379
357 sc = (struct lpt_data *) malloc(sizeof(struct lpt_data),
358 M_TEMP, M_NOWAIT);
359 if (!sc) {
360 printf(LPT_NAME ": cannot malloc!\n");
361 return (0);
362 }
380 sc = DEVTOSOFTC(dev);
363 bzero(sc, sizeof(struct lpt_data));
364
381 bzero(sc, sizeof(struct lpt_data));
382
365 lptdata[nlpt] = sc;
366
367 /*
383 /*
368 * lpt dependent initialisation.
369 */
370 sc->lpt_unit = nlpt;
371
372 /*
373 * ppbus dependent initialisation.
374 */
375 sc->lpt_dev.id_unit = sc->lpt_unit;
376 sc->lpt_dev.name = lptdriver.name;
377 sc->lpt_dev.ppb = ppb;
378 sc->lpt_dev.intr = lptintr;
379
380 /*
381 * Now, try to detect the printer.
382 */
384 * Now, try to detect the printer.
385 */
383 if (!lpt_detect(sc)) {
384 free(sc, M_TEMP);
385 return (0);
386 }
386 if (!lpt_detect(dev))
387 return (ENXIO);
387
388
388 /* Ok, go to next device on next probe */
389 nlpt ++;
389 device_set_desc(dev, "Printer");
390
390
391 return (&sc->lpt_dev);
391 return (0);
392}
393
394static int
392}
393
394static int
395lptattach(struct ppb_device *dev)
395lpt_attach(device_t dev)
396{
396{
397 struct lpt_data *sc = lptdata[dev->id_unit];
397 device_t ppbus = device_get_parent(dev);
398 struct lpt_data *sc = DEVTOSOFTC(dev);
399 int zero = 0, irq, unit = device_get_unit(dev);
398 int error;
399
400 int error;
401
400 /*
401 * Report ourselves
402 */
403 printf(LPT_NAME "%d: <generic printer> on ppbus %d\n",
404 dev->id_unit, dev->ppb->ppb_link->adapter_unit);
405
406 sc->sc_primed = 0; /* not primed yet */
407
402 sc->sc_primed = 0; /* not primed yet */
403
408 if ((error = lpt_request_ppbus(sc, PPB_DONTWAIT))) {
404 if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) {
409 printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
410 return (0);
411 }
412
405 printf(LPT_NAME ": cannot alloc ppbus (%d)!\n", error);
406 return (0);
407 }
408
413 ppb_wctr(&sc->lpt_dev, LPC_NINIT);
409 ppb_wctr(ppbus, LPC_NINIT);
414
415 /* check if we can use interrupt, should be done by ppc stuff */
416 lprintf(("oldirq %x\n", sc->sc_irq));
410
411 /* check if we can use interrupt, should be done by ppc stuff */
412 lprintf(("oldirq %x\n", sc->sc_irq));
417 if (ppb_get_irq(&sc->lpt_dev)) {
413
414 /* retrieve the ppbus irq */
415 BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
416
417 if (irq > 0) {
418 /* declare our interrupt handler */
419 sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
420 &zero, irq, irq, 1, RF_SHAREABLE);
421 }
422 if (sc->intr_resource) {
418 sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
423 sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
419 printf(LPT_NAME "%d: Interrupt-driven port\n", dev->id_unit);
424 device_printf(dev, "Interrupt-driven port\n");
420 } else {
421 sc->sc_irq = 0;
425 } else {
426 sc->sc_irq = 0;
422 lprintf((LPT_NAME "%d: Polled port\n", dev->id_unit));
427 device_printf(dev, "Polled port\n");
423 }
428 }
424 lprintf(("irq %x\n", sc->sc_irq));
429 lprintf(("irq %x %x\n", irq, sc->sc_irq));
425
430
426 lpt_release_ppbus(sc);
431 lpt_release_ppbus(dev);
427
432
428 make_dev(&lpt_cdevsw, dev->id_unit,
429 UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", dev->id_unit);
430 make_dev(&lpt_cdevsw, dev->id_unit | LP_BYPASS,
431 UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", dev->id_unit);
432 return (1);
433 make_dev(&lpt_cdevsw, unit,
434 UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d", unit);
435 make_dev(&lpt_cdevsw, unit | LP_BYPASS,
436 UID_ROOT, GID_WHEEL, 0600, LPT_NAME "%d.ctl", unit);
437 return (0);
433}
434
435static void
436lptout(void *arg)
437{
438}
439
440static void
441lptout(void *arg)
442{
438 struct lpt_data *sc = arg;
439 int pl;
443 device_t dev = (device_t)arg;
444 struct lpt_data *sc = DEVTOSOFTC(dev);
445#ifdef LPT_DEBUG
446 device_t ppbus = device_get_parent(dev);
447#endif
440
448
441 lprintf(("T %x ", ppb_rstr(&sc->lpt_dev)));
449 lprintf(("T %x ", ppb_rstr(ppbus)));
442 if (sc->sc_state & OPEN) {
443 sc->sc_backoff++;
444 if (sc->sc_backoff > hz/LPTOUTMAX)
445 sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
450 if (sc->sc_state & OPEN) {
451 sc->sc_backoff++;
452 if (sc->sc_backoff > hz/LPTOUTMAX)
453 sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
446 timeout(lptout, (caddr_t)sc, sc->sc_backoff);
454 timeout(lptout, (caddr_t)dev, sc->sc_backoff);
447 } else
448 sc->sc_state &= ~TOUT;
449
450 if (sc->sc_state & EERROR)
451 sc->sc_state &= ~EERROR;
452
453 /*
455 } else
456 sc->sc_state &= ~TOUT;
457
458 if (sc->sc_state & EERROR)
459 sc->sc_state &= ~EERROR;
460
461 /*
454 * Avoid possible hangs do to missed interrupts
462 * Avoid possible hangs due to missed interrupts
455 */
456 if (sc->sc_xfercnt) {
463 */
464 if (sc->sc_xfercnt) {
457 pl = spltty();
458 lpt_intr(sc->lpt_unit);
459 splx(pl);
465 lptintr(dev);
460 } else {
461 sc->sc_state &= ~OBUSY;
466 } else {
467 sc->sc_state &= ~OBUSY;
462 wakeup((caddr_t)sc);
468 wakeup((caddr_t)dev);
463 }
464}
465
466/*
467 * lptopen -- reset the printer, then wait until it's selected and not busy.
468 * If LP_BYPASS flag is selected, then we do not try to select the
469 * printer -- this is just used for passing ioctls.
470 */
471
472static int
473lptopen(dev_t dev, int flags, int fmt, struct proc *p)
474{
469 }
470}
471
472/*
473 * lptopen -- reset the printer, then wait until it's selected and not busy.
474 * If LP_BYPASS flag is selected, then we do not try to select the
475 * printer -- this is just used for passing ioctls.
476 */
477
478static int
479lptopen(dev_t dev, int flags, int fmt, struct proc *p)
480{
475 struct lpt_data *sc;
476
477 int s;
478 int trys, err;
479 u_int unit = LPTUNIT(minor(dev));
481 int s;
482 int trys, err;
483 u_int unit = LPTUNIT(minor(dev));
484 struct lpt_data *sc = UNITOSOFTC(unit);
485 device_t lptdev = UNITODEVICE(unit);
486 device_t ppbus = device_get_parent(lptdev);
480
487
481 if ((unit >= nlpt))
488 if (!sc)
482 return (ENXIO);
483
489 return (ENXIO);
490
484 sc = lptdata[unit];
485
486 if (sc->sc_state) {
487 lprintf((LPT_NAME ": still open %x\n", sc->sc_state));
488 return(EBUSY);
489 } else
490 sc->sc_state |= LPTINIT;
491
492 sc->sc_flags = LPTFLAGS(minor(dev));
493
494 /* Check for open with BYPASS flag set. */
495 if (sc->sc_flags & LP_BYPASS) {
496 sc->sc_state = OPEN;
497 return(0);
498 }
499
500 /* request the ppbus only if we don't have it already */
491 if (sc->sc_state) {
492 lprintf((LPT_NAME ": still open %x\n", sc->sc_state));
493 return(EBUSY);
494 } else
495 sc->sc_state |= LPTINIT;
496
497 sc->sc_flags = LPTFLAGS(minor(dev));
498
499 /* Check for open with BYPASS flag set. */
500 if (sc->sc_flags & LP_BYPASS) {
501 sc->sc_state = OPEN;
502 return(0);
503 }
504
505 /* request the ppbus only if we don't have it already */
501 if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
506 if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) {
507 /* give it a chance to try later */
508 sc->sc_state = 0;
502 return (err);
509 return (err);
510 }
503
504 s = spltty();
505 lprintf((LPT_NAME " flags 0x%x\n", sc->sc_flags));
506
511
512 s = spltty();
513 lprintf((LPT_NAME " flags 0x%x\n", sc->sc_flags));
514
507 /* set IRQ status according to ENABLE_IRQ flag */
515 /* set IRQ status according to ENABLE_IRQ flag
516 */
508 if (sc->sc_irq & LP_ENABLE_IRQ)
509 sc->sc_irq |= LP_USE_IRQ;
510 else
511 sc->sc_irq &= ~LP_USE_IRQ;
512
513 /* init printer */
514 if ((sc->sc_flags & LP_NO_PRIME) == 0) {
515 if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) {
517 if (sc->sc_irq & LP_ENABLE_IRQ)
518 sc->sc_irq |= LP_USE_IRQ;
519 else
520 sc->sc_irq &= ~LP_USE_IRQ;
521
522 /* init printer */
523 if ((sc->sc_flags & LP_NO_PRIME) == 0) {
524 if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) {
516 ppb_wctr(&sc->lpt_dev, 0);
525 ppb_wctr(ppbus, 0);
517 sc->sc_primed++;
518 DELAY(500);
519 }
520 }
521
526 sc->sc_primed++;
527 DELAY(500);
528 }
529 }
530
522 ppb_wctr(&sc->lpt_dev, LPC_SEL|LPC_NINIT);
531 ppb_wctr(ppbus, LPC_SEL|LPC_NINIT);
523
524 /* wait till ready (printer running diagnostics) */
525 trys = 0;
526 do {
527 /* ran out of waiting for the printer */
528 if (trys++ >= LPINITRDY*4) {
529 splx(s);
530 sc->sc_state = 0;
532
533 /* wait till ready (printer running diagnostics) */
534 trys = 0;
535 do {
536 /* ran out of waiting for the printer */
537 if (trys++ >= LPINITRDY*4) {
538 splx(s);
539 sc->sc_state = 0;
531 lprintf(("status %x\n", ppb_rstr(&sc->lpt_dev)));
540 lprintf(("status %x\n", ppb_rstr(ppbus)));
532
541
533 lpt_release_ppbus(sc);
542 lpt_release_ppbus(lptdev);
534 return (EBUSY);
535 }
536
537 /* wait 1/4 second, give up if we get a signal */
543 return (EBUSY);
544 }
545
546 /* wait 1/4 second, give up if we get a signal */
538 if (tsleep((caddr_t)sc, LPPRI|PCATCH, "lptinit", hz/4) !=
547 if (tsleep((caddr_t)lptdev, LPPRI|PCATCH, "lptinit", hz/4) !=
539 EWOULDBLOCK) {
540 sc->sc_state = 0;
541 splx(s);
542
548 EWOULDBLOCK) {
549 sc->sc_state = 0;
550 splx(s);
551
543 lpt_release_ppbus(sc);
552 lpt_release_ppbus(lptdev);
544 return (EBUSY);
545 }
546
547 /* is printer online and ready for output */
553 return (EBUSY);
554 }
555
556 /* is printer online and ready for output */
548 } while ((ppb_rstr(&sc->lpt_dev) &
557 } while ((ppb_rstr(ppbus) &
549 (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
550 (LPS_SEL|LPS_NBSY|LPS_NERR));
551
552 sc->sc_control = LPC_SEL|LPC_NINIT;
553 if (sc->sc_flags & LP_AUTOLF)
554 sc->sc_control |= LPC_AUTOL;
555
556 /* enable interrupt if interrupt-driven */
557 if (sc->sc_irq & LP_USE_IRQ)
558 sc->sc_control |= LPC_ENA;
559
558 (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
559 (LPS_SEL|LPS_NBSY|LPS_NERR));
560
561 sc->sc_control = LPC_SEL|LPC_NINIT;
562 if (sc->sc_flags & LP_AUTOLF)
563 sc->sc_control |= LPC_AUTOL;
564
565 /* enable interrupt if interrupt-driven */
566 if (sc->sc_irq & LP_USE_IRQ)
567 sc->sc_control |= LPC_ENA;
568
560 ppb_wctr(&sc->lpt_dev, sc->sc_control);
569 ppb_wctr(ppbus, sc->sc_control);
561
562 sc->sc_state = OPEN;
563 sc->sc_inbuf = geteblk(BUFSIZE);
564 sc->sc_statbuf = geteblk(BUFSTATSIZE);
565 sc->sc_xfercnt = 0;
566 splx(s);
567
568 /* release the ppbus */
570
571 sc->sc_state = OPEN;
572 sc->sc_inbuf = geteblk(BUFSIZE);
573 sc->sc_statbuf = geteblk(BUFSTATSIZE);
574 sc->sc_xfercnt = 0;
575 splx(s);
576
577 /* release the ppbus */
569 lpt_release_ppbus(sc);
578 lpt_release_ppbus(lptdev);
570
571 /* only use timeout if using interrupt */
572 lprintf(("irq %x\n", sc->sc_irq));
573 if (sc->sc_irq & LP_USE_IRQ) {
574 sc->sc_state |= TOUT;
579
580 /* only use timeout if using interrupt */
581 lprintf(("irq %x\n", sc->sc_irq));
582 if (sc->sc_irq & LP_USE_IRQ) {
583 sc->sc_state |= TOUT;
575 timeout(lptout, (caddr_t)sc,
584 timeout(lptout, (caddr_t)lptdev,
576 (sc->sc_backoff = hz/LPTOUTINITIAL));
577 }
578
579 lprintf(("opened.\n"));
580 return(0);
581}
582
583/*
584 * lptclose -- close the device, free the local line buffer.
585 *
586 * Check for interrupted write call added.
587 */
588
589static int
590lptclose(dev_t dev, int flags, int fmt, struct proc *p)
591{
585 (sc->sc_backoff = hz/LPTOUTINITIAL));
586 }
587
588 lprintf(("opened.\n"));
589 return(0);
590}
591
592/*
593 * lptclose -- close the device, free the local line buffer.
594 *
595 * Check for interrupted write call added.
596 */
597
598static int
599lptclose(dev_t dev, int flags, int fmt, struct proc *p)
600{
592 struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
601 u_int unit = LPTUNIT(minor(dev));
602 struct lpt_data *sc = UNITOSOFTC(unit);
603 device_t lptdev = UNITODEVICE(unit);
604 device_t ppbus = device_get_parent(lptdev);
593 int err;
594
595 if(sc->sc_flags & LP_BYPASS)
596 goto end_close;
597
605 int err;
606
607 if(sc->sc_flags & LP_BYPASS)
608 goto end_close;
609
598 if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
610 if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
599 return (err);
600
601 sc->sc_state &= ~OPEN;
602
603 /* if the last write was interrupted, don't complete it */
604 if((!(sc->sc_state & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
611 return (err);
612
613 sc->sc_state &= ~OPEN;
614
615 /* if the last write was interrupted, don't complete it */
616 if((!(sc->sc_state & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
605 while ((ppb_rstr(&sc->lpt_dev) &
617 while ((ppb_rstr(ppbus) &
606 (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
607 (LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
608 /* wait 1/4 second, give up if we get a signal */
618 (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
619 (LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
620 /* wait 1/4 second, give up if we get a signal */
609 if (tsleep((caddr_t)sc, LPPRI|PCATCH,
621 if (tsleep((caddr_t)lptdev, LPPRI|PCATCH,
610 "lpclose", hz) != EWOULDBLOCK)
611 break;
612
622 "lpclose", hz) != EWOULDBLOCK)
623 break;
624
613 ppb_wctr(&sc->lpt_dev, LPC_NINIT);
625 ppb_wctr(ppbus, LPC_NINIT);
614 brelse(sc->sc_inbuf);
615 brelse(sc->sc_statbuf);
616
617end_close:
626 brelse(sc->sc_inbuf);
627 brelse(sc->sc_statbuf);
628
629end_close:
618 /* release the bus anyway */
619 lpt_release_ppbus(sc);
630 /* release the bus anyway
631 * unregistration of interrupt forced by release
632 */
633 lpt_release_ppbus(lptdev);
620
621 sc->sc_state = 0;
622 sc->sc_xfercnt = 0;
623 lprintf(("closed.\n"));
624 return(0);
625}
626
627/*
628 * lpt_pushbytes()
629 * Workhorse for actually spinning and writing bytes to printer
630 * Derived from lpa.c
631 * Originally by ?
632 *
633 * This code is only used when we are polling the port
634 */
635static int
634
635 sc->sc_state = 0;
636 sc->sc_xfercnt = 0;
637 lprintf(("closed.\n"));
638 return(0);
639}
640
641/*
642 * lpt_pushbytes()
643 * Workhorse for actually spinning and writing bytes to printer
644 * Derived from lpa.c
645 * Originally by ?
646 *
647 * This code is only used when we are polling the port
648 */
649static int
636lpt_pushbytes(struct lpt_data *sc)
650lpt_pushbytes(device_t dev)
637{
651{
652 struct lpt_data *sc = DEVTOSOFTC(dev);
653 device_t ppbus = device_get_parent(dev);
638 int spin, err, tic;
639 char ch;
640
641 lprintf(("p"));
642 /* loop for every character .. */
643 while (sc->sc_xfercnt > 0) {
644 /* printer data */
645 ch = *(sc->sc_cp);
646 sc->sc_cp++;
647 sc->sc_xfercnt--;
648
649 /*
650 * Wait for printer ready.
651 * Loop 20 usecs testing BUSY bit, then sleep
652 * for exponentially increasing timeout. (vak)
653 */
654 int spin, err, tic;
655 char ch;
656
657 lprintf(("p"));
658 /* loop for every character .. */
659 while (sc->sc_xfercnt > 0) {
660 /* printer data */
661 ch = *(sc->sc_cp);
662 sc->sc_cp++;
663 sc->sc_xfercnt--;
664
665 /*
666 * Wait for printer ready.
667 * Loop 20 usecs testing BUSY bit, then sleep
668 * for exponentially increasing timeout. (vak)
669 */
654 for (spin = 0; NOT_READY(sc) && spin < MAX_SPIN; ++spin)
670 for (spin = 0; NOT_READY(ppbus) && spin < MAX_SPIN; ++spin)
655 DELAY(1); /* XXX delay is NOT this accurate! */
656 if (spin >= MAX_SPIN) {
657 tic = 0;
671 DELAY(1); /* XXX delay is NOT this accurate! */
672 if (spin >= MAX_SPIN) {
673 tic = 0;
658 while (NOT_READY(sc)) {
674 while (NOT_READY(ppbus)) {
659 /*
660 * Now sleep, every cycle a
661 * little longer ..
662 */
663 tic = tic + tic + 1;
664 /*
665 * But no more than 10 seconds. (vak)
666 */
667 if (tic > MAX_SLEEP)
668 tic = MAX_SLEEP;
675 /*
676 * Now sleep, every cycle a
677 * little longer ..
678 */
679 tic = tic + tic + 1;
680 /*
681 * But no more than 10 seconds. (vak)
682 */
683 if (tic > MAX_SLEEP)
684 tic = MAX_SLEEP;
669 err = tsleep((caddr_t)sc, LPPRI,
685 err = tsleep((caddr_t)dev, LPPRI,
670 LPT_NAME "poll", tic);
671 if (err != EWOULDBLOCK) {
672 return (err);
673 }
674 }
675 }
676
677 /* output data */
686 LPT_NAME "poll", tic);
687 if (err != EWOULDBLOCK) {
688 return (err);
689 }
690 }
691 }
692
693 /* output data */
678 ppb_wdtr(&sc->lpt_dev, ch);
694 ppb_wdtr(ppbus, ch);
679 /* strobe */
695 /* strobe */
680 ppb_wctr(&sc->lpt_dev, sc->sc_control|LPC_STB);
681 ppb_wctr(&sc->lpt_dev, sc->sc_control);
696 ppb_wctr(ppbus, sc->sc_control|LPC_STB);
697 ppb_wctr(ppbus, sc->sc_control);
682
683 }
684 return(0);
685}
686
687/*
688 * lptread --retrieve printer status in IEEE1284 NIBBLE mode
689 */
690
691static int
692lptread(dev_t dev, struct uio *uio, int ioflag)
693{
698
699 }
700 return(0);
701}
702
703/*
704 * lptread --retrieve printer status in IEEE1284 NIBBLE mode
705 */
706
707static int
708lptread(dev_t dev, struct uio *uio, int ioflag)
709{
694 struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
710 u_int unit = LPTUNIT(minor(dev));
711 struct lpt_data *sc = UNITOSOFTC(unit);
712 device_t lptdev = UNITODEVICE(unit);
713 device_t ppbus = device_get_parent(lptdev);
695 int error = 0, len;
696
714 int error = 0, len;
715
697 if ((error = ppb_1284_negociate(&sc->lpt_dev, PPB_NIBBLE, 0)))
716 if ((error = ppb_1284_negociate(ppbus, PPB_NIBBLE, 0)))
698 return (error);
699
700 /* read data in an other buffer, read/write may be simultaneous */
701 len = 0;
702 while (uio->uio_resid) {
717 return (error);
718
719 /* read data in an other buffer, read/write may be simultaneous */
720 len = 0;
721 while (uio->uio_resid) {
703 if ((error = ppb_1284_read(&sc->lpt_dev, PPB_NIBBLE,
722 if ((error = ppb_1284_read(ppbus, PPB_NIBBLE,
704 sc->sc_statbuf->b_data, min(BUFSTATSIZE,
705 uio->uio_resid), &len))) {
706 goto error;
707 }
708
709 if (!len)
710 goto error; /* no more data */
711
712 if ((error = uiomove(sc->sc_statbuf->b_data, len, uio)))
713 goto error;
714 }
715
716error:
723 sc->sc_statbuf->b_data, min(BUFSTATSIZE,
724 uio->uio_resid), &len))) {
725 goto error;
726 }
727
728 if (!len)
729 goto error; /* no more data */
730
731 if ((error = uiomove(sc->sc_statbuf->b_data, len, uio)))
732 goto error;
733 }
734
735error:
717 ppb_1284_terminate(&sc->lpt_dev);
736 ppb_1284_terminate(ppbus);
718 return (error);
719}
720
721/*
722 * lptwrite --copy a line from user space to a local buffer, then call
723 * putc to get the chars moved to the output queue.
724 *
725 * Flagging of interrupted write added.
726 */
727
728static int
729lptwrite(dev_t dev, struct uio *uio, int ioflag)
730{
731 register unsigned n;
737 return (error);
738}
739
740/*
741 * lptwrite --copy a line from user space to a local buffer, then call
742 * putc to get the chars moved to the output queue.
743 *
744 * Flagging of interrupted write added.
745 */
746
747static int
748lptwrite(dev_t dev, struct uio *uio, int ioflag)
749{
750 register unsigned n;
732 int pl, err;
751 int err;
733 u_int unit = LPTUNIT(minor(dev));
752 u_int unit = LPTUNIT(minor(dev));
734 struct lpt_data *sc = lptdata[LPTUNIT(minor(dev))];
753 struct lpt_data *sc = UNITOSOFTC(unit);
754 device_t lptdev = UNITODEVICE(unit);
755 device_t ppbus = device_get_parent(lptdev);
735
736 if(sc->sc_flags & LP_BYPASS) {
737 /* we can't do writes in bypass mode */
738 return(EPERM);
739 }
740
741 /* request the ppbus only if we don't have it already */
756
757 if(sc->sc_flags & LP_BYPASS) {
758 /* we can't do writes in bypass mode */
759 return(EPERM);
760 }
761
762 /* request the ppbus only if we don't have it already */
742 if ((err = lpt_request_ppbus(sc, PPB_WAIT|PPB_INTR)) != 0)
763 /* XXX interrupt registration?! */
764 if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0)
743 return (err);
744
765 return (err);
766
767 /* if interrupts are working, register the handler */
768 if (sc->sc_irq & LP_USE_IRQ) {
769 /* register our interrupt handler */
770 err = BUS_SETUP_INTR(ppbus, lptdev, sc->intr_resource,
771 INTR_TYPE_TTY, lpt_intr, lptdev,
772 &sc->intr_cookie);
773 if (err) {
774 device_printf(lptdev, "handler registration failed, polled mode.\n");
775 sc->sc_irq &= ~LP_USE_IRQ;
776 }
777 }
778
745 sc->sc_state &= ~INTERRUPTED;
746 while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
747 sc->sc_cp = sc->sc_inbuf->b_data ;
748 uiomove(sc->sc_cp, n, uio);
749 sc->sc_xfercnt = n ;
750
751 if (sc->sc_irq & LP_ENABLE_EXT) {
752 /* try any extended mode */
779 sc->sc_state &= ~INTERRUPTED;
780 while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
781 sc->sc_cp = sc->sc_inbuf->b_data ;
782 uiomove(sc->sc_cp, n, uio);
783 sc->sc_xfercnt = n ;
784
785 if (sc->sc_irq & LP_ENABLE_EXT) {
786 /* try any extended mode */
753 err = ppb_write(&sc->lpt_dev, sc->sc_cp,
754 sc->sc_xfercnt, 0);
787 err = ppb_write(ppbus, sc->sc_cp,
788 sc->sc_xfercnt, 0);
755 switch (err) {
756 case 0:
757 /* if not all data was sent, we could rely
758 * on polling for the last bytes */
759 sc->sc_xfercnt = 0;
760 break;
761 case EINTR:
762 sc->sc_state |= INTERRUPTED;

--- 6 unchanged lines hidden (view full) ---

769 return(err);
770 }
771 } else while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
772 lprintf(("i"));
773 /* if the printer is ready for a char, */
774 /* give it one */
775 if ((sc->sc_state & OBUSY) == 0){
776 lprintf(("\nC %d. ", sc->sc_xfercnt));
789 switch (err) {
790 case 0:
791 /* if not all data was sent, we could rely
792 * on polling for the last bytes */
793 sc->sc_xfercnt = 0;
794 break;
795 case EINTR:
796 sc->sc_state |= INTERRUPTED;

--- 6 unchanged lines hidden (view full) ---

803 return(err);
804 }
805 } else while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
806 lprintf(("i"));
807 /* if the printer is ready for a char, */
808 /* give it one */
809 if ((sc->sc_state & OBUSY) == 0){
810 lprintf(("\nC %d. ", sc->sc_xfercnt));
777 pl = spltty();
778 lpt_intr(sc->lpt_unit);
779 (void) splx(pl);
811 lptintr(lptdev);
780 }
781 lprintf(("W "));
782 if (sc->sc_state & OBUSY)
812 }
813 lprintf(("W "));
814 if (sc->sc_state & OBUSY)
783 if ((err = tsleep((caddr_t)sc,
815 if ((err = tsleep((caddr_t)lptdev,
784 LPPRI|PCATCH, LPT_NAME "write", 0))) {
785 sc->sc_state |= INTERRUPTED;
786 return(err);
787 }
788 }
789
790 /* check to see if we must do a polled write */
791 if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
792 lprintf(("p"));
793
816 LPPRI|PCATCH, LPT_NAME "write", 0))) {
817 sc->sc_state |= INTERRUPTED;
818 return(err);
819 }
820 }
821
822 /* check to see if we must do a polled write */
823 if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
824 lprintf(("p"));
825
794 err = lpt_pushbytes(sc);
826 err = lpt_pushbytes(lptdev);
795
796 if (err)
797 return(err);
798 }
799 }
800
801 /* we have not been interrupted, release the ppbus */
827
828 if (err)
829 return(err);
830 }
831 }
832
833 /* we have not been interrupted, release the ppbus */
802 lpt_release_ppbus(sc);
834 lpt_release_ppbus(lptdev);
803
804 return(0);
805}
806
807/*
808 * lpt_intr -- handle printer interrupts which occur when the printer is
809 * ready to accept another char.
810 *
811 * do checking for interrupted write call.
812 */
813
814static void
835
836 return(0);
837}
838
839/*
840 * lpt_intr -- handle printer interrupts which occur when the printer is
841 * ready to accept another char.
842 *
843 * do checking for interrupted write call.
844 */
845
846static void
815lpt_intr(int unit)
847lpt_intr(void *arg)
816{
848{
817 struct lpt_data *sc = lptdata[unit];
849 device_t lptdev = (device_t)arg;
850 device_t ppbus = device_get_parent(lptdev);
851 struct lpt_data *sc = DEVTOSOFTC(lptdev);
818 int sts;
819 int i;
820
821 /* we must own the bus to use it */
822 if ((sc->sc_state & HAVEBUS) == 0)
823 return;
824
825 /*
826 * Is printer online and ready for output?
827 *
828 * Avoid falling back to lptout() too quickly. First spin-loop
829 * to see if the printer will become ready ``really soon now''.
830 */
831 for (i = 0; i < 100 &&
852 int sts;
853 int i;
854
855 /* we must own the bus to use it */
856 if ((sc->sc_state & HAVEBUS) == 0)
857 return;
858
859 /*
860 * Is printer online and ready for output?
861 *
862 * Avoid falling back to lptout() too quickly. First spin-loop
863 * to see if the printer will become ready ``really soon now''.
864 */
865 for (i = 0; i < 100 &&
832 ((sts=ppb_rstr(&sc->lpt_dev)) & RDY_MASK) != LP_READY; i++) ;
866 ((sts=ppb_rstr(ppbus)) & RDY_MASK) != LP_READY; i++) ;
833
834 if ((sts & RDY_MASK) == LP_READY) {
835 sc->sc_state = (sc->sc_state | OBUSY) & ~EERROR;
836 sc->sc_backoff = hz/LPTOUTINITIAL;
837
838 if (sc->sc_xfercnt) {
839 /* send char */
840 /*lprintf(("%x ", *sc->sc_cp)); */
867
868 if ((sts & RDY_MASK) == LP_READY) {
869 sc->sc_state = (sc->sc_state | OBUSY) & ~EERROR;
870 sc->sc_backoff = hz/LPTOUTINITIAL;
871
872 if (sc->sc_xfercnt) {
873 /* send char */
874 /*lprintf(("%x ", *sc->sc_cp)); */
841 ppb_wdtr(&sc->lpt_dev, *sc->sc_cp++) ;
842 ppb_wctr(&sc->lpt_dev, sc->sc_control|LPC_STB);
875 ppb_wdtr(ppbus, *sc->sc_cp++) ;
876 ppb_wctr(ppbus, sc->sc_control|LPC_STB);
843 /* DELAY(X) */
877 /* DELAY(X) */
844 ppb_wctr(&sc->lpt_dev, sc->sc_control);
878 ppb_wctr(ppbus, sc->sc_control);
845
846 /* any more data for printer */
847 if(--(sc->sc_xfercnt) > 0) return;
848 }
849
850 /*
851 * No more data waiting for printer.
852 * Wakeup is not done if write call was interrupted.

--- 9 unchanged lines hidden (view full) ---

862 (sc->sc_state & OPEN))
863 sc->sc_state |= EERROR;
864 /* lptout() will jump in and try to restart. */
865 }
866 lprintf(("sts %x ", sts));
867}
868
869static void
879
880 /* any more data for printer */
881 if(--(sc->sc_xfercnt) > 0) return;
882 }
883
884 /*
885 * No more data waiting for printer.
886 * Wakeup is not done if write call was interrupted.

--- 9 unchanged lines hidden (view full) ---

896 (sc->sc_state & OPEN))
897 sc->sc_state |= EERROR;
898 /* lptout() will jump in and try to restart. */
899 }
900 lprintf(("sts %x ", sts));
901}
902
903static void
870lptintr(int unit)
904lptintr(device_t dev)
871{
872 /* call the interrupt at required spl level */
873 int s = spltty();
874
905{
906 /* call the interrupt at required spl level */
907 int s = spltty();
908
875 lpt_intr(unit);
909 lpt_intr(dev);
876
877 splx(s);
878 return;
879}
880
881static int
882lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
883{
884 int error = 0;
910
911 splx(s);
912 return;
913}
914
915static int
916lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
917{
918 int error = 0;
885 struct lpt_data *sc;
886 u_int unit = LPTUNIT(minor(dev));
919 u_int unit = LPTUNIT(minor(dev));
920 struct lpt_data *sc = UNITOSOFTC(unit);
887 u_char old_sc_irq; /* old printer IRQ status */
888
921 u_char old_sc_irq; /* old printer IRQ status */
922
889 sc = lptdata[unit];
890
891 switch (cmd) {
892 case LPT_IRQ :
893 if(sc->sc_irq & LP_HAS_IRQ) {
894 /*
895 * NOTE:
896 * If the IRQ status is changed,
897 * this will only be visible on the
898 * next open.

--- 35 unchanged lines hidden (view full) ---

934 error = EOPNOTSUPP;
935 break;
936 default:
937 error = ENODEV;
938 }
939
940 return(error);
941}
923 switch (cmd) {
924 case LPT_IRQ :
925 if(sc->sc_irq & LP_HAS_IRQ) {
926 /*
927 * NOTE:
928 * If the IRQ status is changed,
929 * this will only be visible on the
930 * next open.

--- 35 unchanged lines hidden (view full) ---

966 error = EOPNOTSUPP;
967 break;
968 default:
969 error = ENODEV;
970 }
971
972 return(error);
973}
974
975DRIVER_MODULE(lpt, ppbus, lpt_driver, lpt_devclass, 0, 0);
976
977#endif
978