2 * Copyright (c) 1997 Nicolas Souchu
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
31 * General purpose routines for the IEEE1284-1994 Standard
34 #include "opt_ppb_1284.h"
36 #include <sys/param.h>
37 #include <sys/systm.h>
40 #include <machine/clock.h>
42 #include <dev/ppbus/ppbconf.h>
43 #include <dev/ppbus/ppb_1284.h>
47 #include <dev/ppbus/ppbio.h>
49 #define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev))
54 * Wait for the peripherial up to 40ms
57 do_1284_wait(device_t bus, char mask, char status)
59 return (ppb_poll_bus(bus, 4, mask, status, PPB_NOINTR | PPB_POLL));
63 do_peripheral_wait(device_t bus, char mask, char status)
65 return (ppb_poll_bus(bus, 100, mask, status, PPB_NOINTR | PPB_POLL));
68 #define nibble2char(s) (((s & ~nACK) >> 3) | (~s & nBUSY) >> 4)
71 * ppb_1284_reset_error()
73 * Unconditionaly reset the error field
76 ppb_1284_reset_error(device_t bus, int state)
78 struct ppb_data *ppb = DEVTOSOFTC(bus);
80 ppb->error = PPB_NO_ERROR;
87 * ppb_1284_get_state()
92 ppb_1284_get_state(device_t bus)
94 return (DEVTOSOFTC(bus)->state);
98 * ppb_1284_set_state()
100 * Change IEEE1284 state if no error occured
103 ppb_1284_set_state(device_t bus, int state)
105 struct ppb_data *ppb = DEVTOSOFTC(bus);
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)) {
112 ppb->error = PPB_NO_ERROR;
119 ppb_1284_set_error(device_t bus, int error, int event)
121 struct ppb_data *ppb = DEVTOSOFTC(bus);
123 /* do not accumulate errors */
124 if ((ppb->error == PPB_NO_ERROR) &&
125 (ppb->state != PPB_ERROR)) {
127 ppb->state = PPB_ERROR;
131 printf("ppb1284: error=%d status=0x%x event=%d\n", error,
132 ppb_rstr(bus) & 0xff, event);
141 * Converts mode+options into ext. value
144 ppb_request_mode(int mode, int options)
146 int request_mode = 0;
148 if (options & PPB_EXTENSIBILITY_LINK) {
149 request_mode = EXT_LINK_1284_NORMAL;
154 request_mode = (options & PPB_REQUEST_ID) ?
155 NIBBLE_1284_REQUEST_ID :
159 request_mode = (options & PPB_REQUEST_ID) ?
160 BYTE_1284_REQUEST_ID :
164 if (options & PPB_USE_RLE)
165 request_mode = (options & PPB_REQUEST_ID) ?
166 ECP_1284_RLE_REQUEST_ID :
169 request_mode = (options & PPB_REQUEST_ID) ?
170 ECP_1284_REQUEST_ID :
174 request_mode = EPP_1284_NORMAL;
177 panic("%s: unsupported mode %d\n", __FUNCTION__, mode);
181 return (request_mode);
185 * ppb_peripheral_negociate()
187 * Negociate the peripheral side
190 ppb_peripheral_negociate(device_t bus, int mode, int options)
192 int spin, request_mode, error = 0;
195 ppb_set_mode(bus, PPB_COMPATIBLE);
196 ppb_1284_set_state(bus, PPB_PERIPHERAL_NEGOCIATION);
198 /* compute ext. value */
199 request_mode = ppb_request_mode(mode, options);
203 while (spin-- && (ppb_rstr(bus) & nBUSY))
206 /* check termination */
207 if (!(ppb_rstr(bus) & SELECT) || !spin) {
212 /* Event 4 - read ext. value */
215 /* nibble mode is not supported */
216 if ((r == (char)request_mode) ||
217 (r == NIBBLE_1284_NORMAL)) {
219 /* Event 5 - restore direction bit, no data avail */
220 ppb_wctr(bus, (STROBE | nINIT) & ~(SELECTIN));
224 ppb_wctr(bus, (nINIT) & ~(SELECTIN | STROBE));
226 if (r == NIBBLE_1284_NORMAL) {
230 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);
234 ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE);
236 case BYTE_1284_NORMAL:
237 ppb_set_mode(bus, PPB_BYTE);
245 /* negociation succeeds */
248 /* Event 5 - mode not supported */
249 ppb_wctr(bus, SELECTIN);
253 ppb_wctr(bus, (SELECTIN) & ~(STROBE | nINIT));
254 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);
266 ppb_peripheral_terminate(bus, PPB_WAIT);
271 * ppb_peripheral_terminate()
273 * Terminate peripheral transfer side
275 * Always return 0 in compatible mode
278 ppb_peripheral_terminate(device_t bus, int how)
286 ppb_1284_set_state(bus, PPB_PERIPHERAL_TERMINATION);
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);
295 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
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);
304 ppb_wctr(bus, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED));
307 ppb_wctr(bus, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED));
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);
316 ppb_set_mode(bus, PPB_COMPATIBLE);
317 ppb_1284_set_state(bus, PPB_FORWARD_IDLE);
323 * byte_peripheral_outbyte()
325 * Write 1 byte in BYTE mode
328 byte_peripheral_outbyte(device_t bus, char *buffer, int last)
333 if ((error = do_1284_wait(bus, nBUSY, nBUSY))) {
334 ppb_1284_set_error(bus, PPB_TIMEOUT, 7);
338 /* check termination */
339 if (!(ppb_rstr(bus) & SELECT)) {
340 ppb_peripheral_terminate(bus, PPB_WAIT);
344 /* Event 15 - put byte on data lines */
348 ppb_wdtr(bus, *buffer);
351 ppb_wctr(bus, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));
353 /* Event 10 - wait data read */
354 if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
355 ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
361 ppb_wctr(bus, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
363 ppb_wctr(bus, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
367 /* Event 16 - wait strobe */
368 if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) {
369 ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
374 /* check termination */
375 if (!(ppb_rstr(bus) & SELECT)) {
376 ppb_peripheral_terminate(bus, PPB_WAIT);
385 * byte_peripheral_write()
387 * Write n bytes in BYTE mode
390 byte_peripheral_write(device_t bus, char *buffer, int len, int *sent)
395 ppb_1284_set_state(bus, PPB_PERIPHERAL_TRANSFER);
397 /* wait forever, the remote host is master and should initiate
400 for (i=0; i<len; i++) {
401 /* force remote nFAULT low to release the remote waiting
405 ppb_wctr(bus, r & ~nINIT);
411 error = ppb_poll_bus(bus, PPB_FOREVER, nBUSY, nBUSY,
414 if (error && error != EWOULDBLOCK)
420 if ((error = byte_peripheral_outbyte(bus, buffer+i, (i == len-1))))
425 ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE);
434 * Read 1 byte in BYTE mode
437 byte_1284_inbyte(device_t bus, char *buffer)
441 /* Event 7 - ready to take data (nAUTO low) */
442 ppb_wctr(bus, (PCD | nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
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);
451 *buffer = ppb_rdtr(bus);
453 /* Event 10 - data received, can't accept more */
454 ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
456 /* Event 11 - peripheral ack */
457 if ((error = do_1284_wait(bus, nACK, nACK))) {
458 ppb_1284_set_error(bus, PPB_TIMEOUT, 11);
462 /* Event 16 - strobe */
463 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
465 ppb_wctr(bus, (nINIT) & ~(AUTOFEED | STROBE | SELECTIN));
472 * nibble_1284_inbyte()
474 * Read 1 byte in NIBBLE mode
477 nibble_1284_inbyte(device_t bus, char *buffer)
482 for (i = 0; i < 2; i++) {
484 /* Event 7 - ready to take data (nAUTO low) */
485 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
487 /* Event 8 - peripheral writes the first nibble */
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);
496 nibble[i] = ppb_rstr(bus);
498 /* Event 10 - ack, nibble received */
499 ppb_wctr(bus, nINIT & ~(AUTOFEED | STROBE | SELECTIN));
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);
508 *buffer = ((nibble2char(nibble[1]) << 4) & 0xf0) |
509 (nibble2char(nibble[0]) & 0x0f);
518 * Read in IEEE1284 NIBBLE/BYTE mode
521 spp_1284_read(device_t bus, int mode, char *buffer, int max, int *read)
523 int error = 0, len = 0;
524 int terminate_after_transfer = 1;
529 state = ppb_1284_get_state(bus);
532 case PPB_FORWARD_IDLE:
533 if ((error = ppb_1284_negociate(bus, mode, 0)))
537 case PPB_REVERSE_IDLE:
538 terminate_after_transfer = 0;
542 ppb_1284_terminate(bus);
543 if ((error = ppb_1284_negociate(bus, mode, 0)))
548 while ((len < max) && !(ppb_rstr(bus) & (nFAULT))) {
550 ppb_1284_set_state(bus, PPB_REVERSE_TRANSFER);
558 /* read a byte, error means no more data */
559 if (nibble_1284_inbyte(bus, buffer+len))
563 if (byte_1284_inbyte(bus, buffer+len))
575 ppb_1284_set_state(bus, PPB_REVERSE_IDLE);
579 if (terminate_after_transfer || error)
580 ppb_1284_terminate(bus);
590 ppb_1284_read_id(device_t bus, int mode, char *buffer,
595 /* fill the buffer with 0s */
601 if ((error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID)))
603 error = spp_1284_read(bus, PPB_NIBBLE, buffer, max, read);
606 if ((error = ppb_1284_negociate(bus, PPB_BYTE, PPB_REQUEST_ID)))
608 error = spp_1284_read(bus, PPB_BYTE, buffer, max, read);
611 panic("%s: unsupported mode %d\n", __FUNCTION__, mode);
614 ppb_1284_terminate(bus);
624 ppb_1284_read(device_t bus, int mode, char *buffer,
632 error = spp_1284_read(bus, mode, buffer, max, read);
642 * ppb_1284_negociate()
644 * IEEE1284 negociation phase
646 * Normal nibble mode or request device id mode (see ppb_1284.h)
648 * After negociation, nFAULT is low if data is available
651 ppb_1284_negociate(device_t bus, int mode, int options)
660 if (ppb_1284_get_state(bus) >= PPB_PERIPHERAL_NEGOCIATION)
661 ppb_peripheral_terminate(bus, PPB_WAIT);
663 if (ppb_1284_get_state(bus) != PPB_FORWARD_IDLE)
664 ppb_1284_terminate(bus);
670 /* ensure the host is in compatible mode */
671 ppb_set_mode(bus, PPB_COMPATIBLE);
673 /* reset error to catch the actual negociation error */
674 ppb_1284_reset_error(bus, PPB_FORWARD_IDLE);
676 /* calculate ext. value */
677 request_mode = ppb_request_mode(mode, options);
680 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
683 /* enter negociation phase */
684 ppb_1284_set_state(bus, PPB_NEGOCIATION);
686 /* Event 0 - put the exten. value on the data lines */
687 ppb_wdtr(bus, request_mode);
690 /* request remote host attention */
691 ppb_wctr(bus, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
693 ppb_wctr(bus, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN));
697 #endif /* !PERIPH_1284 */
699 /* Event 1 - enter IEEE1284 mode */
700 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
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);
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);
719 #endif /* !PERIPH_1284 */
721 /* Event 3 - latch the ext. value to the peripheral */
722 ppb_wctr(bus, (nINIT | STROBE | AUTOFEED) & ~SELECTIN);
725 /* Event 4 - IEEE1284 device recognized */
726 ppb_wctr(bus, nINIT & ~(SELECTIN | AUTOFEED | STROBE));
728 /* Event 6 - waiting for status lines */
729 if (do_1284_wait(bus, nACK, nACK)) {
730 ppb_1284_set_error(bus, PPB_TIMEOUT, 6);
735 /* Event 7 - quering result consider nACK not to misunderstand
736 * a remote computer terminate sequence */
737 if (options & PPB_EXTENSIBILITY_LINK) {
739 /* XXX not fully supported yet */
740 ppb_1284_terminate(bus);
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);
751 if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) {
752 ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 7);
761 /* enter reverse idle phase */
762 ppb_1284_set_state(bus, PPB_REVERSE_IDLE);
765 /* negociation ok, now setup the communication */
766 ppb_1284_set_state(bus, PPB_SETUP);
767 ppb_wctr(bus, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE));
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);
778 if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY,
779 nACK | SELECT | PERROR | nBUSY)) {
780 ppb_1284_set_error(bus, PPB_TIMEOUT, 30);
784 #endif /* !PERIPH_1284 */
786 /* ok, the host enters the ForwardIdle state */
787 ppb_1284_set_state(bus, PPB_ECP_FORWARD_IDLE);
790 ppb_1284_set_state(bus, PPB_EPP_IDLE);
794 panic("%s: unknown mode (%d)!", __FUNCTION__, mode);
796 ppb_set_mode(bus, mode);
801 ppb_1284_terminate(bus);
807 * ppb_1284_terminate()
809 * IEEE1284 termination phase, return code should ignored since the host
810 * is _always_ in compatible mode after ppb_1284_terminate()
813 ppb_1284_terminate(device_t bus)
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);
825 /* request remote host attention */
826 ppb_wctr(bus, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED));
828 #endif /* PERIPH_1284 */
830 /* Event 22 - set nSelectin low and nAutoFeed high */
831 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
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);
839 /* Event 25 - set nAutoFd low */
840 ppb_wctr(bus, (nINIT | SELECTIN | AUTOFEED) & ~STROBE);
842 /* Event 26 - compatible mode status is set */
844 /* Event 27 - peripheral set nAck high */
845 if (do_1284_wait(bus, nACK, nACK)) {
846 ppb_1284_set_error(bus, PPB_TIMEOUT, 27);
849 /* Event 28 - end termination, return to idle phase */
850 ppb_wctr(bus, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
853 /* return to compatible mode */
854 ppb_set_mode(bus, PPB_COMPATIBLE);
855 ppb_1284_set_state(bus, PPB_FORWARD_IDLE);