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