241}; 242 243static bus_addr_t lpt_iat[] = {0, 2, 4, 6}; 244 245#ifndef PC98 246/* 247 * Internal routine to lptprobe to do port tests of one byte value 248 */ 249static int 250lpt_port_test (int port, u_char data, u_char mask) 251{ 252 int temp, timeout; 253 254 data = data & mask; 255 outb(port, data); 256 timeout = 10000; 257 do { 258 DELAY(10); 259 temp = inb(port) & mask; 260 } 261 while (temp != data && --timeout); 262 lprintf(("Port 0x%x\tout=%x\tin=%x\ttout=%d\n", 263 port, data, temp, timeout)); 264 return (temp == data); 265} 266#endif /* PC98 */ 267 268/* 269 * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94 270 * Based partially on Rod Grimes' printer probe 271 * 272 * Logic: 273 * 1) If no port address was given, use the bios detected ports 274 * and autodetect what ports the printers are on. 275 * 2) Otherwise, probe the data port at the address given, 276 * using the method in Rod Grimes' port probe. 277 * (Much code ripped off directly from Rod's probe.) 278 * 279 * Comments from Rod's probe: 280 * Logic: 281 * 1) You should be able to write to and read back the same value 282 * to the data port. Do an alternating zeros, alternating ones, 283 * walking zero, and walking one test to check for stuck bits. 284 * 285 * 2) You should be able to write to and read back the same value 286 * to the control port lower 5 bits, the upper 3 bits are reserved 287 * per the IBM PC technical reference manauls and different boards 288 * do different things with them. Do an alternating zeros, alternating 289 * ones, walking zero, and walking one test to check for stuck bits. 290 * 291 * Some printers drag the strobe line down when the are powered off 292 * so this bit has been masked out of the control port test. 293 * 294 * XXX Some printers may not like a fast pulse on init or strobe, I 295 * don't know at this point, if that becomes a problem these bits 296 * should be turned off in the mask byte for the control port test. 297 * 298 * We are finally left with a mask of 0x14, due to some printers 299 * being adamant about holding other bits high ........ 300 * 301 * Before probing the control port, we write a 0 to the data port - 302 * If not, some printers chuck out garbage when the strobe line 303 * gets toggled. 304 * 305 * 3) Set the data and control ports to a value of 0 306 * 307 * This probe routine has been tested on Epson Lx-800, HP LJ3P, 308 * Epson FX-1170 and C.Itoh 8510RM 309 * printers. 310 * Quick exit on fail added. 311 */ 312 313int 314lpt_probe(device_t dev) 315{ 316#ifdef PC98 317#define PC98_OLD_LPT 0x40 318#define PC98_IEEE_1284_FUNCTION 0x149 319 int rid; 320 struct resource *res; 321 322 /* Check isapnp ids */ 323 if (isa_get_vendorid(dev)) 324 return ENXIO; 325 326 rid = 0; 327 res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4, 328 RF_ACTIVE); 329 if (res == NULL) 330 return ENXIO; 331 isa_load_resourcev(res, lpt_iat, 4); 332 333 if (isa_get_port(dev) == PC98_OLD_LPT) { 334 unsigned int pc98_ieee_mode, tmp; 335 336 tmp = inb(PC98_IEEE_1284_FUNCTION); 337 pc98_ieee_mode = tmp; 338 if ((tmp & 0x10) == 0x10) { 339 outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10); 340 tmp = inb(PC98_IEEE_1284_FUNCTION); 341 if ((tmp & 0x10) != 0x10) { 342 outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode); 343 bus_release_resource(dev, SYS_RES_IOPORT, rid, 344 res); 345 return ENXIO; 346 } 347 } 348 } 349 350 bus_release_resource(dev, SYS_RES_IOPORT, rid, res); 351 return 0; 352#else 353 int port; 354 static short next_bios_lpt = 0; 355 int status; 356 static u_char testbyte[18] = { 357 0x55, /* alternating zeros */ 358 0xaa, /* alternating ones */ 359 0xfe, 0xfd, 0xfb, 0xf7, 360 0xef, 0xdf, 0xbf, 0x7f, /* walking zero */ 361 0x01, 0x02, 0x04, 0x08, 362 0x10, 0x20, 0x40, 0x80 /* walking one */ 363 }; 364 int i; 365 366 /* 367 * Make sure there is some way for lptopen to see that 368 * the port is not configured 369 * This 0 will remain if the port isn't attached 370 */ 371 (lpt_sc + dvp->id_unit)->sc_port = 0; 372 373 status = IO_LPTSIZE; 374 /* If port not specified, use bios list */ 375 if(dvp->id_iobase < 0) { /* port? */ 376 if((next_bios_lpt < BIOS_MAX_LPT) && 377 (*(BIOS_PORTS+next_bios_lpt) != 0) ) { 378 dvp->id_iobase = *(BIOS_PORTS+next_bios_lpt++); 379 goto end_probe; 380 } else 381 return (0); 382 } 383 384 /* Port was explicitly specified */ 385 /* This allows probing of ports unknown to the BIOS */ 386 port = dvp->id_iobase + lpt_data; 387 for (i = 0; i < 18; i++) { 388 if (!lpt_port_test(port, testbyte[i], 0xff)) { 389 status = 0; 390 goto end_probe; 391 } 392 } 393 394end_probe: 395 /* write 0's to control and data ports */ 396 outb(dvp->id_iobase+lpt_data, 0); 397 outb(dvp->id_iobase+lpt_control, 0); 398 399 return (status); 400#endif 401} 402 403/* XXX Todo - try and detect if interrupt is working */ 404int 405lpt_attach(device_t dev) 406{ 407 int rid, unit; 408 struct lpt_softc *sc; 409 410 unit = device_get_unit(dev); 411 sc = device_get_softc(dev); 412 413 rid = 0; 414 sc->res_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, 415 lpt_iat, 4, RF_ACTIVE); 416 if (sc->res_port == NULL) 417 return ENXIO; 418 isa_load_resourcev(sc->res_port, lpt_iat, 4); 419 420 sc->sc_port = rman_get_start(sc->res_port); 421 sc->sc_primed = 0; /* not primed yet */ 422#ifdef PC98 423 outb(sc->sc_port+lpt_pstb_ctrl, LPC_DIS_PSTB); /* PSTB disable */ 424 outb(sc->sc_port+lpt_control, LPC_MODE8255); /* 8255 mode set */ 425 outb(sc->sc_port+lpt_control, LPC_NIRQ8); /* IRQ8 inactive */ 426 outb(sc->sc_port+lpt_control, LPC_NPSTB); /* PSTB inactive */ 427 outb(sc->sc_port+lpt_pstb_ctrl, LPC_EN_PSTB); /* PSTB enable */ 428#else 429 outb(sc->sc_port+lpt_control, LPC_NINIT); 430#endif 431 432 sc->sc_irq = 0; 433 if (isa_get_irq(dev) != -1) { 434 rid = 0; 435 sc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 436 0, ~0, 1, RF_ACTIVE); 437 if (sc->res_irq == NULL) { 438 bus_release_resource(dev, SYS_RES_IOPORT, 0, 439 sc->res_port); 440 return ENXIO; 441 } 442 if (bus_setup_intr(dev, sc->res_irq, INTR_TYPE_TTY, lpt_intr, 443 sc, &sc->sc_ih)) { 444 bus_release_resource(dev, SYS_RES_IOPORT, 0, 445 sc->res_port); 446 bus_release_resource(dev, SYS_RES_IRQ, 0, 447 sc->res_irq); 448 return ENXIO; 449 } 450 sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ; 451 device_printf(dev, "Interrupt-driven port"); 452 } 453 454 /* XXX what to do about the flags in the minor number? */ 455 make_dev(&lpt_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "lpt%d", unit); 456 make_dev(&lpt_cdevsw, unit | LP_BYPASS, 457 UID_ROOT, GID_WHEEL, 0600, "lpctl%d", unit); 458 459 return 0; 460} 461 462/* 463 * lptopen -- reset the printer, then wait until it's selected and not busy. 464 * If LP_BYPASS flag is selected, then we do not try to select the 465 * printer -- this is just used for passing ioctls. 466 */ 467 468static int 469lptopen (dev_t dev, int flags, int fmt, struct thread *td) 470{ 471 struct lpt_softc *sc; 472 int s; 473#ifdef PC98 474 int port; 475#else 476 int trys, port; 477#endif 478 479 sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev))); 480 if (sc->sc_port == 0) 481 return (ENXIO); 482 483 if (sc->sc_state) { 484 lprintf(("lp: still open %x\n", sc->sc_state)); 485 return(EBUSY); 486 } else 487 sc->sc_state |= INIT; 488 489 sc->sc_flags = LPTFLAGS(minor(dev)); 490 491 /* Check for open with BYPASS flag set. */ 492 if (sc->sc_flags & LP_BYPASS) { 493 sc->sc_state = OPEN; 494 return(0); 495 } 496 497 s = spltty(); 498 lprintf(("lp flags 0x%x\n", sc->sc_flags)); 499 port = sc->sc_port; 500 501 /* set IRQ status according to ENABLE_IRQ flag */ 502 if (sc->sc_irq & LP_ENABLE_IRQ) 503 sc->sc_irq |= LP_USE_IRQ; 504 else 505 sc->sc_irq &= ~LP_USE_IRQ; 506 507 /* init printer */ 508#ifndef PC98 509 if ((sc->sc_flags & LP_NO_PRIME) == 0) { 510 if((sc->sc_flags & LP_PRIMEOPEN) || sc->sc_primed == 0) { 511 outb(port+lpt_control, 0); 512 sc->sc_primed++; 513 DELAY(500); 514 } 515 } 516 517 outb (port+lpt_control, LPC_SEL|LPC_NINIT); 518 519 /* wait till ready (printer running diagnostics) */ 520 trys = 0; 521 do { 522 /* ran out of waiting for the printer */ 523 if (trys++ >= LPINITRDY*4) { 524 splx(s); 525 sc->sc_state = 0; 526 lprintf(("status %x\n", inb(port+lpt_status))); 527 return (EBUSY); 528 } 529 530 /* wait 1/4 second, give up if we get a signal */ 531 if (tsleep (sc, LPPRI|PCATCH, "lptinit", hz/4) != 532 EWOULDBLOCK) { 533 sc->sc_state = 0; 534 splx(s); 535 return (EBUSY); 536 } 537 538 /* is printer online and ready for output */ 539 } while ((inb(port+lpt_status) & (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) != 540 (LPS_SEL|LPS_NBSY|LPS_NERR)); 541 542 sc->sc_control = LPC_SEL|LPC_NINIT; 543 if (sc->sc_flags & LP_AUTOLF) 544 sc->sc_control |= LPC_AUTOL; 545 546 /* enable interrupt if interrupt-driven */ 547 if (sc->sc_irq & LP_USE_IRQ) 548 sc->sc_control |= LPC_ENA; 549 550 outb(port+lpt_control, sc->sc_control); 551#endif 552 553 sc->sc_state = OPEN; 554 sc->sc_inbuf = geteblk(BUFSIZE); 555 sc->sc_xfercnt = 0; 556 splx(s); 557 558 /* only use timeout if using interrupt */ 559 lprintf(("irq %x\n", sc->sc_irq)); 560 if (sc->sc_irq & LP_USE_IRQ) { 561 sc->sc_state |= TOUT; 562 timeout (lptout, (caddr_t)sc, 563 (sc->sc_backoff = hz/LPTOUTINITIAL)); 564 } 565 566 lprintf(("opened.\n")); 567 return(0); 568} 569 570static void 571lptout (void *arg) 572{ 573 struct lpt_softc *sc = arg; 574 int pl; 575 576 lprintf(("T %x ", inb(sc->sc_port+lpt_status))); 577 if (sc->sc_state & OPEN) { 578 sc->sc_backoff++; 579 if (sc->sc_backoff > hz/LPTOUTMAX) 580 sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX; 581 timeout (lptout, (caddr_t)sc, sc->sc_backoff); 582 } else 583 sc->sc_state &= ~TOUT; 584 585 if (sc->sc_state & ERROR) 586 sc->sc_state &= ~ERROR; 587 588 /* 589 * Avoid possible hangs do to missed interrupts 590 */ 591 if (sc->sc_xfercnt) { 592 pl = spltty(); 593 lpt_intr(sc); 594 splx(pl); 595 } else { 596 sc->sc_state &= ~OBUSY; 597 wakeup(sc); 598 } 599} 600 601/* 602 * lptclose -- close the device, free the local line buffer. 603 * 604 * Check for interrupted write call added. 605 */ 606 607static int 608lptclose(dev_t dev, int flags, int fmt, struct thread *td) 609{ 610 struct lpt_softc *sc; 611#ifndef PC98 612 int port; 613#endif 614 615 sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev))); 616 if(sc->sc_flags & LP_BYPASS) 617 goto end_close; 618 619#ifndef PC98 620 port = sc->sc_port; 621#endif 622 sc->sc_state &= ~OPEN; 623 624#ifndef PC98 625 /* if the last write was interrupted, don't complete it */ 626 if((!(sc->sc_state & INTERRUPTED)) && (sc->sc_irq & LP_USE_IRQ)) 627 while ((inb(port+lpt_status) & (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR)) != 628 (LPS_SEL|LPS_NBSY|LPS_NERR) || sc->sc_xfercnt) 629 /* wait 1/4 second, give up if we get a signal */ 630 if (tsleep (sc, LPPRI|PCATCH, 631 "lpclose", hz) != EWOULDBLOCK) 632 break; 633 634 outb(sc->sc_port+lpt_control, LPC_NINIT); 635#endif 636 brelse(sc->sc_inbuf); 637 638end_close: 639 sc->sc_state = 0; 640 sc->sc_xfercnt = 0; 641 lprintf(("closed.\n")); 642 return(0); 643} 644 645/* 646 * pushbytes() 647 * Workhorse for actually spinning and writing bytes to printer 648 * Derived from lpa.c 649 * Originally by ? 650 * 651 * This code is only used when we are polling the port 652 */ 653static int 654pushbytes(struct lpt_softc * sc) 655{ 656 int spin, err, tic; 657 char ch; 658 int port = sc->sc_port; 659 660 lprintf(("p")); 661 /* loop for every character .. */ 662 while (sc->sc_xfercnt > 0) { 663 /* printer data */ 664 ch = *(sc->sc_cp); 665 sc->sc_cp++; 666 sc->sc_xfercnt--; 667 668 /* 669 * Wait for printer ready. 670 * Loop 20 usecs testing BUSY bit, then sleep 671 * for exponentially increasing timeout. (vak) 672 */ 673 for (spin=0; NOT_READY(port+lpt_status) && spin<MAX_SPIN; ++spin) 674 DELAY(1); /* XXX delay is NOT this accurate! */ 675 if (spin >= MAX_SPIN) { 676 tic = 0; 677 while (NOT_READY(port+lpt_status)) { 678 /* 679 * Now sleep, every cycle a 680 * little longer .. 681 */ 682 tic = tic + tic + 1; 683 /* 684 * But no more than 10 seconds. (vak) 685 */ 686 if (tic > MAX_SLEEP) 687 tic = MAX_SLEEP; 688 err = tsleep(sc, LPPRI, 689 "lptpoll", tic); 690 if (err != EWOULDBLOCK) { 691 return (err); 692 } 693 } 694 } 695 696 /* output data */ 697 outb(port+lpt_data, ch); 698#ifdef PC98 699 DELAY(1); 700 outb(port+lpt_control, LPC_PSTB); 701 DELAY(1); 702 outb(port+lpt_control, LPC_NPSTB); 703#else 704 /* strobe */ 705 outb(port+lpt_control, sc->sc_control|LPC_STB); 706 outb(port+lpt_control, sc->sc_control); 707#endif 708 709 } 710 return(0); 711} 712 713/* 714 * lptwrite --copy a line from user space to a local buffer, then call 715 * putc to get the chars moved to the output queue. 716 * 717 * Flagging of interrupted write added. 718 */ 719 720static int 721lptwrite(dev_t dev, struct uio * uio, int ioflag) 722{ 723 register unsigned n; 724 int pl, err; 725 struct lpt_softc *sc; 726 727 sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev))); 728 if(sc->sc_flags & LP_BYPASS) { 729 /* we can't do writes in bypass mode */ 730 return(EPERM); 731 } 732 733 sc->sc_state &= ~INTERRUPTED; 734 while ((n = min(BUFSIZE, uio->uio_resid)) != 0) { 735 sc->sc_cp = sc->sc_inbuf->b_data ; 736 uiomove(sc->sc_cp, n, uio); 737 sc->sc_xfercnt = n ; 738 while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) { 739 lprintf(("i")); 740 /* if the printer is ready for a char, */ 741 /* give it one */ 742 if ((sc->sc_state & OBUSY) == 0){ 743 lprintf(("\nC %d. ", sc->sc_xfercnt)); 744 pl = spltty(); 745 lpt_intr(sc); 746 (void) splx(pl); 747 } 748 lprintf(("W ")); 749 if (sc->sc_state & OBUSY) 750 if ((err = tsleep (sc, 751 LPPRI|PCATCH, "lpwrite", 0))) { 752 sc->sc_state |= INTERRUPTED; 753 return(err); 754 } 755 } 756 /* check to see if we must do a polled write */ 757 if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) { 758 lprintf(("p")); 759 if((err = pushbytes(sc))) 760 return(err); 761 } 762 } 763 return(0); 764} 765 766/* 767 * lptintr -- handle printer interrupts which occur when the printer is 768 * ready to accept another char. 769 * 770 * do checking for interrupted write call. 771 */ 772 773static void 774lpt_intr(void *arg) 775{ 776} 777 778static int 779lptioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td) 780{ 781 int error = 0; 782 struct lpt_softc *sc; 783 u_int unit = LPTUNIT(minor(dev)); 784 u_char old_sc_irq; /* old printer IRQ status */ 785 786 sc = devclass_get_softc(olpt_devclass, unit); 787 788 switch (cmd) { 789 case LPT_IRQ : 790 if(sc->sc_irq & LP_HAS_IRQ) { 791 /* 792 * NOTE: 793 * If the IRQ status is changed, 794 * this will only be visible on the 795 * next open. 796 * 797 * If interrupt status changes, 798 * this gets syslog'd. 799 */ 800 old_sc_irq = sc->sc_irq; 801 if(*(int*)data == 0) 802 sc->sc_irq &= (~LP_ENABLE_IRQ); 803 else 804 sc->sc_irq |= LP_ENABLE_IRQ; 805 if (old_sc_irq != sc->sc_irq ) 806 log(LOG_NOTICE, "lpt%c switched to %s mode\n", 807 (char)unit+'0', 808 (sc->sc_irq & LP_ENABLE_IRQ)? 809 "interrupt-driven":"polled"); 810 } else /* polled port */ 811 error = EOPNOTSUPP; 812 break; 813 default: 814 error = ENODEV; 815 } 816 817 return(error); 818}
|