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