olpt.c revision 55391
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
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This software is a component of "386BSD" developed by
16 *	William F. Jolitz, TeleMuse.
17 * 4. Neither the name of the developer nor the name "386BSD"
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
22 * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
23 * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
24 * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
25 * NOT MAKE USE OF THIS WORK.
26 *
27 * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
28 * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
29 * REFERENCES SUCH AS THE  "PORTING UNIX TO THE 386" SERIES
30 * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
31 * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
32 * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
33 * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
34 * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPER BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
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 * $FreeBSD: head/sys/pc98/cbus/olpt.c 55391 2000-01-04 04:46:50Z nyan $
50 */
51
52/*
53 * Device Driver for AT parallel printer port
54 * Written by William Jolitz 12/18/90
55 */
56
57/*
58 * Parallel port TCP/IP interfaces added.  I looked at the driver from
59 * MACH but this is a complete rewrite, and btw. incompatible, and it
60 * should perform better too.  I have never run the MACH driver though.
61 *
62 * This driver sends two bytes (0x08, 0x00) in front of each packet,
63 * to allow us to distinguish another format later.
64 *
65 * Now added an Linux/Crynwr compatibility mode which is enabled using
66 * IF_LINK0 - Tim Wilkinson.
67 *
68 * TODO:
69 *    Make HDLC/PPP mode, use IF_LLC1 to enable.
70 *
71 * Connect the two computers using a Laplink parallel cable to use this
72 * feature:
73 *
74 *      +----------------------------------------+
75 * 	|A-name	A-End	B-End	Descr.	Port/Bit |
76 *      +----------------------------------------+
77 *	|DATA0	2	15	Data	0/0x01   |
78 *	|-ERROR	15	2	   	1/0x08   |
79 *      +----------------------------------------+
80 *	|DATA1	3	13	Data	0/0x02	 |
81 *	|+SLCT	13	3	   	1/0x10   |
82 *      +----------------------------------------+
83 *	|DATA2	4	12	Data	0/0x04   |
84 *	|+PE	12	4	   	1/0x20   |
85 *      +----------------------------------------+
86 *	|DATA3	5	10	Strobe	0/0x08   |
87 *	|-ACK	10	5	   	1/0x40   |
88 *      +----------------------------------------+
89 *	|DATA4	6	11	Data	0/0x10   |
90 *	|BUSY	11	6	   	1/~0x80  |
91 *      +----------------------------------------+
92 *	|GND	18-25	18-25	GND	-        |
93 *      +----------------------------------------+
94 *
95 * Expect transfer-rates up to 75 kbyte/sec.
96 *
97 * If GCC could correctly grok
98 *	register int port asm("edx")
99 * the code would be cleaner
100 *
101 * Poul-Henning Kamp <phk@freebsd.org>
102 */
103
104#include "olpt.h"
105#include "opt_inet.h"
106#ifdef PC98
107#undef INET	/* PLIP is not supported for old PC-98 */
108#endif
109
110#include <sys/param.h>
111#include <sys/systm.h>
112#include <sys/conf.h>
113#include <sys/buf.h>
114#include <sys/kernel.h>
115#include <sys/uio.h>
116#include <sys/syslog.h>
117#include <machine/clock.h>
118#include <machine/lpt.h>
119
120#include <i386/isa/isa_device.h>
121#include <i386/isa/lptreg.h>
122
123#ifdef INET
124#include <sys/malloc.h>
125#include <sys/mbuf.h>
126#include <sys/socket.h>
127#include <sys/sockio.h>
128
129#include <net/if.h>
130#include <net/if_types.h>
131#include <net/netisr.h>
132#include <netinet/in.h>
133#include <netinet/in_var.h>
134#include <net/bpf.h>
135#endif /* INET */
136
137
138#define	LPINITRDY	4	/* wait up to 4 seconds for a ready */
139#define	LPTOUTINITIAL	10	/* initial timeout to wait for ready 1/10 s */
140#define	LPTOUTMAX	1	/* maximal timeout 1 s */
141#define	LPPRI		(PZERO+8)
142#define	BUFSIZE		1024
143
144#ifdef INET
145#ifndef LPMTU			/* MTU for the lp# interfaces */
146#define	LPMTU	1500
147#endif
148
149#ifndef LPMAXSPIN1		/* DELAY factor for the lp# interfaces */
150#define	LPMAXSPIN1	8000   /* Spinning for remote intr to happen */
151#endif
152
153#ifndef LPMAXSPIN2		/* DELAY factor for the lp# interfaces */
154#define	LPMAXSPIN2	500	/* Spinning for remote handshake to happen */
155#endif
156
157#ifndef LPMAXERRS		/* Max errors before !RUNNING */
158#define	LPMAXERRS	100
159#endif
160
161#define CLPIPHDRLEN	14	/* We send dummy ethernet addresses (two) + packet type in front of packet */
162#define	CLPIP_SHAKE	0x80	/* This bit toggles between nibble reception */
163#define MLPIPHDRLEN	CLPIPHDRLEN
164
165#define LPIPHDRLEN	2	/* We send 0x08, 0x00 in front of packet */
166#define	LPIP_SHAKE	0x40	/* This bit toggles between nibble reception */
167#if !defined(MLPIPHDRLEN) || LPIPHDRLEN > MLPIPHDRLEN
168#define MLPIPHDRLEN	LPIPHDRLEN
169#endif
170
171#define	LPIPTBLSIZE	256	/* Size of octet translation table */
172
173#endif /* INET */
174
175#ifndef PC98
176/* BIOS printer list - used by BIOS probe*/
177#define	BIOS_LPT_PORTS	0x408
178#define	BIOS_PORTS	(short *)(KERNBASE+BIOS_LPT_PORTS)
179#define	BIOS_MAX_LPT	4
180#endif
181
182
183#ifndef DEBUG
184#define lprintf(args)
185#else
186#define lprintf(args)	do {				\
187				if (lptflag)		\
188					printf args;	\
189			} while (0)
190static int volatile lptflag = 1;
191#endif
192
193#define	LPTUNIT(s)	((s)&0x03)
194#define	LPTFLAGS(s)	((s)&0xfc)
195
196static struct lpt_softc {
197	int	sc_port;
198	short	sc_state;
199	/* default case: negative prime, negative ack, handshake strobe,
200	   prime once */
201	u_char	sc_control;
202	char	sc_flags;
203#define LP_POS_INIT	0x04	/* if we are a postive init signal */
204#define LP_POS_ACK	0x08	/* if we are a positive going ack */
205#define LP_NO_PRIME	0x10	/* don't prime the printer at all */
206#define LP_PRIMEOPEN	0x20	/* prime on every open */
207#define LP_AUTOLF	0x40	/* tell printer to do an automatic lf */
208#define LP_BYPASS	0x80	/* bypass  printer ready checks */
209	struct	buf *sc_inbuf;
210	short	sc_xfercnt ;
211	char	sc_primed;
212	char	*sc_cp ;
213	u_char	sc_irq ;	/* IRQ status of port */
214#define LP_HAS_IRQ	0x01	/* we have an irq available */
215#define LP_USE_IRQ	0x02	/* we are using our irq */
216#define LP_ENABLE_IRQ	0x04	/* enable IRQ on open */
217	u_char	sc_backoff ;	/* time to call lptout() again */
218
219#ifdef INET
220	struct  ifnet	sc_if;
221	u_char		*sc_ifbuf;
222	int		sc_iferrs;
223#endif
224} lpt_sc[NOLPT] ;
225
226/* bits for state */
227#define	OPEN		(1<<0)	/* device is open */
228#define	ASLP		(1<<1)	/* awaiting draining of printer */
229#define	ERROR		(1<<2)	/* error was received from printer */
230#define	OBUSY		(1<<3)	/* printer is busy doing output */
231#define LPTOUT		(1<<4)	/* timeout while not selected */
232#define TOUT		(1<<5)	/* timeout while not selected */
233#define INIT		(1<<6)	/* waiting to initialize for open */
234#define INTERRUPTED	(1<<7)	/* write call was interrupted */
235
236
237/* status masks to interrogate printer status */
238#define RDY_MASK	(LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)	/* ready ? */
239#define LP_READY	(LPS_SEL|LPS_NBSY|LPS_NERR)
240
241/* Printer Ready condition  - from lpa.c */
242/* Only used in polling code */
243#ifdef PC98
244#define	NOT_READY(x)	((inb(x) & LPS_NBSY) != LPS_NBSY)
245#else	/* IBM-PC */
246#define	LPS_INVERT	(LPS_NBSY | LPS_NACK |           LPS_SEL | LPS_NERR)
247#define	LPS_MASK	(LPS_NBSY | LPS_NACK | LPS_OUT | LPS_SEL | LPS_NERR)
248#define	NOT_READY(x)	((inb(x)^LPS_INVERT)&LPS_MASK)
249#endif
250
251#define	MAX_SLEEP	(hz*5)	/* Timeout while waiting for device ready */
252#define	MAX_SPIN	20	/* Max delay for device ready in usecs */
253
254static timeout_t lptout;
255static int	lptprobe (struct isa_device *dvp);
256static int	lptattach (struct isa_device *isdp);
257static ointhand2_t	lptintr;
258
259#ifdef INET
260
261/* Tables for the lp# interface */
262static u_char *txmith;
263#define txmitl (txmith+(1*LPIPTBLSIZE))
264#define trecvh (txmith+(2*LPIPTBLSIZE))
265#define trecvl (txmith+(3*LPIPTBLSIZE))
266
267static u_char *ctxmith;
268#define ctxmitl (ctxmith+(1*LPIPTBLSIZE))
269#define ctrecvh (ctxmith+(2*LPIPTBLSIZE))
270#define ctrecvl (ctxmith+(3*LPIPTBLSIZE))
271
272/* Functions for the lp# interface */
273static void lpattach(struct lpt_softc *,int);
274#ifndef PC98
275static int lpinittables(void);
276#endif
277static int lpioctl(struct ifnet *, u_long, caddr_t);
278static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
279	struct rtentry *);
280static void lpintr(int);
281#endif /* INET */
282
283struct	isa_driver olptdriver = {
284	lptprobe, lptattach, "olpt"
285};
286
287static	d_open_t	lptopen;
288static	d_close_t	lptclose;
289static	d_write_t	lptwrite;
290static	d_ioctl_t	lptioctl;
291
292#define CDEV_MAJOR 16
293static struct cdevsw lpt_cdevsw = {
294	/* open */	lptopen,
295	/* close */	lptclose,
296	/* read */	noread,
297	/* write */	lptwrite,
298	/* ioctl */	lptioctl,
299	/* poll */	nopoll,
300	/* mmap */	nommap,
301	/* strategy */	nostrategy,
302	/* name */	"lpt",
303	/* maj */	CDEV_MAJOR,
304	/* dump */	nodump,
305	/* psize */	nopsize,
306	/* flags */	0,
307	/* bmaj */	-1
308};
309
310#ifndef PC98
311/*
312 * Internal routine to lptprobe to do port tests of one byte value
313 */
314static int
315lpt_port_test (int port, u_char data, u_char mask)
316{
317	int	temp, timeout;
318
319	data = data & mask;
320	outb(port, data);
321	timeout = 10000;
322	do {
323		DELAY(10);
324		temp = inb(port) & mask;
325	}
326	while (temp != data && --timeout);
327	lprintf(("Port 0x%x\tout=%x\tin=%x\ttout=%d\n",
328		port, data, temp, timeout));
329	return (temp == data);
330}
331#endif /* PC98 */
332
333/*
334 * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94
335 * Based partially on Rod Grimes' printer probe
336 *
337 * Logic:
338 *	1) If no port address was given, use the bios detected ports
339 *	   and autodetect what ports the printers are on.
340 *	2) Otherwise, probe the data port at the address given,
341 *	   using the method in Rod Grimes' port probe.
342 *	   (Much code ripped off directly from Rod's probe.)
343 *
344 * Comments from Rod's probe:
345 * Logic:
346 *	1) You should be able to write to and read back the same value
347 *	   to the data port.  Do an alternating zeros, alternating ones,
348 *	   walking zero, and walking one test to check for stuck bits.
349 *
350 *	2) You should be able to write to and read back the same value
351 *	   to the control port lower 5 bits, the upper 3 bits are reserved
352 *	   per the IBM PC technical reference manauls and different boards
353 *	   do different things with them.  Do an alternating zeros, alternating
354 *	   ones, walking zero, and walking one test to check for stuck bits.
355 *
356 *	   Some printers drag the strobe line down when the are powered off
357 * 	   so this bit has been masked out of the control port test.
358 *
359 *	   XXX Some printers may not like a fast pulse on init or strobe, I
360 *	   don't know at this point, if that becomes a problem these bits
361 *	   should be turned off in the mask byte for the control port test.
362 *
363 *	   We are finally left with a mask of 0x14, due to some printers
364 *	   being adamant about holding other bits high ........
365 *
366 *	   Before probing the control port, we write a 0 to the data port -
367 *	   If not, some printers chuck out garbage when the strobe line
368 *	   gets toggled.
369 *
370 *	3) Set the data and control ports to a value of 0
371 *
372 *	This probe routine has been tested on Epson Lx-800, HP LJ3P,
373 *	Epson FX-1170 and C.Itoh 8510RM
374 *	printers.
375 *	Quick exit on fail added.
376 */
377
378int
379lptprobe(struct isa_device *dvp)
380{
381#ifdef PC98
382#define PC98_OLD_LPT 0x40
383#define PC98_IEEE_1284_FUNCTION 0x149
384	unsigned int pc98_ieee_mode, tmp;
385
386	if (dvp->id_iobase == PC98_OLD_LPT) {
387		tmp = inb(PC98_IEEE_1284_FUNCTION);
388		pc98_ieee_mode = tmp;
389		if ((tmp & 0x10) == 0x10) {
390			outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10);
391			tmp = inb(PC98_IEEE_1284_FUNCTION);
392			if ((tmp & 0x10) != 0x10) {
393				outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode);
394				return 0;
395			}
396		}
397	}
398	return 8;
399#else
400	int		port;
401	static short	next_bios_lpt = 0;
402	int		status;
403	static u_char	testbyte[18] = {
404		0x55,			/* alternating zeros */
405		0xaa,			/* alternating ones */
406		0xfe, 0xfd, 0xfb, 0xf7,
407		0xef, 0xdf, 0xbf, 0x7f,	/* walking zero */
408		0x01, 0x02, 0x04, 0x08,
409		0x10, 0x20, 0x40, 0x80	/* walking one */
410	};
411	int		i;
412
413	/*
414	 * Make sure there is some way for lptopen to see that
415	 * the port is not configured
416	 * This 0 will remain if the port isn't attached
417	 */
418	(lpt_sc + dvp->id_unit)->sc_port = 0;
419
420	status = IO_LPTSIZE;
421	/* If port not specified, use bios list */
422	if(dvp->id_iobase < 0) {	/* port? */
423		if((next_bios_lpt < BIOS_MAX_LPT) &&
424				(*(BIOS_PORTS+next_bios_lpt) != 0) ) {
425			dvp->id_iobase = *(BIOS_PORTS+next_bios_lpt++);
426			goto end_probe;
427		} else
428			return (0);
429	}
430
431	/* Port was explicitly specified */
432	/* This allows probing of ports unknown to the BIOS */
433	port = dvp->id_iobase + lpt_data;
434	for (i = 0; i < 18; i++) {
435		if (!lpt_port_test(port, testbyte[i], 0xff)) {
436			status = 0;
437			goto end_probe;
438		}
439	}
440
441end_probe:
442	/* write 0's to control and data ports */
443	outb(dvp->id_iobase+lpt_data, 0);
444	outb(dvp->id_iobase+lpt_control, 0);
445
446	return (status);
447#endif
448}
449
450/* XXX Todo - try and detect if interrupt is working */
451int
452lptattach(struct isa_device *isdp)
453{
454	struct	lpt_softc	*sc;
455	int	unit;
456
457	isdp->id_ointr = lptintr;
458	unit = isdp->id_unit;
459	sc = lpt_sc + unit;
460	sc->sc_port = isdp->id_iobase;
461	sc->sc_primed = 0;	/* not primed yet */
462#ifdef PC98
463	outb(sc->sc_port+lpt_pstb_ctrl,	LPC_DIS_PSTB);	/* PSTB disable */
464	outb(sc->sc_port+lpt_control,	LPC_MODE8255);	/* 8255 mode set */
465	outb(sc->sc_port+lpt_control,	LPC_NIRQ8);	/* IRQ8 inactive */
466	outb(sc->sc_port+lpt_control,	LPC_NPSTB);	/* PSTB inactive */
467	outb(sc->sc_port+lpt_pstb_ctrl,	LPC_EN_PSTB);	/* PSTB enable */
468#else
469	outb(sc->sc_port+lpt_control, LPC_NINIT);
470#endif
471
472	/* check if we can use interrupt */
473	lprintf(("oldirq %x\n", sc->sc_irq));
474	if (isdp->id_irq) {
475		sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
476		printf("lpt%d: Interrupt-driven port\n", unit);
477#ifdef INET
478		lpattach(sc, unit);
479#endif
480	} else {
481		sc->sc_irq = 0;
482		lprintf(("lpt%d: Polled port\n", unit));
483	}
484	lprintf(("irq %x\n", sc->sc_irq));
485
486	/* XXX what to do about the flags in the minor number? */
487	make_dev(&lpt_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "lpt%d", unit);
488	make_dev(&lpt_cdevsw, unit | LP_BYPASS,
489			UID_ROOT, GID_WHEEL, 0600, "lpctl%d", unit);
490	return (1);
491}
492
493/*
494 * lptopen -- reset the printer, then wait until it's selected and not busy.
495 *	If LP_BYPASS flag is selected, then we do not try to select the
496 *	printer -- this is just used for passing ioctls.
497 */
498
499static	int
500lptopen (dev_t dev, int flags, int fmt, struct proc *p)
501{
502	struct lpt_softc *sc;
503	int s;
504#ifdef PC98
505	int port;
506#else
507	int trys, port;
508#endif
509	u_int unit = LPTUNIT(minor(dev));
510
511	sc = lpt_sc + unit;
512	if ((unit >= NOLPT) || (sc->sc_port == 0))
513		return (ENXIO);
514
515#ifdef INET
516	if (sc->sc_if.if_flags & IFF_UP)
517		return(EBUSY);
518#endif
519
520	if (sc->sc_state) {
521		lprintf(("lp: still open %x\n", sc->sc_state));
522		return(EBUSY);
523	} else
524		sc->sc_state |= INIT;
525
526	sc->sc_flags = LPTFLAGS(minor(dev));
527
528	/* Check for open with BYPASS flag set. */
529	if (sc->sc_flags & LP_BYPASS) {
530		sc->sc_state = OPEN;
531		return(0);
532	}
533
534	s = spltty();
535	lprintf(("lp flags 0x%x\n", sc->sc_flags));
536	port = sc->sc_port;
537
538	/* set IRQ status according to ENABLE_IRQ flag */
539	if (sc->sc_irq & LP_ENABLE_IRQ)
540		sc->sc_irq |= LP_USE_IRQ;
541	else
542		sc->sc_irq &= ~LP_USE_IRQ;
543
544	/* init printer */
545#ifndef PC98
546	if ((sc->sc_flags & LP_NO_PRIME) == 0) {
547		if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) {
548			outb(port+lpt_control, 0);
549			sc->sc_primed++;
550			DELAY(500);
551		}
552	}
553
554	outb (port+lpt_control, LPC_SEL|LPC_NINIT);
555
556	/* wait till ready (printer running diagnostics) */
557	trys = 0;
558	do {
559		/* ran out of waiting for the printer */
560		if (trys++ >= LPINITRDY*4) {
561			splx(s);
562			sc->sc_state = 0;
563			lprintf(("status %x\n", inb(port+lpt_status)));
564			return (EBUSY);
565		}
566
567		/* wait 1/4 second, give up if we get a signal */
568		if (tsleep ((caddr_t)sc, LPPRI|PCATCH, "lptinit", hz/4) !=
569		    EWOULDBLOCK) {
570			sc->sc_state = 0;
571			splx(s);
572			return (EBUSY);
573		}
574
575		/* is printer online and ready for output */
576	} while ((inb(port+lpt_status) & (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
577		 (LPS_SEL|LPS_NBSY|LPS_NERR));
578
579	sc->sc_control = LPC_SEL|LPC_NINIT;
580	if (sc->sc_flags & LP_AUTOLF)
581		sc->sc_control |= LPC_AUTOL;
582
583	/* enable interrupt if interrupt-driven */
584	if (sc->sc_irq & LP_USE_IRQ)
585		sc->sc_control |= LPC_ENA;
586
587	outb(port+lpt_control, sc->sc_control);
588#endif
589
590	sc->sc_state = OPEN;
591	sc->sc_inbuf = geteblk(BUFSIZE);
592	sc->sc_xfercnt = 0;
593	splx(s);
594
595	/* only use timeout if using interrupt */
596	lprintf(("irq %x\n", sc->sc_irq));
597	if (sc->sc_irq & LP_USE_IRQ) {
598		sc->sc_state |= TOUT;
599		timeout (lptout, (caddr_t)sc,
600			 (sc->sc_backoff = hz/LPTOUTINITIAL));
601	}
602
603	lprintf(("opened.\n"));
604	return(0);
605}
606
607static void
608lptout (void *arg)
609{
610	struct lpt_softc *sc = arg;
611	int pl;
612
613	lprintf(("T %x ", inb(sc->sc_port+lpt_status)));
614	if (sc->sc_state & OPEN) {
615		sc->sc_backoff++;
616		if (sc->sc_backoff > hz/LPTOUTMAX)
617			sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
618		timeout (lptout, (caddr_t)sc, sc->sc_backoff);
619	} else
620		sc->sc_state &= ~TOUT;
621
622	if (sc->sc_state & ERROR)
623		sc->sc_state &= ~ERROR;
624
625	/*
626	 * Avoid possible hangs do to missed interrupts
627	 */
628	if (sc->sc_xfercnt) {
629		pl = spltty();
630		lptintr(sc - lpt_sc);
631		splx(pl);
632	} else {
633		sc->sc_state &= ~OBUSY;
634		wakeup((caddr_t)sc);
635	}
636}
637
638/*
639 * lptclose -- close the device, free the local line buffer.
640 *
641 * Check for interrupted write call added.
642 */
643
644static	int
645lptclose(dev_t dev, int flags, int fmt, struct proc *p)
646{
647	struct lpt_softc *sc = lpt_sc + LPTUNIT(minor(dev));
648#ifndef PC98
649	int port = sc->sc_port;
650#endif
651
652	if(sc->sc_flags & LP_BYPASS)
653		goto end_close;
654
655	sc->sc_state &= ~OPEN;
656
657#ifndef PC98
658	/* if the last write was interrupted, don't complete it */
659	if((!(sc->sc_state  & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ))
660		while ((inb(port+lpt_status) & (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) !=
661			(LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt)
662			/* wait 1/4 second, give up if we get a signal */
663			if (tsleep ((caddr_t)sc, LPPRI|PCATCH,
664				"lpclose", hz) != EWOULDBLOCK)
665				break;
666
667	outb(sc->sc_port+lpt_control, LPC_NINIT);
668#endif
669	brelse(sc->sc_inbuf);
670
671end_close:
672	sc->sc_state = 0;
673	sc->sc_xfercnt = 0;
674	lprintf(("closed.\n"));
675	return(0);
676}
677
678/*
679 * pushbytes()
680 *	Workhorse for actually spinning and writing bytes to printer
681 *	Derived from lpa.c
682 *	Originally by ?
683 *
684 *	This code is only used when we are polling the port
685 */
686static int
687pushbytes(struct lpt_softc * sc)
688{
689	int spin, err, tic;
690	char ch;
691	int port = sc->sc_port;
692
693	lprintf(("p"));
694	/* loop for every character .. */
695	while (sc->sc_xfercnt > 0) {
696		/* printer data */
697		ch = *(sc->sc_cp);
698		sc->sc_cp++;
699		sc->sc_xfercnt--;
700
701		/*
702		 * Wait for printer ready.
703		 * Loop 20 usecs testing BUSY bit, then sleep
704		 * for exponentially increasing timeout. (vak)
705		 */
706		for (spin=0; NOT_READY(port+lpt_status) && spin<MAX_SPIN; ++spin)
707			DELAY(1);	/* XXX delay is NOT this accurate! */
708		if (spin >= MAX_SPIN) {
709			tic = 0;
710			while (NOT_READY(port+lpt_status)) {
711				/*
712				 * Now sleep, every cycle a
713				 * little longer ..
714				 */
715				tic = tic + tic + 1;
716				/*
717				 * But no more than 10 seconds. (vak)
718				 */
719				if (tic > MAX_SLEEP)
720					tic = MAX_SLEEP;
721				err = tsleep((caddr_t)sc, LPPRI,
722					"lptpoll", tic);
723				if (err != EWOULDBLOCK) {
724					return (err);
725				}
726			}
727		}
728
729		/* output data */
730		outb(port+lpt_data, ch);
731#ifdef PC98
732		DELAY(1);
733		outb(port+lpt_control, LPC_PSTB);
734		DELAY(1);
735		outb(port+lpt_control, LPC_NPSTB);
736#else
737		/* strobe */
738		outb(port+lpt_control, sc->sc_control|LPC_STB);
739		outb(port+lpt_control, sc->sc_control);
740#endif
741
742	}
743	return(0);
744}
745
746/*
747 * lptwrite --copy a line from user space to a local buffer, then call
748 * putc to get the chars moved to the output queue.
749 *
750 * Flagging of interrupted write added.
751 */
752
753static	int
754lptwrite(dev_t dev, struct uio * uio, int ioflag)
755{
756	register unsigned n;
757	int pl, err;
758	struct lpt_softc *sc = lpt_sc + LPTUNIT(minor(dev));
759
760	if(sc->sc_flags & LP_BYPASS) {
761		/* we can't do writes in bypass mode */
762		return(EPERM);
763	}
764
765	sc->sc_state &= ~INTERRUPTED;
766	while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
767		sc->sc_cp = sc->sc_inbuf->b_data ;
768		uiomove(sc->sc_cp, n, uio);
769		sc->sc_xfercnt = n ;
770		while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
771			lprintf(("i"));
772			/* if the printer is ready for a char, */
773			/* give it one */
774			if ((sc->sc_state & OBUSY) == 0){
775				lprintf(("\nC %d. ", sc->sc_xfercnt));
776				pl = spltty();
777				lptintr(sc - lpt_sc);
778				(void) splx(pl);
779			}
780			lprintf(("W "));
781			if (sc->sc_state & OBUSY)
782				if ((err = tsleep ((caddr_t)sc,
783					 LPPRI|PCATCH, "lpwrite", 0))) {
784					sc->sc_state |= INTERRUPTED;
785					return(err);
786				}
787		}
788		/* check to see if we must do a polled write */
789		if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
790			lprintf(("p"));
791			if((err = pushbytes(sc)))
792				return(err);
793		}
794	}
795	return(0);
796}
797
798/*
799 * lptintr -- handle printer interrupts which occur when the printer is
800 * ready to accept another char.
801 *
802 * do checking for interrupted write call.
803 */
804
805static void
806lptintr(int unit)
807{
808#if defined(INET) || !defined(PC98)
809	struct lpt_softc *sc = lpt_sc + unit;
810#endif
811#ifndef PC98
812	int port = sc->sc_port, sts;
813	int i;
814#endif
815
816#ifdef INET
817	if(sc->sc_if.if_flags & IFF_UP) {
818	    lpintr(unit);
819	    return;
820	}
821#endif /* INET */
822
823#ifndef PC98
824	/*
825	 * Is printer online and ready for output?
826	 *
827	 * Avoid falling back to lptout() too quickly.  First spin-loop
828	 * to see if the printer will become ready ``really soon now''.
829	 */
830	for (i = 0;
831	     i < 100 &&
832	     ((sts=inb(port+lpt_status)) & RDY_MASK) != LP_READY;
833	     i++) ;
834	if ((sts & RDY_MASK) == LP_READY) {
835		sc->sc_state = (sc->sc_state | OBUSY) & ~ERROR;
836		sc->sc_backoff = hz/LPTOUTINITIAL;
837
838		if (sc->sc_xfercnt) {
839			/* send char */
840			/*lprintf(("%x ", *sc->sc_cp)); */
841			outb(port+lpt_data, *sc->sc_cp++) ;
842			outb(port+lpt_control, sc->sc_control|LPC_STB);
843			/* DELAY(X) */
844			outb(port+lpt_control, 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.
853		 */
854		sc->sc_state &= ~OBUSY;
855		if(!(sc->sc_state & INTERRUPTED))
856			wakeup((caddr_t)sc);
857		lprintf(("w "));
858		return;
859	} else	{	/* check for error */
860		if(((sts & (LPS_NERR | LPS_OUT) ) != LPS_NERR) &&
861				(sc->sc_state & OPEN))
862			sc->sc_state |= ERROR;
863		/* lptout() will jump in and try to restart. */
864	}
865#endif
866	lprintf(("sts %x ", sts));
867}
868
869static	int
870lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
871{
872	int	error = 0;
873        struct	lpt_softc *sc;
874        u_int	unit = LPTUNIT(minor(dev));
875	u_char	old_sc_irq;	/* old printer IRQ status */
876
877        sc = lpt_sc + unit;
878
879	switch (cmd) {
880	case LPT_IRQ :
881		if(sc->sc_irq & LP_HAS_IRQ) {
882			/*
883			 * NOTE:
884			 * If the IRQ status is changed,
885			 * this will only be visible on the
886			 * next open.
887			 *
888			 * If interrupt status changes,
889			 * this gets syslog'd.
890			 */
891			old_sc_irq = sc->sc_irq;
892			if(*(int*)data == 0)
893				sc->sc_irq &= (~LP_ENABLE_IRQ);
894			else
895				sc->sc_irq |= LP_ENABLE_IRQ;
896			if (old_sc_irq != sc->sc_irq )
897				log(LOG_NOTICE, "lpt%c switched to %s mode\n",
898					(char)unit+'0',
899					(sc->sc_irq & LP_ENABLE_IRQ)?
900					"interrupt-driven":"polled");
901		} else /* polled port */
902			error = EOPNOTSUPP;
903		break;
904	default:
905		error = ENODEV;
906	}
907
908	return(error);
909}
910
911#ifdef INET
912
913static void
914lpattach (struct lpt_softc *sc, int unit)
915{
916	struct ifnet *ifp = &sc->sc_if;
917
918	ifp->if_softc = sc;
919	ifp->if_name = "lp";
920	ifp->if_unit = unit;
921	ifp->if_mtu = LPMTU;
922	ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
923	ifp->if_ioctl = lpioctl;
924	ifp->if_output = lpoutput;
925	ifp->if_type = IFT_PARA;
926	ifp->if_hdrlen = 0;
927	ifp->if_addrlen = 0;
928	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
929	if_attach(ifp);
930	printf("lp%d: TCP/IP capable interface\n", unit);
931
932	bpfattach(ifp, DLT_NULL, LPIPHDRLEN);
933}
934
935#ifndef PC98
936/*
937 * Build the translation tables for the LPIP (BSD unix) protocol.
938 * We don't want to calculate these nasties in our tight loop, so we
939 * precalculate them when we initialize.
940 */
941static int
942lpinittables (void)
943{
944    int i;
945
946    if (!txmith)
947	txmith = malloc(4*LPIPTBLSIZE, M_DEVBUF, M_NOWAIT);
948
949    if (!txmith)
950	return 1;
951
952    if (!ctxmith)
953	ctxmith = malloc(4*LPIPTBLSIZE, M_DEVBUF, M_NOWAIT);
954
955    if (!ctxmith)
956	return 1;
957
958    for (i=0; i < LPIPTBLSIZE; i++) {
959	ctxmith[i] = (i & 0xF0) >> 4;
960	ctxmitl[i] = 0x10 | (i & 0x0F);
961	ctrecvh[i] = (i & 0x78) << 1;
962	ctrecvl[i] = (i & 0x78) >> 3;
963    }
964
965    for (i=0; i < LPIPTBLSIZE; i++) {
966	txmith[i] = ((i & 0x80) >> 3) | ((i & 0x70) >> 4) | 0x08;
967	txmitl[i] = ((i & 0x08) << 1) | (i & 0x07);
968	trecvh[i] = ((~i) & 0x80) | ((i & 0x38) << 1);
969	trecvl[i] = (((~i) & 0x80) >> 4) | ((i & 0x38) >> 3);
970    }
971
972    return 0;
973}
974#endif /* PC98 */
975
976/*
977 * Process an ioctl request.
978 */
979
980static int
981lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
982{
983    struct lpt_softc *sc = lpt_sc + ifp->if_unit;
984    struct ifaddr *ifa = (struct ifaddr *)data;
985    struct ifreq *ifr = (struct ifreq *)data;
986    u_char *ptr;
987
988    switch (cmd) {
989
990    case SIOCSIFDSTADDR:
991    case SIOCAIFADDR:
992    case SIOCSIFADDR:
993	if (ifa->ifa_addr->sa_family != AF_INET)
994	    return EAFNOSUPPORT;
995	ifp->if_flags |= IFF_UP;
996	/* FALLTHROUGH */
997    case SIOCSIFFLAGS:
998	if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) {
999	    outb(sc->sc_port + lpt_control, 0x00);
1000	    ifp->if_flags &= ~IFF_RUNNING;
1001	    break;
1002	}
1003#ifdef PC98
1004	/* XXX */
1005	return ENOBUFS;
1006#else
1007	if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) {
1008	    if (lpinittables())
1009		return ENOBUFS;
1010	    sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN,
1011				  M_DEVBUF, M_WAITOK);
1012	    if (!sc->sc_ifbuf)
1013		return ENOBUFS;
1014
1015	    outb(sc->sc_port + lpt_control, LPC_ENA);
1016	    ifp->if_flags |= IFF_RUNNING;
1017	}
1018	break;
1019#endif
1020    case SIOCSIFMTU:
1021	ptr = sc->sc_ifbuf;
1022	sc->sc_ifbuf = malloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_NOWAIT);
1023	if (!sc->sc_ifbuf) {
1024	    sc->sc_ifbuf = ptr;
1025	    return ENOBUFS;
1026	}
1027	if (ptr)
1028	    free(ptr,M_DEVBUF);
1029	sc->sc_if.if_mtu = ifr->ifr_mtu;
1030	break;
1031
1032    case SIOCGIFMTU:
1033	ifr->ifr_mtu = sc->sc_if.if_mtu;
1034	break;
1035
1036    case SIOCADDMULTI:
1037    case SIOCDELMULTI:
1038	if (ifr == 0) {
1039	    return EAFNOSUPPORT;		/* XXX */
1040	}
1041	switch (ifr->ifr_addr.sa_family) {
1042
1043#ifdef INET
1044	case AF_INET:
1045	    break;
1046#endif
1047
1048	default:
1049	    return EAFNOSUPPORT;
1050	}
1051	break;
1052
1053    default:
1054	lprintf(("LP:ioctl(0x%lx)\n", cmd));
1055	return EINVAL;
1056    }
1057    return 0;
1058}
1059
1060static __inline int
1061clpoutbyte (u_char byte, int spin, int data_port, int status_port)
1062{
1063	outb(data_port, ctxmitl[byte]);
1064	while (inb(status_port) & CLPIP_SHAKE)
1065		if (--spin == 0) {
1066			return 1;
1067		}
1068	outb(data_port, ctxmith[byte]);
1069	while (!(inb(status_port) & CLPIP_SHAKE))
1070		if (--spin == 0) {
1071			return 1;
1072		}
1073	return 0;
1074}
1075
1076static __inline int
1077clpinbyte (int spin, int data_port, int status_port)
1078{
1079	int c, cl;
1080
1081	while((inb(status_port) & CLPIP_SHAKE))
1082	    if(!--spin) {
1083		return -1;
1084	    }
1085	cl = inb(status_port);
1086	outb(data_port, 0x10);
1087
1088	while(!(inb(status_port) & CLPIP_SHAKE))
1089	    if(!--spin) {
1090		return -1;
1091	    }
1092	c = inb(status_port);
1093	outb(data_port, 0x00);
1094
1095	return (ctrecvl[cl] | ctrecvh[c]);
1096}
1097
1098static void
1099lpintr (int unit)
1100{
1101	struct   lpt_softc *sc = lpt_sc + unit;
1102	register int lpt_data_port = sc->sc_port + lpt_data;
1103	register int lpt_stat_port = sc->sc_port + lpt_status;
1104		 int lpt_ctrl_port = sc->sc_port + lpt_control;
1105	int len, s, j;
1106	u_char *bp;
1107	u_char c, cl;
1108	struct mbuf *top;
1109
1110	s = splhigh();
1111
1112	if (sc->sc_if.if_flags & IFF_LINK0) {
1113
1114	    /* Ack. the request */
1115	    outb(lpt_data_port, 0x01);
1116
1117	    /* Get the packet length */
1118	    j = clpinbyte(LPMAXSPIN2, lpt_data_port, lpt_stat_port);
1119	    if (j == -1)
1120		goto err;
1121	    len = j;
1122	    j = clpinbyte(LPMAXSPIN2, lpt_data_port, lpt_stat_port);
1123	    if (j == -1)
1124		goto err;
1125	    len = len + (j << 8);
1126	    if (len > sc->sc_if.if_mtu + MLPIPHDRLEN)
1127		goto err;
1128
1129	    bp  = sc->sc_ifbuf;
1130
1131	    while (len--) {
1132	        j = clpinbyte(LPMAXSPIN2, lpt_data_port, lpt_stat_port);
1133	        if (j == -1) {
1134		    goto err;
1135	        }
1136	        *bp++ = j;
1137	    }
1138	    /* Get and ignore checksum */
1139	    j = clpinbyte(LPMAXSPIN2, lpt_data_port, lpt_stat_port);
1140	    if (j == -1) {
1141	        goto err;
1142	    }
1143
1144	    len = bp - sc->sc_ifbuf;
1145	    if (len <= CLPIPHDRLEN)
1146	        goto err;
1147
1148	    sc->sc_iferrs = 0;
1149
1150	    if (IF_QFULL(&ipintrq)) {
1151	        lprintf(("DROP"));
1152	        IF_DROP(&ipintrq);
1153		goto done;
1154	    }
1155	    len -= CLPIPHDRLEN;
1156	    sc->sc_if.if_ipackets++;
1157	    sc->sc_if.if_ibytes += len;
1158	    top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, &sc->sc_if, 0);
1159	    if (top) {
1160	        IF_ENQUEUE(&ipintrq, top);
1161	        schednetisr(NETISR_IP);
1162	    }
1163	    goto done;
1164	}
1165	while ((inb(lpt_stat_port) & LPIP_SHAKE)) {
1166	    len = sc->sc_if.if_mtu + LPIPHDRLEN;
1167	    bp  = sc->sc_ifbuf;
1168	    while (len--) {
1169
1170		cl = inb(lpt_stat_port);
1171		outb(lpt_data_port, 8);
1172
1173		j = LPMAXSPIN2;
1174		while((inb(lpt_stat_port) & LPIP_SHAKE))
1175		    if(!--j) goto err;
1176
1177		c = inb(lpt_stat_port);
1178		outb(lpt_data_port, 0);
1179
1180		*bp++= trecvh[cl] | trecvl[c];
1181
1182		j = LPMAXSPIN2;
1183		while (!((cl=inb(lpt_stat_port)) & LPIP_SHAKE)) {
1184		    if (cl != c &&
1185			(((cl = inb(lpt_stat_port)) ^ 0xb8) & 0xf8) ==
1186			  (c & 0xf8))
1187			goto end;
1188		    if (!--j) goto err;
1189		}
1190	    }
1191
1192	end:
1193	    len = bp - sc->sc_ifbuf;
1194	    if (len <= LPIPHDRLEN)
1195		goto err;
1196
1197	    sc->sc_iferrs = 0;
1198
1199	    if (IF_QFULL(&ipintrq)) {
1200		lprintf(("DROP"));
1201		IF_DROP(&ipintrq);
1202		goto done;
1203	    }
1204	    if (sc->sc_if.if_bpf) {
1205		bpf_tap(&sc->sc_if, sc->sc_ifbuf, len);
1206	    }
1207	    len -= LPIPHDRLEN;
1208	    sc->sc_if.if_ipackets++;
1209	    sc->sc_if.if_ibytes += len;
1210	    top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, &sc->sc_if, 0);
1211	    if (top) {
1212		    IF_ENQUEUE(&ipintrq, top);
1213		    schednetisr(NETISR_IP);
1214	    }
1215	}
1216	goto done;
1217
1218    err:
1219	outb(lpt_data_port, 0);
1220	lprintf(("R"));
1221	sc->sc_if.if_ierrors++;
1222	sc->sc_iferrs++;
1223
1224	/*
1225	 * We are not able to send receive anything for now,
1226	 * so stop wasting our time
1227	 */
1228	if (sc->sc_iferrs > LPMAXERRS) {
1229	    printf("lp%d: Too many errors, Going off-line.\n", unit);
1230	    outb(lpt_ctrl_port, 0x00);
1231	    sc->sc_if.if_flags &= ~IFF_RUNNING;
1232	    sc->sc_iferrs=0;
1233	}
1234
1235    done:
1236	splx(s);
1237	return;
1238}
1239
1240static __inline int
1241lpoutbyte (u_char byte, int spin, int data_port, int status_port)
1242{
1243    outb(data_port, txmith[byte]);
1244    while (!(inb(status_port) & LPIP_SHAKE))
1245	if (--spin == 0)
1246		return 1;
1247    outb(data_port, txmitl[byte]);
1248    while (inb(status_port) & LPIP_SHAKE)
1249	if (--spin == 0)
1250		return 1;
1251    return 0;
1252}
1253
1254static int
1255lpoutput (struct ifnet *ifp, struct mbuf *m,
1256	  struct sockaddr *dst, struct rtentry *rt)
1257{
1258    register int lpt_data_port = lpt_sc[ifp->if_unit].sc_port + lpt_data;
1259    register int lpt_stat_port = lpt_sc[ifp->if_unit].sc_port + lpt_status;
1260#ifndef PC98
1261	     int lpt_ctrl_port = lpt_sc[ifp->if_unit].sc_port + lpt_control;
1262#endif
1263
1264    int s, err;
1265    struct mbuf *mm;
1266    u_char *cp = "\0\0";
1267    u_char chksum = 0;
1268    int count = 0;
1269    int i;
1270    int spin;
1271
1272    /* We need a sensible value if we abort */
1273    cp++;
1274    ifp->if_flags |= IFF_RUNNING;
1275
1276    err = 1;			/* assume we're aborting because of an error */
1277
1278    s = splhigh();
1279
1280#ifndef PC98
1281    /* Suspend (on laptops) or receive-errors might have taken us offline */
1282    outb(lpt_ctrl_port, LPC_ENA);
1283#endif
1284
1285    if (ifp->if_flags & IFF_LINK0) {
1286
1287	if (!(inb(lpt_stat_port) & CLPIP_SHAKE)) {
1288	    lprintf(("&"));
1289	    lptintr(ifp->if_unit);
1290	}
1291
1292	/* Alert other end to pending packet */
1293	spin = LPMAXSPIN1;
1294	outb(lpt_data_port, 0x08);
1295	while ((inb(lpt_stat_port) & 0x08) == 0)
1296		if (--spin == 0) {
1297			goto nend;
1298		}
1299
1300	/* Calculate length of packet, then send that */
1301
1302	count += 14;		/* Ethernet header len */
1303
1304	mm = m;
1305	for (mm = m; mm; mm = mm->m_next) {
1306		count += mm->m_len;
1307	}
1308	if (clpoutbyte(count & 0xFF, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1309		goto nend;
1310	if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1311		goto nend;
1312
1313	/* Send dummy ethernet header */
1314	for (i = 0; i < 12; i++) {
1315		if (clpoutbyte(i, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1316			goto nend;
1317		chksum += i;
1318	}
1319
1320	if (clpoutbyte(0x08, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1321		goto nend;
1322	if (clpoutbyte(0x00, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1323		goto nend;
1324	chksum += 0x08 + 0x00;		/* Add into checksum */
1325
1326	mm = m;
1327	do {
1328		cp = mtod(mm, u_char *);
1329		while (mm->m_len--) {
1330			chksum += *cp;
1331			if (clpoutbyte(*cp++, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
1332				goto nend;
1333		}
1334	} while ((mm = mm->m_next));
1335
1336	/* Send checksum */
1337	if (clpoutbyte(chksum, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
1338		goto nend;
1339
1340	/* Go quiescent */
1341	outb(lpt_data_port, 0);
1342
1343	err = 0;			/* No errors */
1344
1345	nend:
1346	if (err)  {				/* if we didn't timeout... */
1347		ifp->if_oerrors++;
1348		lprintf(("X"));
1349	} else {
1350		ifp->if_opackets++;
1351		ifp->if_obytes += m->m_pkthdr.len;
1352	}
1353
1354	m_freem(m);
1355
1356	if (!(inb(lpt_stat_port) & CLPIP_SHAKE)) {
1357		lprintf(("^"));
1358		lptintr(ifp->if_unit);
1359	}
1360	(void) splx(s);
1361	return 0;
1362    }
1363
1364    if (inb(lpt_stat_port) & LPIP_SHAKE) {
1365        lprintf(("&"));
1366        lptintr(ifp->if_unit);
1367    }
1368
1369    if (lpoutbyte(0x08, LPMAXSPIN1, lpt_data_port, lpt_stat_port))
1370        goto end;
1371    if (lpoutbyte(0x00, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
1372        goto end;
1373
1374    mm = m;
1375    do {
1376        cp = mtod(mm,u_char *);
1377        while (mm->m_len--)
1378	    if (lpoutbyte(*cp++, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
1379	        goto end;
1380    } while ((mm = mm->m_next));
1381
1382    err = 0;				/* no errors were encountered */
1383
1384    end:
1385    --cp;
1386    outb(lpt_data_port, txmitl[*cp] ^ 0x17);
1387
1388    if (err)  {				/* if we didn't timeout... */
1389	ifp->if_oerrors++;
1390        lprintf(("X"));
1391    } else {
1392	ifp->if_opackets++;
1393	ifp->if_obytes += m->m_pkthdr.len;
1394	if (ifp->if_bpf) {
1395	    /*
1396	     * We need to prepend the packet type as
1397	     * a two byte field.  Cons up a dummy header
1398	     * to pacify bpf.  This is safe because bpf
1399	     * will only read from the mbuf (i.e., it won't
1400	     * try to free it or keep a pointer to it).
1401	     */
1402	    struct mbuf m0;
1403	    u_short hdr = 0x800;
1404
1405	    m0.m_next = m;
1406	    m0.m_len = 2;
1407	    m0.m_data = (char *)&hdr;
1408
1409	    bpf_mtap(ifp, &m0);
1410	}
1411    }
1412
1413    m_freem(m);
1414
1415    if (inb(lpt_stat_port) & LPIP_SHAKE) {
1416	lprintf(("^"));
1417	lptintr(ifp->if_unit);
1418    }
1419
1420    (void) splx(s);
1421    return 0;
1422}
1423
1424#endif /* INET */
1425
1426static int lpt_devsw_installed;
1427
1428static void 	lpt_drvinit(void *unused)
1429{
1430
1431	if( ! lpt_devsw_installed ) {
1432		cdevsw_add(&lpt_cdevsw);
1433		lpt_devsw_installed = 1;
1434    	}
1435}
1436
1437SYSINIT(lptdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,lpt_drvinit,NULL)
1438
1439