xref: /freebsd/sys/dev/ppbus/ppb_1284.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
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