ppb_1284.c (bf492ef4c813a815048389ef9e4d9e1fdb62965d) ppb_1284.c (bc35c17446fab005a7e11b67b9004736f1c8498b)
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 unchanged lines hidden (view full) ---

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 *
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 unchanged lines hidden (view full) ---

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