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