ppb_1284.c revision 55939
1/*- 2 * Copyright (c) 1997 Nicolas Souchu 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 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/ppbus/ppb_1284.c 55939 2000-01-14 00:18:06Z nsouch $ 27 * 28 */ 29 30/* 31 * General purpose routines for the IEEE1284-1994 Standard 32 */ 33 34#include "opt_ppb_1284.h" 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/bus.h> 39 40#include <machine/clock.h> 41 42#include <dev/ppbus/ppbconf.h> 43#include <dev/ppbus/ppb_1284.h> 44 45#include "ppbus_if.h" 46 47#include <dev/ppbus/ppbio.h> 48 49#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) 50 51/* 52 * do_1284_wait() 53 * 54 * Wait for the peripherial up to 40ms 55 */ 56static int 57do_1284_wait(device_t bus, char mask, char status) 58{ 59 return (ppb_poll_bus(bus, 4, mask, status, PPB_NOINTR | PPB_POLL)); 60} 61 62static int 63do_peripheral_wait(device_t bus, char mask, char status) 64{ 65 return (ppb_poll_bus(bus, 100, mask, status, PPB_NOINTR | PPB_POLL)); 66} 67 68#define nibble2char(s) (((s & ~nACK) >> 3) | (~s & nBUSY) >> 4) 69 70/* 71 * ppb_1284_reset_error() 72 * 73 * Unconditionaly reset the error field 74 */ 75static int 76ppb_1284_reset_error(device_t bus, int state) 77{ 78 struct ppb_data *ppb = DEVTOSOFTC(bus); 79 80 ppb->error = PPB_NO_ERROR; 81 ppb->state = state; 82 83 return (0); 84} 85 86/* 87 * ppb_1284_get_state() 88 * 89 * Get IEEE1284 state 90 */ 91static int 92ppb_1284_get_state(device_t bus) 93{ 94 return (DEVTOSOFTC(bus)->state); 95} 96 97/* 98 * ppb_1284_set_state() 99 * 100 * Change IEEE1284 state if no error occured 101 */ 102static int 103ppb_1284_set_state(device_t bus, int state) 104{ 105 struct ppb_data *ppb = DEVTOSOFTC(bus); 106 107 /* call ppb_1284_reset_error() if you absolutly want to change 108 * the state from PPB_ERROR to another */ 109 if ((ppb->state != PPB_ERROR) && 110 (ppb->error == PPB_NO_ERROR)) { 111 ppb->state = state; 112 ppb->error = PPB_NO_ERROR; 113 } 114 115 return (0); 116} 117 118static int 119ppb_1284_set_error(device_t bus, int error, int event) 120{ 121 struct ppb_data *ppb = DEVTOSOFTC(bus); 122 123 /* do not accumulate errors */ 124 if ((ppb->error == PPB_NO_ERROR) && 125 (ppb->state != PPB_ERROR)) { 126 ppb->error = error; 127 ppb->state = PPB_ERROR; 128 } 129 130#ifdef DEBUG_1284 131 printf("ppb1284: error=%d status=0x%x event=%d\n", error, 132 ppb_rstr(bus) & 0xff, event); 133#endif 134 135 return (0); 136} 137 138/* 139 * ppb_request_mode() 140 * 141 * Converts mode+options into ext. value 142 */ 143static int 144ppb_request_mode(int mode, int options) 145{ 146 int request_mode = 0; 147 148 if (options & PPB_EXTENSIBILITY_LINK) { 149 request_mode = EXT_LINK_1284_NORMAL; 150 151 } else { 152 switch (mode) { 153 case PPB_NIBBLE: 154 request_mode = (options & PPB_REQUEST_ID) ? 155 NIBBLE_1284_REQUEST_ID : 156 NIBBLE_1284_NORMAL; 157 break; 158 case PPB_PS2: 159 request_mode = (options & PPB_REQUEST_ID) ? 160 BYTE_1284_REQUEST_ID : 161 BYTE_1284_NORMAL; 162 break; 163 case PPB_ECP: 164 if (options & PPB_USE_RLE) 165 request_mode = (options & PPB_REQUEST_ID) ? 166 ECP_1284_RLE_REQUEST_ID : 167 ECP_1284_RLE; 168 else 169 request_mode = (options & PPB_REQUEST_ID) ? 170 ECP_1284_REQUEST_ID : 171 ECP_1284_NORMAL; 172 break; 173 case PPB_EPP: 174 request_mode = EPP_1284_NORMAL; 175 break; 176 default: 177 panic("%s: unsupported mode %d\n", __FUNCTION__, mode); 178 } 179 } 180 181 return (request_mode); 182} 183 184/* 185 * ppb_peripheral_negociate() 186 * 187 * Negociate the peripheral side 188 */ 189int 190ppb_peripheral_negociate(device_t bus, int mode, int options) 191{ 192 int spin, request_mode, error = 0; 193 char r; 194 195 ppb_set_mode(bus, PPB_COMPATIBLE); 196 ppb_1284_set_state(bus, PPB_PERIPHERAL_NEGOCIATION); 197 198 /* compute ext. value */ 199 request_mode = ppb_request_mode(mode, options); 200 201 /* wait host */ 202 spin = 10; 203 while (spin-- && (ppb_rstr(bus) & nBUSY)) 204 DELAY(1); 205 206 /* check termination */ 207 if (!(ppb_rstr(bus) & SELECT) || !spin) { 208 error = ENODEV; 209 goto error; 210 } 211 212 /* Event 4 - read ext. value */ 213 r = ppb_rdtr(bus); 214 215 /* nibble mode is not supported */ 216 if ((r == (char)request_mode) || 217 (r == NIBBLE_1284_NORMAL)) { 218 219 /* Event 5 - restore direction bit, no data avail */ 220 ppb_wctr(bus, (STROBE | nINIT) & ~(SELECTIN)); 221 DELAY(1); 222 223 /* Event 6 */ 224 ppb_wctr(bus, (nINIT) & ~(SELECTIN | STROBE)); 225 226 if (r == NIBBLE_1284_NORMAL) { 227#ifdef DEBUG_1284 228 printf("R"); 229#endif 230 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4); 231 error = EINVAL; 232 goto error; 233 } else { 234 ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE); 235 switch (r) { 236 case BYTE_1284_NORMAL: 237 ppb_set_mode(bus, PPB_BYTE); 238 break; 239 default: 240 break; 241 } 242#ifdef DEBUG_1284 243 printf("A"); 244#endif 245 /* negociation succeeds */ 246 } 247 } else { 248 /* Event 5 - mode not supported */ 249 ppb_wctr(bus, SELECTIN); 250 DELAY(1); 251 252 /* Event 6 */ 253 ppb_wctr(bus, (SELECTIN) & ~(STROBE | nINIT)); 254 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4); 255 256#ifdef DEBUG_1284 257 printf("r"); 258#endif 259 error = EINVAL; 260 goto error; 261 } 262 263 return (0); 264 265error: 266 ppb_peripheral_terminate(bus, PPB_WAIT); 267 return (error); 268} 269 270/* 271 * ppb_peripheral_terminate() 272 * 273 * Terminate peripheral transfer side 274 * 275 * Always return 0 in compatible mode 276 */ 277int 278ppb_peripheral_terminate(device_t bus, int how) 279{ 280 int error = 0; 281 282#ifdef DEBUG_1284 283 printf("t"); 284#endif 285 286 ppb_1284_set_state(bus, PPB_PERIPHERAL_TERMINATION); 287 288 /* Event 22 - wait up to host response time (1s) */ 289 if ((error = do_peripheral_wait(bus, SELECT | nBUSY, 0))) { 290 ppb_1284_set_error(bus, PPB_TIMEOUT, 22); 291 goto error; 292 } 293 294 /* Event 24 */ 295 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN)); 296 297 /* Event 25 - wait up to host response time (1s) */ 298 if ((error = do_peripheral_wait(bus, nBUSY, nBUSY))) { 299 ppb_1284_set_error(bus, PPB_TIMEOUT, 25); 300 goto error; 301 } 302 303 /* Event 26 */ 304 ppb_wctr(bus, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED)); 305 DELAY(1); 306 /* Event 27 */ 307 ppb_wctr(bus, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED)); 308 309 /* Event 28 - wait up to host response time (1s) */ 310 if ((error = do_peripheral_wait(bus, nBUSY, 0))) { 311 ppb_1284_set_error(bus, PPB_TIMEOUT, 28); 312 goto error; 313 } 314 315error: 316 ppb_set_mode(bus, PPB_COMPATIBLE); 317 ppb_1284_set_state(bus, PPB_FORWARD_IDLE); 318 319 return (0); 320} 321 322/* 323 * byte_peripheral_outbyte() 324 * 325 * Write 1 byte in BYTE mode 326 */ 327static int 328byte_peripheral_outbyte(device_t bus, char *buffer, int last) 329{ 330 int error = 0; 331 332 /* Event 7 */ 333 if ((error = do_1284_wait(bus, nBUSY, nBUSY))) { 334 ppb_1284_set_error(bus, PPB_TIMEOUT, 7); 335 goto error; 336 } 337 338 /* check termination */ 339 if (!(ppb_rstr(bus) & SELECT)) { 340 ppb_peripheral_terminate(bus, PPB_WAIT); 341 goto error; 342 } 343 344 /* Event 15 - put byte on data lines */ 345#ifdef DEBUG_1284 346 printf("B"); 347#endif 348 ppb_wdtr(bus, *buffer); 349 350 /* Event 9 */ 351 ppb_wctr(bus, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN)); 352 353 /* Event 10 - wait data read */ 354 if ((error = do_peripheral_wait(bus, nBUSY, 0))) { 355 ppb_1284_set_error(bus, PPB_TIMEOUT, 16); 356 goto error; 357 } 358 359 /* Event 11 */ 360 if (!last) { 361 ppb_wctr(bus, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN)); 362 } else { 363 ppb_wctr(bus, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED)); 364 } 365 366#if 0 367 /* Event 16 - wait strobe */ 368 if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) { 369 ppb_1284_set_error(bus, PPB_TIMEOUT, 16); 370 goto error; 371 } 372#endif 373 374 /* check termination */ 375 if (!(ppb_rstr(bus) & SELECT)) { 376 ppb_peripheral_terminate(bus, PPB_WAIT); 377 goto error; 378 } 379 380error: 381 return (error); 382} 383 384/* 385 * byte_peripheral_write() 386 * 387 * Write n bytes in BYTE mode 388 */ 389int 390byte_peripheral_write(device_t bus, char *buffer, int len, int *sent) 391{ 392 int error = 0, i; 393 char r; 394 395 ppb_1284_set_state(bus, PPB_PERIPHERAL_TRANSFER); 396 397 /* wait forever, the remote host is master and should initiate 398 * termination 399 */ 400 for (i=0; i<len; i++) { 401 /* force remote nFAULT low to release the remote waiting 402 * process, if any 403 */ 404 r = ppb_rctr(bus); 405 ppb_wctr(bus, r & ~nINIT); 406 407#ifdef DEBUG_1284 408 printf("y"); 409#endif 410 /* Event 7 */ 411 error = ppb_poll_bus(bus, PPB_FOREVER, nBUSY, nBUSY, 412 PPB_INTR); 413 414 if (error && error != EWOULDBLOCK) 415 goto error; 416 417#ifdef DEBUG_1284 418 printf("b"); 419#endif 420 if ((error = byte_peripheral_outbyte(bus, buffer+i, (i == len-1)))) 421 goto error; 422 } 423error: 424 if (!error) 425 ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE); 426 427 *sent = i; 428 return (error); 429} 430 431/* 432 * byte_1284_inbyte() 433 * 434 * Read 1 byte in BYTE mode 435 */ 436int 437byte_1284_inbyte(device_t bus, char *buffer) 438{ 439 int error = 0; 440 441 /* Event 7 - ready to take data (nAUTO low) */ 442 ppb_wctr(bus, (PCD | nINIT | AUTOFEED) & ~(STROBE | SELECTIN)); 443 444 /* Event 9 - peripheral set nAck low */ 445 if ((error = do_1284_wait(bus, nACK, 0))) { 446 ppb_1284_set_error(bus, PPB_TIMEOUT, 9); 447 goto error; 448 } 449 450 /* read the byte */ 451 *buffer = ppb_rdtr(bus); 452 453 /* Event 10 - data received, can't accept more */ 454 ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN)); 455 456 /* Event 11 - peripheral ack */ 457 if ((error = do_1284_wait(bus, nACK, nACK))) { 458 ppb_1284_set_error(bus, PPB_TIMEOUT, 11); 459 goto error; 460 } 461 462 /* Event 16 - strobe */ 463 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN)); 464 DELAY(3); 465 ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN)); 466 467error: 468 return (error); 469} 470 471/* 472 * nibble_1284_inbyte() 473 * 474 * Read 1 byte in NIBBLE mode 475 */ 476int 477nibble_1284_inbyte(device_t bus, char *buffer) 478{ 479 char nibble[2]; 480 int i, error; 481 482 for (i = 0; i < 2; i++) { 483 484 /* Event 7 - ready to take data (nAUTO low) */ 485 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN)); 486 487 /* Event 8 - peripheral writes the first nibble */ 488 489 /* Event 9 - peripheral set nAck low */ 490 if ((error = do_1284_wait(bus, nACK, 0))) { 491 ppb_1284_set_error(bus, PPB_TIMEOUT, 9); 492 goto error; 493 } 494 495 /* read nibble */ 496 nibble[i] = ppb_rstr(bus); 497 498 /* Event 10 - ack, nibble received */ 499 ppb_wctr(bus, nINIT & ~(AUTOFEED | STROBE | SELECTIN)); 500 501 /* Event 11 - wait ack from peripherial */ 502 if ((error = do_1284_wait(bus, nACK, nACK))) { 503 ppb_1284_set_error(bus, PPB_TIMEOUT, 11); 504 goto error; 505 } 506 } 507 508 *buffer = ((nibble2char(nibble[1]) << 4) & 0xf0) | 509 (nibble2char(nibble[0]) & 0x0f); 510 511error: 512 return (error); 513} 514 515/* 516 * spp_1284_read() 517 * 518 * Read in IEEE1284 NIBBLE/BYTE mode 519 */ 520int 521spp_1284_read(device_t bus, int mode, char *buffer, int max, int *read) 522{ 523 int error = 0, len = 0; 524 int terminate_after_transfer = 1; 525 int state; 526 527 *read = len = 0; 528 529 state = ppb_1284_get_state(bus); 530 531 switch (state) { 532 case PPB_FORWARD_IDLE: 533 if ((error = ppb_1284_negociate(bus, mode, 0))) 534 return (error); 535 break; 536 537 case PPB_REVERSE_IDLE: 538 terminate_after_transfer = 0; 539 break; 540 541 default: 542 ppb_1284_terminate(bus); 543 if ((error = ppb_1284_negociate(bus, mode, 0))) 544 return (error); 545 break; 546 } 547 548 while ((len < max) && !(ppb_rstr(bus) & (nFAULT))) { 549 550 ppb_1284_set_state(bus, PPB_REVERSE_TRANSFER); 551 552#ifdef DEBUG_1284 553 printf("B"); 554#endif 555 556 switch (mode) { 557 case PPB_NIBBLE: 558 /* read a byte, error means no more data */ 559 if (nibble_1284_inbyte(bus, buffer+len)) 560 goto end_while; 561 break; 562 case PPB_BYTE: 563 if (byte_1284_inbyte(bus, buffer+len)) 564 goto end_while; 565 break; 566 default: 567 error = EINVAL; 568 goto end_while; 569 } 570 len ++; 571 } 572end_while: 573 574 if (!error) 575 ppb_1284_set_state(bus, PPB_REVERSE_IDLE); 576 577 *read = len; 578 579 if (terminate_after_transfer || error) 580 ppb_1284_terminate(bus); 581 582 return (error); 583} 584 585/* 586 * ppb_1284_read_id() 587 * 588 */ 589int 590ppb_1284_read_id(device_t bus, int mode, char *buffer, 591 int max, int *read) 592{ 593 int error = 0; 594 595 /* fill the buffer with 0s */ 596 bzero(buffer, max); 597 598 switch (mode) { 599 case PPB_NIBBLE: 600 case PPB_ECP: 601 if ((error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID))) 602 return (error); 603 error = spp_1284_read(bus, PPB_NIBBLE, buffer, max, read); 604 break; 605 case PPB_BYTE: 606 if ((error = ppb_1284_negociate(bus, PPB_BYTE, PPB_REQUEST_ID))) 607 return (error); 608 error = spp_1284_read(bus, PPB_BYTE, buffer, max, read); 609 break; 610 default: 611 panic("%s: unsupported mode %d\n", __FUNCTION__, mode); 612 } 613 614 ppb_1284_terminate(bus); 615 return (error); 616} 617 618/* 619 * ppb_1284_read() 620 * 621 * IEEE1284 read 622 */ 623int 624ppb_1284_read(device_t bus, int mode, char *buffer, 625 int max, int *read) 626{ 627 int error = 0; 628 629 switch (mode) { 630 case PPB_NIBBLE: 631 case PPB_BYTE: 632 error = spp_1284_read(bus, mode, buffer, max, read); 633 break; 634 default: 635 return (EINVAL); 636 } 637 638 return (error); 639} 640 641/* 642 * ppb_1284_negociate() 643 * 644 * IEEE1284 negociation phase 645 * 646 * Normal nibble mode or request device id mode (see ppb_1284.h) 647 * 648 * After negociation, nFAULT is low if data is available 649 */ 650int 651ppb_1284_negociate(device_t bus, int mode, int options) 652{ 653 int error; 654 int request_mode; 655 656#ifdef DEBUG_1284 657 printf("n"); 658#endif 659 660 if (ppb_1284_get_state(bus) >= PPB_PERIPHERAL_NEGOCIATION) 661 ppb_peripheral_terminate(bus, PPB_WAIT); 662 663 if (ppb_1284_get_state(bus) != PPB_FORWARD_IDLE) 664 ppb_1284_terminate(bus); 665 666#ifdef DEBUG_1284 667 printf("%d", mode); 668#endif 669 670 /* ensure the host is in compatible mode */ 671 ppb_set_mode(bus, PPB_COMPATIBLE); 672 673 /* reset error to catch the actual negociation error */ 674 ppb_1284_reset_error(bus, PPB_FORWARD_IDLE); 675 676 /* calculate ext. value */ 677 request_mode = ppb_request_mode(mode, options); 678 679 /* default state */ 680 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED)); 681 DELAY(1); 682 683 /* enter negociation phase */ 684 ppb_1284_set_state(bus, PPB_NEGOCIATION); 685 686 /* Event 0 - put the exten. value on the data lines */ 687 ppb_wdtr(bus, request_mode); 688 689#ifdef PERIPH_1284 690 /* request remote host attention */ 691 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN)); 692 DELAY(1); 693 ppb_wctr(bus, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN)); 694#else 695 DELAY(1); 696 697#endif /* !PERIPH_1284 */ 698 699 /* Event 1 - enter IEEE1284 mode */ 700 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN)); 701 702#ifdef PERIPH_1284 703 /* ignore the PError line, wait a bit more, remote host's 704 * interrupts don't respond fast enough */ 705 if (ppb_poll_bus(bus, 40, nACK | SELECT | nFAULT, 706 SELECT | nFAULT, PPB_NOINTR | PPB_POLL)) { 707 ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2); 708 error = ENODEV; 709 goto error; 710 } 711#else 712 /* Event 2 - trying IEEE1284 dialog */ 713 if (do_1284_wait(bus, nACK | PERROR | SELECT | nFAULT, 714 PERROR | SELECT | nFAULT)) { 715 ppb_1284_set_error(bus, PPB_NOT_IEEE1284, 2); 716 error = ENODEV; 717 goto error; 718 } 719#endif /* !PERIPH_1284 */ 720 721 /* Event 3 - latch the ext. value to the peripheral */ 722 ppb_wctr(bus, (nINIT | STROBE | AUTOFEED) & ~SELECTIN); 723 DELAY(1); 724 725 /* Event 4 - IEEE1284 device recognized */ 726 ppb_wctr(bus, nINIT & ~(SELECTIN | AUTOFEED | STROBE)); 727 728 /* Event 6 - waiting for status lines */ 729 if (do_1284_wait(bus, nACK, nACK)) { 730 ppb_1284_set_error(bus, PPB_TIMEOUT, 6); 731 error = EBUSY; 732 goto error; 733 } 734 735 /* Event 7 - quering result consider nACK not to misunderstand 736 * a remote computer terminate sequence */ 737 if (options & PPB_EXTENSIBILITY_LINK) { 738 739 /* XXX not fully supported yet */ 740 ppb_1284_terminate(bus); 741 return (0); 742 743 } 744 if (request_mode == NIBBLE_1284_NORMAL) { 745 if (do_1284_wait(bus, nACK | SELECT, nACK)) { 746 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7); 747 error = ENODEV; 748 goto error; 749 } 750 } else { 751 if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) { 752 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7); 753 error = ENODEV; 754 goto error; 755 } 756 } 757 758 switch (mode) { 759 case PPB_NIBBLE: 760 case PPB_PS2: 761 /* enter reverse idle phase */ 762 ppb_1284_set_state(bus, PPB_REVERSE_IDLE); 763 break; 764 case PPB_ECP: 765 /* negociation ok, now setup the communication */ 766 ppb_1284_set_state(bus, PPB_SETUP); 767 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE)); 768 769#ifdef PERIPH_1284 770 /* ignore PError line */ 771 if (do_1284_wait(bus, nACK | SELECT | nBUSY, 772 nACK | SELECT | nBUSY)) { 773 ppb_1284_set_error(bus, PPB_TIMEOUT, 30); 774 error = ENODEV; 775 goto error; 776 } 777#else 778 if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY, 779 nACK | SELECT | PERROR | nBUSY)) { 780 ppb_1284_set_error(bus, PPB_TIMEOUT, 30); 781 error = ENODEV; 782 goto error; 783 } 784#endif /* !PERIPH_1284 */ 785 786 /* ok, the host enters the ForwardIdle state */ 787 ppb_1284_set_state(bus, PPB_ECP_FORWARD_IDLE); 788 break; 789 case PPB_EPP: 790 ppb_1284_set_state(bus, PPB_EPP_IDLE); 791 break; 792 793 default: 794 panic("%s: unknown mode (%d)!", __FUNCTION__, mode); 795 } 796 ppb_set_mode(bus, mode); 797 798 return (0); 799 800error: 801 ppb_1284_terminate(bus); 802 803 return (error); 804} 805 806/* 807 * ppb_1284_terminate() 808 * 809 * IEEE1284 termination phase, return code should ignored since the host 810 * is _always_ in compatible mode after ppb_1284_terminate() 811 */ 812int 813ppb_1284_terminate(device_t bus) 814{ 815 816#ifdef DEBUG_1284 817 printf("T"); 818#endif 819 820 /* do not reset error here to keep the error that 821 * may occured before the ppb_1284_terminate() call */ 822 ppb_1284_set_state(bus, PPB_TERMINATION); 823 824#ifdef PERIPH_1284 825 /* request remote host attention */ 826 ppb_wctr(bus, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED)); 827 DELAY(1); 828#endif /* PERIPH_1284 */ 829 830 /* Event 22 - set nSelectin low and nAutoFeed high */ 831 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED)); 832 833 /* Event 24 - waiting for peripheral, Xflag ignored */ 834 if (do_1284_wait(bus, nACK | nBUSY | nFAULT, nFAULT)) { 835 ppb_1284_set_error(bus, PPB_TIMEOUT, 24); 836 goto error; 837 } 838 839 /* Event 25 - set nAutoFd low */ 840 ppb_wctr(bus, (nINIT | SELECTIN | AUTOFEED) & ~STROBE); 841 842 /* Event 26 - compatible mode status is set */ 843 844 /* Event 27 - peripheral set nAck high */ 845 if (do_1284_wait(bus, nACK, nACK)) { 846 ppb_1284_set_error(bus, PPB_TIMEOUT, 27); 847 } 848 849 /* Event 28 - end termination, return to idle phase */ 850 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED)); 851 852error: 853 /* return to compatible mode */ 854 ppb_set_mode(bus, PPB_COMPATIBLE); 855 ppb_1284_set_state(bus, PPB_FORWARD_IDLE); 856 857 return (0); 858} 859