1 /* $NetBSD: ppbus_1284.c,v 1.14 2021/11/14 20:51:57 andvar Exp $ */
2 
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  * FreeBSD: src/sys/dev/ppbus/ppb_1284.c,v 1.11 2000/01/14 08:03:14 nsouch Exp
29  *
30  */
31 
32 /* General purpose routines for the IEEE1284-1994 Standard */
33 
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: ppbus_1284.c,v 1.14 2021/11/14 20:51:57 andvar Exp $");
36 
37 #include "opt_ppbus_1284.h"
38 
39 #include <sys/param.h>
40 #include <sys/malloc.h>
41 #include <sys/systm.h>
42 
43 #include <dev/ppbus/ppbus_conf.h>
44 #include <dev/ppbus/ppbus_base.h>
45 #include <dev/ppbus/ppbus_1284.h>
46 #include <dev/ppbus/ppbus_io.h>
47 #include <dev/ppbus/ppbus_var.h>
48 
49 
50 /* Wait for the peripheral up to 40ms */
51 static int
do_1284_wait(struct ppbus_softc * bus,char mask,char status)52 do_1284_wait(struct ppbus_softc * bus, char mask, char status)
53 {
54           return (ppbus_poll_bus(bus->sc_dev, 4, mask, status,
55                     PPBUS_NOINTR | PPBUS_POLL));
56 }
57 
58 /* Wait for the host up to 1 second (peripheral side) */
59 static int
do_peripheral_wait(struct ppbus_softc * bus,char mask,char status)60 do_peripheral_wait(struct ppbus_softc * bus, char mask, char status)
61 {
62           return (ppbus_poll_bus(bus->sc_dev, 100, mask, status,
63                     PPBUS_NOINTR | PPBUS_POLL));
64 }
65 
66 
67 /* Unconditionally reset the error field */
68 static int
ppbus_1284_reset_error(struct ppbus_softc * bus,int state)69 ppbus_1284_reset_error(struct ppbus_softc * bus, int state)
70 {
71           bus->sc_1284_error = PPBUS_NO_ERROR;
72           bus->sc_1284_state = state;
73           return 0;
74 }
75 
76 
77 /* Get IEEE1284 state */
78 int
ppbus_1284_get_state(device_t dev)79 ppbus_1284_get_state(device_t dev)
80 {
81           struct ppbus_softc *sc = device_private(dev);
82 
83           return sc->sc_1284_state;
84 }
85 
86 
87 /* Set IEEE1284 state if no error occurred */
88 int
ppbus_1284_set_state(device_t dev,int state)89 ppbus_1284_set_state(device_t dev, int state)
90 {
91           struct ppbus_softc * bus = device_private(dev);
92 
93           /* call ppbus_1284_reset_error() if you absolutly want to change
94            * the state from PPBUS_ERROR to another */
95           if ((bus->sc_1284_state != PPBUS_ERROR) &&
96                               (bus->sc_1284_error == PPBUS_NO_ERROR)) {
97                     bus->sc_1284_state = state;
98                     bus->sc_1284_error = PPBUS_NO_ERROR;
99           }
100 
101           return 0;
102 }
103 
104 
105 /* Set the IEEE1284 error field */
106 static int
ppbus_1284_set_error(struct ppbus_softc * bus,int error,int event)107 ppbus_1284_set_error(struct ppbus_softc * bus, int error, int event)
108 {
109           /* do not accumulate errors */
110           if ((bus->sc_1284_error == PPBUS_NO_ERROR) &&
111                               (bus->sc_1284_state != PPBUS_ERROR)) {
112                     bus->sc_1284_error = error;
113                     bus->sc_1284_state = PPBUS_ERROR;
114           }
115 
116 #ifdef DEBUG_1284
117           printf("%s<1284>: error=%d status=0x%x event=%d\n",
118                     device_xname(bus->sc_dev), error, ppbus_rstr(bus->sc_dev),
119                     event);
120 
121 #endif
122 
123           return 0;
124 }
125 
126 
127 /* Converts mode+options into ext. value */
128 static int
ppbus_request_mode(int mode,int options)129 ppbus_request_mode(int mode, int options)
130 {
131           int request_mode = 0;
132 
133           if (options & PPBUS_EXTENSIBILITY_LINK) {
134                     request_mode = EXT_LINK_1284_NORMAL;
135 
136           }
137           else {
138                     switch (mode) {
139                     case PPBUS_NIBBLE:
140                               request_mode = (options & PPBUS_REQUEST_ID) ?
141                                                   NIBBLE_1284_REQUEST_ID :
142                                                   NIBBLE_1284_NORMAL;
143                               break;
144                     case PPBUS_PS2:
145                               request_mode = (options & PPBUS_REQUEST_ID) ?
146                                                   BYTE_1284_REQUEST_ID :
147                                                   BYTE_1284_NORMAL;
148                               break;
149                     case PPBUS_ECP:
150                               if (options & PPBUS_USE_RLE)
151                                         request_mode = (options & PPBUS_REQUEST_ID) ?
152                                                   ECP_1284_RLE_REQUEST_ID :
153                                                   ECP_1284_RLE;
154                               else
155                                         request_mode = (options & PPBUS_REQUEST_ID) ?
156                                                   ECP_1284_REQUEST_ID :
157                                                   ECP_1284_NORMAL;
158                               break;
159                     case PPBUS_EPP:
160                               request_mode = EPP_1284_NORMAL;
161                               break;
162                     default:
163                               panic("%s: unsupported mode %d\n", __func__, mode);
164                     }
165           }
166 
167           return (request_mode);
168 }
169 
170 
171 /* Negotiate the peripheral side */
172 int
ppbus_peripheral_negotiate(device_t dev,int mode,int options)173 ppbus_peripheral_negotiate(device_t dev, int mode, int options)
174 {
175           struct ppbus_softc * bus = device_private(dev);
176           int spin, request_mode, error = 0;
177           char r;
178 
179           ppbus_1284_terminate(dev);
180           ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_NEGOTIATION);
181 
182           /* compute ext. value */
183           request_mode = ppbus_request_mode(mode, options);
184 
185           /* wait host */
186           spin = 10;
187           while (spin-- && (ppbus_rstr(dev) & nBUSY))
188                     DELAY(1);
189 
190           /* check termination */
191           if (!(ppbus_rstr(dev) & SELECT) || !spin) {
192                     error = ENODEV;
193                     goto error;
194           }
195 
196           /* Event 4 - read ext. value */
197           r = ppbus_rdtr(dev);
198 
199           /* nibble mode is not supported */
200           if ((r == (char)request_mode) ||
201                               (r == NIBBLE_1284_NORMAL)) {
202 
203                     /* Event 5 - restore direction bit, no data avail */
204                     ppbus_wctr(dev, (STROBE | nINIT) & ~(SELECTIN));
205                     DELAY(1);
206 
207                     /* Event 6 */
208                     ppbus_wctr(dev, (nINIT) & ~(SELECTIN | STROBE));
209 
210                     if (r == NIBBLE_1284_NORMAL) {
211 #ifdef DEBUG_1284
212                               printf("R");
213 #endif
214                               ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 4);
215                               error = EINVAL;
216                               goto error;
217                     }
218                     else {
219                               ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_IDLE);
220 #ifdef DEBUG_1284
221                               printf("A");
222 #endif
223                               /* negotiation succeeds */
224                     }
225           }
226           else {
227                     /* Event 5 - mode not supported */
228                     ppbus_wctr(dev, SELECTIN);
229                     DELAY(1);
230 
231                     /* Event 6 */
232                     ppbus_wctr(dev, (SELECTIN) & ~(STROBE | nINIT));
233                     ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 4);
234 
235 #ifdef DEBUG_1284
236                     printf("r");
237 #endif
238                     error = EINVAL;
239                     goto error;
240           }
241 
242           return (0);
243 
244 error:
245           ppbus_peripheral_terminate(dev, PPBUS_WAIT);
246           return (error);
247 }
248 
249 
250 /* Terminate peripheral transfer side. Always return 0 in compatible mode */
251 int
ppbus_peripheral_terminate(device_t dev,int how)252 ppbus_peripheral_terminate(device_t dev, int how)
253 {
254           struct ppbus_softc * bus = device_private(dev);
255           int error = 0;
256 
257 #ifdef DEBUG_1284
258           printf("t");
259 #endif
260 
261           ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_TERMINATION);
262 
263           /* Event 22 - wait up to host response time (1s) */
264           if ((error = do_peripheral_wait(bus, SELECT | nBUSY, 0))) {
265                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 22);
266                     goto error;
267           }
268 
269           /* Event 24 */
270         ppbus_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
271 
272           /* Event 25 - wait up to host response time (1s) */
273           if ((error = do_peripheral_wait(bus, nBUSY, nBUSY))) {
274                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 25);
275                     goto error;
276           }
277 
278           /* Event 26 */
279         ppbus_wctr(dev, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED));
280           DELAY(1);
281           /* Event 27 */
282         ppbus_wctr(dev, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED));
283 
284           /* Event 28 - wait up to host response time (1s) */
285           if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
286                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 28);
287                     goto error;
288           }
289 
290 error:
291           ppbus_1284_terminate(dev);
292           ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
293 
294           return (0);
295 }
296 
297 
298 /* Write 1 byte to host in BYTE mode (peripheral side) */
299 static int
byte_peripheral_outbyte(device_t dev,char * buffer,int last)300 byte_peripheral_outbyte(device_t dev, char *buffer, int last)
301 {
302           struct ppbus_softc * bus = device_private(dev);
303           int error = 0;
304 
305           /* Event 7 */
306           if ((error = do_1284_wait(bus, nBUSY, nBUSY))) {
307                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 7);
308                     goto error;
309           }
310 
311           /* check termination */
312           if (!(ppbus_rstr(dev) & SELECT)) {
313                     ppbus_peripheral_terminate(dev, PPBUS_WAIT);
314                     goto error;
315           }
316 
317           /* Event 15 - put byte on data lines */
318 #ifdef DEBUG_1284
319           printf("B");
320 #endif
321           ppbus_wdtr(dev, *buffer);
322 
323           /* Event 9 */
324           ppbus_wctr(dev, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));
325 
326           /* Event 10 - wait data read */
327           if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
328                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 16);
329                     goto error;
330           }
331 
332           /* Event 11 */
333           if (!last) {
334                     ppbus_wctr(dev, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
335           } else {
336                     ppbus_wctr(dev, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
337           }
338 
339 #if 0
340           /* Event 16 - wait strobe */
341           if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) {
342                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 16);
343                     goto error;
344           }
345 #endif
346 
347           /* check termination */
348           if (!(ppbus_rstr(dev) & SELECT)) {
349                     ppbus_peripheral_terminate(dev, PPBUS_WAIT);
350                     goto error;
351           }
352 
353 error:
354           return (error);
355 }
356 
357 
358 /* Write n bytes to host in BYTE mode (peripheral side) */
359 int
byte_peripheral_write(device_t dev,char * buffer,int len,int * sent)360 byte_peripheral_write(device_t dev, char *buffer, int len,
361           int *sent)
362 {
363           int error = 0, i;
364           char r;
365 
366           ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_TRANSFER);
367 
368           /* wait forever, the remote host is master and should initiate
369            * termination
370            */
371           for(i = 0; i < len; i++) {
372                     /* force remote nFAULT low to release the remote waiting
373                      * process, if any
374                      */
375                     r = ppbus_rctr(dev);
376                     ppbus_wctr(dev, r & ~nINIT);
377 
378 #ifdef DEBUG_1284
379                     printf("y");
380 #endif
381                     /* Event 7 */
382                     error = ppbus_poll_bus(dev, PPBUS_FOREVER, nBUSY, nBUSY,
383                                                   PPBUS_INTR);
384 
385                     if (error && error != EWOULDBLOCK)
386                               goto error;
387 
388 #ifdef DEBUG_1284
389                     printf("b");
390 #endif
391                     if ((error = byte_peripheral_outbyte(dev, buffer+i, (i == len-1))))
392                               goto error;
393           }
394 error:
395           if (!error)
396                     ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_IDLE);
397 
398           *sent = i;
399           return (error);
400 }
401 
402 
403 /* Read the device ID using the specified mode */
404 int
ppbus_1284_read_id(device_t dev,int mode,char ** buffer,size_t * size,size_t * read)405 ppbus_1284_read_id(device_t dev, int mode, char ** buffer,
406                     size_t * size, size_t * read)
407 {
408           u_int16_t msg_sz;
409           u_int8_t length_field;
410           u_int8_t old_mode;
411           int error;
412           int old_ivar;
413           int new_ivar = 1;
414 
415           error = ppbus_read_ivar(dev, PPBUS_IVAR_IEEE, &old_ivar);
416           if(error) {
417                     printf("%s(%s): error reading PPBUS_IVAR_IEEE.\n", __func__,
418                               device_xname(dev));
419                     return error;
420           }
421           if(old_ivar == 0) {
422                     error = ppbus_write_ivar(dev, PPBUS_IVAR_IEEE, &new_ivar);
423                     if(error) {
424                               printf("%s(%s): error enabling IEEE usage.\n", __func__,
425                                         device_xname(dev));
426                               return error;
427                     }
428           }
429 
430           old_mode = ppbus_get_mode(dev);
431           switch (mode) {
432           case PPBUS_NIBBLE:
433           case PPBUS_ECP:
434           case PPBUS_BYTE:
435                     error = ppbus_set_mode(dev, mode, PPBUS_REQUEST_ID);
436                     if(error) {
437                               printf("%s(%s): error setting bus mode.\n", __func__,
438                                         device_xname(dev));
439                               goto end_read_id;
440                     }
441                     break;
442           default:
443                     printf("%s(%s): mode does not support returning device ID.\n",
444                               __func__, device_xname(dev));
445                     error = ENODEV;
446                     goto end_read_id;
447           }
448 
449           error = ppbus_read(dev, &length_field, 1, 0, read);
450           if(error) {
451                     printf("%s(%s): error reading first byte.\n", __func__,
452                               device_xname(dev));
453                     goto end_read_id;
454           }
455           msg_sz = length_field;
456           error = ppbus_read(dev, &length_field, 1, 0, read);
457           if(error) {
458                     printf("%s(%s): error reading second byte.\n",
459                               __func__, device_xname(dev));
460                     goto end_read_id;
461           }
462           msg_sz <<= 8;
463           msg_sz |= length_field;
464           msg_sz -= 2;
465           if(msg_sz <= 0) {
466                     printf("%s(%s): device ID length <= 0.\n", __func__,
467                               device_xname(dev));
468                     goto end_read_id;
469           }
470           *buffer = malloc(msg_sz, M_DEVBUF, M_WAITOK);
471           *size = msg_sz;
472           error = ppbus_read(dev, *buffer, msg_sz, 0, read);
473 
474 end_read_id:
475           ppbus_set_mode(dev, old_mode, 0);
476           if(old_ivar == 0) {
477                     if(ppbus_write_ivar(dev, PPBUS_IVAR_IEEE, &old_ivar)) {
478                               printf("%s(%s): error restoring PPBUS_IVAR_IEEE.\n",
479                                         __func__, device_xname(dev));
480                     }
481           }
482           return (error);
483 }
484 
485 /*
486  * IEEE1284 negotiation phase: after negotiation, nFAULT is low if data is
487  * available for reverse modes.
488  */
489 int
ppbus_1284_negotiate(device_t dev,int mode,int options)490 ppbus_1284_negotiate(device_t dev, int mode, int options)
491 {
492           struct ppbus_softc * bus = device_private(dev);
493           int error;
494           int request_mode;
495 
496 #ifdef DEBUG_1284
497           printf("n");
498 #endif
499 
500           if (ppbus_1284_get_state(dev) >= PPBUS_PERIPHERAL_NEGOTIATION)
501                     ppbus_peripheral_terminate(dev, PPBUS_WAIT);
502 
503 #ifdef DEBUG_1284
504           printf("%d", mode);
505 #endif
506 
507           /* ensure the host is in compatible mode */
508           ppbus_1284_terminate(dev);
509 
510           /* reset error to catch the actual negotiation error */
511           ppbus_1284_reset_error(bus, PPBUS_FORWARD_IDLE);
512 
513           /* calculate ext. value */
514           request_mode = ppbus_request_mode(mode, options);
515 
516           /* default state */
517           ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
518           DELAY(1);
519 
520           /* enter negotiation phase */
521           ppbus_1284_set_state(dev, PPBUS_NEGOTIATION);
522 
523           /* Event 0 - put the exten. value on the data lines */
524           ppbus_wdtr(dev, request_mode);
525 
526 #ifdef PERIPH_1284
527           /* request remote host attention */
528         ppbus_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
529         DELAY(1);
530         ppbus_wctr(dev, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN));
531 #else
532           DELAY(1);
533 
534 #endif /* !PERIPH_1284 */
535 
536           /* Event 1 - enter IEEE1284 mode */
537           ppbus_wctr(dev, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
538 
539 #ifdef PERIPH_1284
540           /* ignore the PError line, wait a bit more, remote host's
541            * interrupts don't respond fast enough */
542           if (ppbus_poll_bus(bus, 40, nACK | SELECT | nFAULT,
543                                         SELECT | nFAULT, PPBUS_NOINTR | PPBUS_POLL)) {
544                 ppbus_1284_set_error(bus, PPBUS_NOT_IEEE1284, 2);
545                 error = ENODEV;
546                 goto error;
547         }
548 #else
549           /* Event 2 - trying IEEE1284 dialog */
550           if (do_1284_wait(bus, nACK | PERROR | SELECT | nFAULT,
551                               PERROR  | SELECT | nFAULT)) {
552                     ppbus_1284_set_error(bus, PPBUS_NOT_IEEE1284, 2);
553                     error = ENODEV;
554                     goto error;
555           }
556 #endif /* !PERIPH_1284 */
557 
558           /* Event 3 - latch the ext. value to the peripheral */
559           ppbus_wctr(dev, (nINIT | STROBE | AUTOFEED) & ~SELECTIN);
560           DELAY(1);
561 
562           /* Event 4 - IEEE1284 device recognized */
563           ppbus_wctr(dev, nINIT & ~(SELECTIN | AUTOFEED | STROBE));
564 
565           /* Event 6 - waiting for status lines */
566           if (do_1284_wait(bus, nACK, nACK)) {
567                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 6);
568                     error = EBUSY;
569                     goto error;
570           }
571 
572           /* Event 7 - querying result consider nACK not to misunderstand
573            * a remote computer terminate sequence */
574           if (options & PPBUS_EXTENSIBILITY_LINK) {
575                     /* XXX not fully supported yet */
576                     ppbus_1284_terminate(dev);
577                     error = ENODEV;
578                     goto error;
579                     /* return (0); */
580           }
581           if (request_mode == NIBBLE_1284_NORMAL) {
582                     if (do_1284_wait(bus, nACK | SELECT, nACK)) {
583                               ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 7);
584                               error = ENODEV;
585                               goto error;
586                     }
587           } else {
588                     if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) {
589                               ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 7);
590                               error = ENODEV;
591                               goto error;
592                     }
593           }
594 
595           switch (mode) {
596           case PPBUS_NIBBLE:
597           case PPBUS_PS2:
598                     /* enter reverse idle phase */
599                     ppbus_1284_set_state(dev, PPBUS_REVERSE_IDLE);
600                     break;
601           case PPBUS_ECP:
602                     /* negotiation ok, now setup the communication */
603                     ppbus_1284_set_state(dev, PPBUS_SETUP);
604                     ppbus_wctr(dev, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE));
605 
606 #ifdef PERIPH_1284
607                     /* ignore PError line */
608                     if (do_1284_wait(bus, nACK | SELECT | nBUSY,
609                                         nACK | SELECT | nBUSY)) {
610                         ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 30);
611                         error = ENODEV;
612                         goto error;
613                 }
614 #else
615                     if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY,
616                                                   nACK | SELECT | PERROR | nBUSY)) {
617                               ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 30);
618                               error = ENODEV;
619                               goto error;
620                     }
621 #endif /* !PERIPH_1284 */
622 
623                     /* ok, the host enters the ForwardIdle state */
624                     ppbus_1284_set_state(dev, PPBUS_ECP_FORWARD_IDLE);
625                     break;
626           case PPBUS_EPP:
627                     ppbus_1284_set_state(dev, PPBUS_EPP_IDLE);
628                     break;
629           default:
630                     panic("%s: unknown mode (%d)!", __func__, mode);
631           }
632 
633           return 0;
634 
635 error:
636           ppbus_1284_terminate(dev);
637           return error;
638 }
639 
640 /*
641  * IEEE1284 termination phase, return code should ignored since the host
642  * is _always_ in compatible mode after ppbus_1284_terminate()
643  */
644 int
ppbus_1284_terminate(device_t dev)645 ppbus_1284_terminate(device_t dev)
646 {
647           struct ppbus_softc * bus = device_private(dev);
648 
649 #ifdef DEBUG_1284
650           printf("T");
651 #endif
652 
653           /* do not reset error here to keep the error that
654            * may occurred before the ppbus_1284_terminate() call */
655           ppbus_1284_set_state(dev, PPBUS_TERMINATION);
656 
657 #ifdef PERIPH_1284
658           /* request remote host attention */
659         ppbus_wctr(dev, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED));
660         DELAY(1);
661 #endif /* PERIPH_1284 */
662 
663           /* Event 22 - set nSelectin low and nAutoFeed high */
664           ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
665 
666           /* Event 24 - waiting for peripheral, Xflag ignored */
667           if (do_1284_wait(bus, nACK | nBUSY | nFAULT, nFAULT)) {
668                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 24);
669                     goto error;
670           }
671 
672           /* Event 25 - set nAutoFd low */
673           ppbus_wctr(dev, (nINIT | SELECTIN | AUTOFEED) & ~STROBE);
674 
675           /* Event 26 - compatible mode status is set */
676 
677           /* Event 27 - peripheral set nAck high */
678           if (do_1284_wait(bus, nACK, nACK)) {
679                     ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 27);
680           }
681 
682           /* Event 28 - end termination, return to idle phase */
683           ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
684 
685 error:
686           ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
687 
688           return (0);
689 }
690