Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / bus / ppbus / ppb_1284.c
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: src/sys/dev/ppbus/ppb_1284.c,v 1.11 2000/01/14 08:03:14 nsouch Exp $
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  */
56 static int
57 do_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
62 static int
63 do_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  */
75 static int
76 ppb_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  */
91 int
92 ppb_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  */
102 int
103 ppb_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
118 static int
119 ppb_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  */
143 static int
144 ppb_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  */
189 int
190 ppb_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
265 error:
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  */
277 int
278 ppb_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         
315 error:
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  */
327 static int
328 byte_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
380 error:
381         return (error);
382 }
383
384 /*
385  * byte_peripheral_write()
386  *
387  * Write n bytes in BYTE mode
388  */
389 int
390 byte_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         }
423 error:
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  */
436 int
437 byte_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
467 error:
468         return (error);
469 }
470
471 /*
472  * nibble_1284_inbyte()
473  *
474  * Read 1 byte in NIBBLE mode
475  */
476 int
477 nibble_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
511 error:
512         return (error);
513 }
514
515 /*
516  * spp_1284_read()
517  *
518  * Read in IEEE1284 NIBBLE/BYTE mode
519  */
520 int
521 spp_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         }
572 end_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  */
589 int
590 ppb_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  */
623 int
624 ppb_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  */
650 int
651 ppb_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
800 error:
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  */
812 int
813 ppb_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
852 error:
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 }