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 */
51static int
52do_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) */
59static int
60do_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 */
68static int
69ppbus_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 */
78int
79ppbus_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 */
88int
89ppbus_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 */
106static int
107ppbus_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 */
128static int
129ppbus_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 */
172int
173ppbus_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
244error:
245	ppbus_peripheral_terminate(dev, PPBUS_WAIT);
246	return (error);
247}
248
249
250/* Terminate peripheral transfer side. Always return 0 in compatible mode */
251int
252ppbus_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
290error:
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) */
299static int
300byte_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
353error:
354	return (error);
355}
356
357
358/* Write n bytes to host in BYTE mode (peripheral side) */
359int
360byte_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	}
394error:
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 */
404int
405ppbus_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
474end_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 */
489int
490ppbus_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
635error:
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 */
644int
645ppbus_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
685error:
686	ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
687
688	return (0);
689}
690