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