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