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