1 /* $NetBSD: lpt.c,v 1.27 2008/04/16 09:39:01 cegger Exp $ */
4 * Copyright (c) 1990 William F. Jolitz, TeleMuse
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This software is a component of "386BSD" developed by
18 * William F. Jolitz, TeleMuse.
19 * 4. Neither the name of the developer nor the name "386BSD"
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
24 * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
25 * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
26 * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
27 * NOT MAKE USE OF THIS WORK.
29 * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
30 * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
31 * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES
32 * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
33 * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
34 * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
35 * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
36 * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
38 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * from: unknown origin, 386BSD 0.1
51 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
52 * From Id: nlpt.c,v 1.14 1999/02/08 13:55:43 des Exp
53 * FreeBSD: src/sys/dev/ppbus/lpt.c,v 1.15.2.3 2000/07/07 00:30:40 obrien Exp
57 * Device Driver for AT parallel printer port
58 * Written by William Jolitz 12/18/90
62 * Updated for ppbus by Nicolas Souchu
66 #include <sys/cdefs.h>
67 __KERNEL_RCSID(0, "$NetBSD: lpt.c,v 1.27 2008/04/16 09:39:01 cegger Exp $");
69 #include "opt_ppbus_lpt.h"
71 #include <sys/param.h>
72 #include <sys/systm.h>
74 #include <sys/kernel.h>
76 #include <sys/malloc.h>
79 #include <sys/ioctl.h>
80 #include <sys/types.h>
81 #include <sys/syslog.h>
85 #include <dev/ppbus/ppbus_1284.h>
86 #include <dev/ppbus/ppbus_base.h>
87 #include <dev/ppbus/ppbus_io.h>
88 #include <dev/ppbus/ppbus_msq.h>
89 #include <dev/ppbus/ppbus_var.h>
91 #include <dev/ppbus/lptvar.h>
92 #include <dev/ppbus/lptreg.h>
93 #include <dev/ppbus/lptio.h>
95 /* Autoconf functions */
96 static int lpt_probe(device_t
, cfdata_t
, void *);
97 static void lpt_attach(device_t
, device_t
, void *);
98 static int lpt_detach(device_t
, int);
100 /* Autoconf structure */
101 CFATTACH_DECL_NEW(lpt_ppbus
, sizeof(struct lpt_softc
), lpt_probe
, lpt_attach
,
104 extern struct cfdriver lpt_cd
;
106 dev_type_open(lptopen
);
107 dev_type_close(lptclose
);
108 dev_type_read(lptread
);
109 dev_type_write(lptwrite
);
110 dev_type_ioctl(lptioctl
);
112 const struct cdevsw lpt_cdevsw
= {
113 lptopen
, lptclose
, lptread
, lptwrite
, lptioctl
,
114 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
118 /* Function prototypes */
119 static int lpt_detect(device_t
);
120 static int lpt_request_ppbus(struct lpt_softc
*, int);
121 static int lpt_release_ppbus(struct lpt_softc
*, int);
122 static int lpt_logstatus(const device_t
, const unsigned char);
128 lpt_probe(device_t parent
, cfdata_t match
, void *aux
)
130 /* Test ppbus's capability */
131 return lpt_detect(parent
);
135 lpt_attach(device_t parent
, device_t self
, void *aux
)
137 struct lpt_softc
* sc
= device_private(self
);
138 struct ppbus_device_softc
* ppbdev
= &(sc
->ppbus_dev
);
139 struct ppbus_attach_args
* args
= aux
;
143 ppbdev
->sc_dev
= self
;
145 error
= lpt_request_ppbus(sc
, 0);
147 printf("%s(%s): error (%d) requesting bus(%s). Device not "
148 "properly attached.\n", __func__
, device_xname(self
),
149 error
, device_xname(parent
));
153 /* Record capabilities */
154 ppbdev
->capabilities
= args
->capabilities
;
156 /* Allocate memory buffers */
157 if(ppbdev
->capabilities
& PPBUS_HAS_DMA
) {
158 if(ppbus_dma_malloc(parent
, &(sc
->sc_inbuf
),
159 &(sc
->sc_in_baddr
), BUFSIZE
)) {
161 printf(" : cannot allocate input DMA buffer. Device "
162 "not properly attached!\n");
165 if(ppbus_dma_malloc(parent
, &(sc
->sc_outbuf
),
166 &(sc
->sc_out_baddr
), BUFSIZE
)) {
168 ppbus_dma_free(parent
, &(sc
->sc_inbuf
),
169 &(sc
->sc_in_baddr
), BUFSIZE
);
170 printf(" : cannot allocate output DMA buffer. Device "
171 "not properly attached!\n");
175 sc
->sc_inbuf
= malloc(BUFSIZE
, M_DEVBUF
, M_WAITOK
);
176 sc
->sc_outbuf
= malloc(BUFSIZE
, M_DEVBUF
, M_WAITOK
);
180 ppbdev
->ctx
.mode
= ppbus_get_mode(parent
);
181 snprintb(buf
, sizeof(buf
),
182 "\20\1COMPATIBLE\2NIBBLE\3PS2\4EPP\5ECP\6FAST_CENTR",
184 printf(": port mode = %s\n", buf
);
186 /* Initialize the device on open by default */
187 sc
->sc_flags
= LPT_PRIME
;
189 lpt_release_ppbus(sc
, 0);
193 lpt_detach(device_t self
, int flags
)
195 struct lpt_softc
* lpt
= device_private(self
);
196 struct ppbus_device_softc
* ppbdev
= (struct ppbus_device_softc
*) lpt
;
199 if(lpt
->sc_state
& HAVEBUS
) {
200 err
= lpt_release_ppbus(lpt
, 0);
202 printf("%s error (%d) while releasing bus",
203 device_xname(self
), err
);
204 if(flags
& DETACH_FORCE
) {
205 printf(", continuing (DETACH_FORCE)!\n");
208 printf(", terminating!\n");
212 lpt
->sc_state
&= ~HAVEBUS
;
215 ppbdev
->ctx
.valid
= 0;
217 /* Free memory buffers */
218 if(ppbdev
->capabilities
& PPBUS_HAS_DMA
) {
219 ppbus_dma_free(device_parent(self
), &(lpt
->sc_inbuf
),
220 &(lpt
->sc_in_baddr
), BUFSIZE
);
221 ppbus_dma_free(device_parent(self
), &(lpt
->sc_outbuf
),
222 &(lpt
->sc_out_baddr
), BUFSIZE
);
224 free(lpt
->sc_inbuf
, M_DEVBUF
);
225 free(lpt
->sc_outbuf
, M_DEVBUF
);
231 /* Grab bus for lpt device */
233 lpt_request_ppbus(struct lpt_softc
* lpt
, int how
)
235 device_t dev
= lpt
->ppbus_dev
.sc_dev
;
238 error
= ppbus_request_bus(device_parent(dev
), dev
, how
, (hz
));
240 lpt
->sc_state
|= HAVEBUS
;
243 LPT_DPRINTF(("%s(%s): error %d requesting bus.\n", __func__
,
244 device_xname(dev
), error
));
250 /* Release ppbus to enable other devices to use it. */
252 lpt_release_ppbus(struct lpt_softc
* lpt
, int how
)
254 device_t dev
= lpt
->ppbus_dev
.sc_dev
;
257 if(lpt
->sc_state
& HAVEBUS
) {
258 error
= ppbus_release_bus(device_parent(dev
), dev
, how
, (hz
));
260 lpt
->sc_state
&= ~HAVEBUS
;
262 LPT_DPRINTF(("%s(%s): error releasing bus.\n", __func__
,
268 LPT_DPRINTF(("%s(%s): device does not own bus.\n", __func__
,
277 * Probe simplified by replacing multiple loops with a hardcoded
278 * test pattern - 1999/02/08 des@freebsd.org
280 * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94
281 * Based partially on Rod Grimes' printer probe
284 * 1) If no port address was given, use the bios detected ports
285 * and autodetect what ports the printers are on.
286 * 2) Otherwise, probe the data port at the address given,
287 * using the method in Rod Grimes' port probe.
288 * (Much code ripped off directly from Rod's probe.)
290 * Comments from Rod's probe:
292 * 1) You should be able to write to and read back the same value
293 * to the data port. Do an alternating zeros, alternating ones,
294 * walking zero, and walking one test to check for stuck bits.
296 * 2) You should be able to write to and read back the same value
297 * to the control port lower 5 bits, the upper 3 bits are reserved
298 * per the IBM PC technical reference manauls and different boards
299 * do different things with them. Do an alternating zeros, alternating
300 * ones, walking zero, and walking one test to check for stuck bits.
302 * Some printers drag the strobe line down when the are powered off
303 * so this bit has been masked out of the control port test.
305 * XXX Some printers may not like a fast pulse on init or strobe, I
306 * don't know at this point, if that becomes a problem these bits
307 * should be turned off in the mask byte for the control port test.
309 * We are finally left with a mask of 0x14, due to some printers
310 * being adamant about holding other bits high ........
312 * Before probing the control port, we write a 0 to the data port -
313 * If not, some printers chuck out garbage when the strobe line
316 * 3) Set the data and control ports to a value of 0
318 * This probe routine has been tested on Epson Lx-800, HP LJ3P,
319 * Epson FX-1170 and C.Itoh 8510RM
321 * Quick exit on fail added.
324 lpt_detect(device_t dev
)
326 static const u_char testbyte
[18] = {
327 0x55, /* alternating zeros */
328 0xaa, /* alternating ones */
329 0xfe, 0xfd, 0xfb, 0xf7,
330 0xef, 0xdf, 0xbf, 0x7f, /* walking zero */
331 0x01, 0x02, 0x04, 0x08,
332 0x10, 0x20, 0x40, 0x80 /* walking one */
335 u_char dtr
, ctr
, str
, var
;
337 /* Save register contents */
338 dtr
= ppbus_rdtr(dev
);
339 ctr
= ppbus_rctr(dev
);
340 str
= ppbus_rstr(dev
);
342 status
= 1; /* assume success */
345 for(i
= 0; i
< 18; i
++) {
346 ppbus_wdtr(dev
, testbyte
[i
]);
347 if((var
= ppbus_rdtr(dev
)) != testbyte
[i
]) {
349 LPT_DPRINTF(("%s(%s): byte value %x cannot be written "
350 "and read from data port (got %x instead).\n",
351 __func__
, device_xname(dev
), testbyte
[i
], var
));
356 /* Test control port */
358 for(i
= 0; i
< 18; i
++) {
359 ppbus_wctr(dev
, (testbyte
[i
] & 0x14));
360 if(((var
= ppbus_rctr(dev
)) & 0x14) != (testbyte
[i
] & 0x14)) {
362 LPT_DPRINTF(("%s(%s): byte value %x (unmasked value "
363 "%x) cannot be written and read from control "
364 "port (got %x instead).\n", __func__
,
365 device_xname(dev
), (testbyte
[i
] & 0x14),
366 testbyte
[i
], (var
& 0x14)));
372 /* Restore contents of registers */
373 ppbus_wdtr(dev
, dtr
);
374 ppbus_wctr(dev
, ctr
);
375 ppbus_wstr(dev
, str
);
380 /* Log status of status register for printer port */
382 lpt_logstatus(const device_t dev
, const unsigned char status
)
387 if(!(status
& LPS_SEL
)) {
388 log(LOG_ERR
, "%s: offline.", device_xname(dev
));
390 else if(!(status
& LPS_NBSY
)) {
391 log(LOG_ERR
, "%s: busy.", device_xname(dev
));
393 else if(status
& LPS_OUT
) {
394 log(LOG_ERR
, "%s: out of paper.", device_xname(dev
));
397 else if(!(status
& LPS_NERR
)) {
398 log(LOG_ERR
, "%s: output error.", device_xname(dev
));
401 log(LOG_ERR
, "%s: no error indication.", device_xname(dev
));
409 * lptopen -- reset the printer, then wait until it's selected and not busy.
412 lptopen(dev_t dev_id
, int flags
, int fmt
, struct lwp
*l
)
417 struct lpt_softc
* lpt
;
418 struct ppbus_device_softc
* ppbus_dev
;
421 dev
= device_lookup(&lpt_cd
, LPTUNIT(dev_id
));
423 LPT_DPRINTF(("%s(): device not configured.\n", __func__
));
427 lpt
= device_private(dev
);
429 ppbus
= device_parent(dev
);
430 ppbus_dev
= &(lpt
->ppbus_dev
);
432 /* Request the ppbus */
433 err
= lpt_request_ppbus(lpt
, PPBUS_WAIT
|PPBUS_INTR
);
435 LPT_DPRINTF(("%s(%s): error (%d) while requesting bus.\n",
436 __func__
, device_xname(dev
), err
));
440 /* Update bus mode */
441 ppbus_dev
->ctx
.mode
= ppbus_get_mode(ppbus
);
444 if ((lpt
->sc_flags
& LPT_PRIME
) && !LPTCTL(dev_id
)) {
445 LPT_VPRINTF(("%s(%s): initializing printer.\n", __func__
,
447 lpt
->sc_state
|= LPTINIT
;
448 ppbus_wctr(ppbus
, LPC_SEL
| LPC_NINIT
);
450 /* wait till ready (printer running diagnostics) */
451 for(trys
= 0, status
= ppbus_rstr(ppbus
); (status
& RDY_MASK
)
452 != LP_READY
; trys
+= LPT_STEP
, status
=
455 /* Time up waiting for the printer */
456 if(trys
>= LPT_TIMEOUT
)
458 /* wait LPT_STEP ticks, give up if we get a signal */
460 err
= tsleep((void *)lpt
, LPPRI
|PCATCH
,
461 "lptinit", LPT_STEP
);
462 if((err
) && (err
!= EWOULDBLOCK
)) {
463 lpt
->sc_state
&= ~LPTINIT
;
464 LPT_DPRINTF(("%s(%s): interrupted "
465 "during initialization.\n", __func__
,
467 lpt_release_ppbus(lpt
, PPBUS_WAIT
);
473 lpt
->sc_state
&= ~LPTINIT
;
474 if(trys
>= LPT_TIMEOUT
) {
475 LPT_DPRINTF(("%s(%s): timed out while initializing "
476 "printer. [status %x]\n", __func__
,
477 device_xname(dev
), status
));
478 err
= lpt_logstatus(dev
, status
);
479 lpt_release_ppbus(lpt
, PPBUS_WAIT
);
483 LPT_VPRINTF(("%s(%s): printer ready.\n", __func__
,
488 /* Set autolinefeed if requested */
489 if (lpt
->sc_flags
& LPT_AUTOLF
)
490 ppbus_wctr(ppbus
, LPC_AUTOL
);
492 ppbus_wctr(ppbus
, 0);
495 lpt
->sc_state
|= OPEN
;
501 * lptclose -- close the device, free the local line buffer.
503 * Check for interrupted write call added.
506 lptclose(dev_t dev_id
, int flags
, int fmt
, struct lwp
*l
)
508 device_t dev
= device_lookup(&lpt_cd
, LPTUNIT(dev_id
));
509 struct lpt_softc
*sc
= device_private(dev
);
512 err
= lpt_release_ppbus(sc
, PPBUS_WAIT
|PPBUS_INTR
);
514 LPT_DPRINTF(("%s(%s): error (%d) while releasing ppbus.\n",
515 __func__
, device_xname(dev
), err
));
524 * lptread --retrieve printer status in IEEE1284 NIBBLE mode
527 lptread(dev_t dev_id
, struct uio
*uio
, int ioflag
)
531 device_t dev
= device_lookup(&lpt_cd
, LPTUNIT(dev_id
));
532 struct lpt_softc
*sc
= device_private(dev
);
534 if(!(sc
->sc_state
& HAVEBUS
)) {
535 LPT_DPRINTF(("%s(%s): attempt to read using device which does "
536 "not own the bus(%s).\n", __func__
, device_xname(dev
),
537 device_xname(device_parent(dev
))));
541 sc
->sc_state
&= ~INTERRUPTED
;
542 while (uio
->uio_resid
) {
543 error
= ppbus_read(device_parent(dev
), sc
->sc_outbuf
,
544 min(BUFSIZE
, uio
->uio_resid
), 0, &len
);
546 /* If error or no more data, stop */
548 if (error
!= EWOULDBLOCK
)
549 sc
->sc_state
|= INTERRUPTED
;
555 if ((error
= uiomove(sc
->sc_outbuf
, len
, uio
)))
563 * lptwrite --copy a line from user space to a local buffer, then call
564 * putc to get the chars moved to the output queue.
566 * Flagging of interrupted write added.
569 lptwrite(dev_t dev_id
, struct uio
* uio
, int ioflag
)
573 device_t dev
= device_lookup(&lpt_cd
, LPTUNIT(dev_id
));
574 struct lpt_softc
* sc
= device_private(dev
);
576 /* Check state and flags */
577 if(!(sc
->sc_state
& HAVEBUS
)) {
578 LPT_DPRINTF(("%s(%s): attempt to write using device which does "
579 "not own the bus(%s).\n", __func__
, device_xname(dev
),
580 device_xname(device_parent(dev
))));
584 LPT_VPRINTF(("%s(%s): writing %zu bytes\n", __func__
,
585 device_xname(dev
), uio
->uio_resid
));
588 sc
->sc_state
&= ~INTERRUPTED
;
589 while (uio
->uio_resid
) {
590 n
= MIN(BUFSIZE
, uio
->uio_resid
);
591 error
= uiomove(sc
->sc_inbuf
, n
, uio
);
595 error
= ppbus_write(device_parent(dev
), sc
->sc_inbuf
, n
, ioflag
,
598 if (error
!= EWOULDBLOCK
)
599 sc
->sc_state
|= INTERRUPTED
;
604 LPT_VPRINTF(("%s(%s): transfer finished, error %d.\n", __func__
,
605 device_xname(dev
), error
));
612 lptioctl(dev_t dev_id
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
614 device_t dev
= device_lookup(&lpt_cd
, LPTUNIT(dev_id
));
615 struct lpt_softc
*sc
= device_private(dev
);
619 if(!(sc
->sc_state
& HAVEBUS
)) {
620 LPT_DPRINTF(("%s(%s): attempt to perform ioctl on device which "
621 "does not own the bus(%s).\n", __func__
, device_xname(dev
),
622 device_xname(device_parent(dev
))));
628 switch (ppbus_get_mode(device_parent(dev
))) {
629 case PPBUS_COMPATIBLE
:
656 switch (*(int *)data
) {
658 val
= PPBUS_COMPATIBLE
;
682 error
= ppbus_set_mode(device_parent(dev
), val
, 0);
690 error
= ppbus_read_ivar(device_parent(dev
), PPBUS_IVAR_DMA
, &val
);
696 /* IEEE mode negotiation */
697 error
= ppbus_read_ivar(device_parent(dev
), PPBUS_IVAR_IEEE
, &val
);
704 error
= ppbus_read_ivar(device_parent(dev
), PPBUS_IVAR_INTR
, &val
);
720 val
= (fl
& LPT_DMA
);
721 error
= ppbus_write_ivar(device_parent(dev
), PPBUS_IVAR_DMA
, &val
);
725 /* IEEE mode negotiation */
726 val
= (fl
& LPT_IEEE
);
727 error
= ppbus_write_ivar(device_parent(dev
), PPBUS_IVAR_IEEE
, &val
);
732 val
= (fl
& LPT_INTR
);
733 error
= ppbus_write_ivar(device_parent(dev
), PPBUS_IVAR_INTR
, &val
);
738 sc
->sc_flags
= fl
& (LPT_PRIME
|LPT_AUTOLF
);