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