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