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