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