The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ppbus/ppbus_1284.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: ppbus_1284.c,v 1.6 2004/02/24 15:12:52 wiz 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.6 2004/02/24 15:12:52 wiz 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 peripherial up to 40ms */
   51 static int
   52 do_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) */
   59 static int
   60 do_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 /* Unconditionaly reset the error field */
   68 static int
   69 ppbus_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 */
   78 int
   79 ppbus_1284_get_state(struct device * dev)
   80 {
   81         return (((struct ppbus_softc *)dev)->sc_1284_state);
   82 }
   83 
   84 
   85 /* Set IEEE1284 state if no error occurred */
   86 int
   87 ppbus_1284_set_state(struct device * dev, int state)
   88 {
   89         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
   90 
   91         /* call ppbus_1284_reset_error() if you absolutly want to change
   92          * the state from PPBUS_ERROR to another */
   93         if ((bus->sc_1284_state != PPBUS_ERROR) &&
   94                         (bus->sc_1284_error == PPBUS_NO_ERROR)) {
   95                 bus->sc_1284_state = state;
   96                 bus->sc_1284_error = PPBUS_NO_ERROR;
   97         }
   98 
   99         return 0;
  100 }
  101 
  102 
  103 /* Set the IEEE1284 error field */
  104 static int
  105 ppbus_1284_set_error(struct ppbus_softc * bus, int error, int event)
  106 {
  107         /* do not accumulate errors */
  108         if ((bus->sc_1284_error == PPBUS_NO_ERROR) &&
  109                         (bus->sc_1284_state != PPBUS_ERROR)) {
  110                 bus->sc_1284_error = error;
  111                 bus->sc_1284_state = PPBUS_ERROR;
  112         }
  113 
  114 #ifdef DEBUG_1284
  115         printf("%s<1284>: error=%d status=0x%x event=%d\n", 
  116                 bus->sc_dev.dv_xname, error, ppbus_rstr((struct device *)bus), 
  117                 event);
  118                 
  119 #endif
  120 
  121         return 0;
  122 }
  123 
  124 
  125 /* Converts mode+options into ext. value */
  126 static int
  127 ppbus_request_mode(int mode, int options)
  128 {
  129         int request_mode = 0;
  130 
  131         if (options & PPBUS_EXTENSIBILITY_LINK) {
  132                 request_mode = EXT_LINK_1284_NORMAL;
  133 
  134         } 
  135         else {
  136                 switch (mode) {
  137                 case PPBUS_NIBBLE:
  138                         request_mode = (options & PPBUS_REQUEST_ID) ?
  139                                         NIBBLE_1284_REQUEST_ID :
  140                                         NIBBLE_1284_NORMAL;
  141                         break;
  142                 case PPBUS_PS2:
  143                         request_mode = (options & PPBUS_REQUEST_ID) ?
  144                                         BYTE_1284_REQUEST_ID :
  145                                         BYTE_1284_NORMAL;
  146                         break;
  147                 case PPBUS_ECP:
  148                         if (options & PPBUS_USE_RLE)
  149                                 request_mode = (options & PPBUS_REQUEST_ID) ?
  150                                         ECP_1284_RLE_REQUEST_ID :
  151                                         ECP_1284_RLE;
  152                         else
  153                                 request_mode = (options & PPBUS_REQUEST_ID) ?
  154                                         ECP_1284_REQUEST_ID :
  155                                         ECP_1284_NORMAL;
  156                         break;
  157                 case PPBUS_EPP:
  158                         request_mode = EPP_1284_NORMAL;
  159                         break;
  160                 default:
  161                         panic("%s: unsupported mode %d\n", __FUNCTION__, mode);
  162                 }
  163         }
  164 
  165         return (request_mode);
  166 }
  167 
  168 
  169 /* Negotiate the peripheral side */
  170 int
  171 ppbus_peripheral_negotiate(struct device * dev, int mode, int options)
  172 {
  173         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
  174         int spin, request_mode, error = 0;
  175         char r;
  176 
  177         ppbus_1284_terminate(dev);
  178         ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_NEGOTIATION);
  179 
  180         /* compute ext. value */
  181         request_mode = ppbus_request_mode(mode, options);
  182 
  183         /* wait host */
  184         spin = 10;
  185         while (spin-- && (ppbus_rstr(dev) & nBUSY))
  186                 DELAY(1);
  187 
  188         /* check termination */
  189         if (!(ppbus_rstr(dev) & SELECT) || !spin) {
  190                 error = ENODEV;
  191                 goto error;
  192         }
  193 
  194         /* Event 4 - read ext. value */
  195         r = ppbus_rdtr(dev);
  196 
  197         /* nibble mode is not supported */
  198         if ((r == (char)request_mode) ||
  199                         (r == NIBBLE_1284_NORMAL)) {
  200 
  201                 /* Event 5 - restore direction bit, no data avail */
  202                 ppbus_wctr(dev, (STROBE | nINIT) & ~(SELECTIN));
  203                 DELAY(1);
  204 
  205                 /* Event 6 */
  206                 ppbus_wctr(dev, (nINIT) & ~(SELECTIN | STROBE));
  207 
  208                 if (r == NIBBLE_1284_NORMAL) {
  209 #ifdef DEBUG_1284
  210                         printf("R");
  211 #endif
  212                         ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 4);
  213                         error = EINVAL;
  214                         goto error;
  215                 } 
  216                 else {
  217                         ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_IDLE);
  218 #ifdef DEBUG_1284
  219                         printf("A");
  220 #endif
  221                         /* negotiation succeeds */
  222                 }
  223         } 
  224         else {
  225                 /* Event 5 - mode not supported */
  226                 ppbus_wctr(dev, SELECTIN);
  227                 DELAY(1);
  228 
  229                 /* Event 6 */
  230                 ppbus_wctr(dev, (SELECTIN) & ~(STROBE | nINIT));
  231                 ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 4);
  232 
  233 #ifdef DEBUG_1284
  234                 printf("r");
  235 #endif
  236                 error = EINVAL;
  237                 goto error;
  238         }
  239 
  240         return (0);
  241 
  242 error:
  243         ppbus_peripheral_terminate(dev, PPBUS_WAIT);
  244         return (error);
  245 }
  246 
  247 
  248 /* Terminate peripheral transfer side. Always return 0 in compatible mode */
  249 int
  250 ppbus_peripheral_terminate(struct device * dev, int how)
  251 {
  252         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
  253         int error = 0;
  254 
  255 #ifdef DEBUG_1284
  256         printf("t");
  257 #endif
  258 
  259         ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_TERMINATION);
  260 
  261         /* Event 22 - wait up to host response time (1s) */
  262         if ((error = do_peripheral_wait(bus, SELECT | nBUSY, 0))) {
  263                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 22);
  264                 goto error;
  265         }
  266 
  267         /* Event 24 */
  268         ppbus_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
  269 
  270         /* Event 25 - wait up to host response time (1s) */
  271         if ((error = do_peripheral_wait(bus, nBUSY, nBUSY))) {
  272                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 25);
  273                 goto error;
  274         }
  275 
  276         /* Event 26 */
  277         ppbus_wctr(dev, (SELECTIN | nINIT | STROBE) & ~(AUTOFEED));
  278         DELAY(1);
  279         /* Event 27 */
  280         ppbus_wctr(dev, (SELECTIN | nINIT) & ~(STROBE | AUTOFEED));
  281 
  282         /* Event 28 - wait up to host response time (1s) */
  283         if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
  284                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 28);
  285                 goto error;
  286         }
  287         
  288 error:
  289         ppbus_1284_terminate(dev);
  290         ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
  291 
  292         return (0);
  293 }
  294 
  295 
  296 /* Write 1 byte to host in BYTE mode (peripheral side) */
  297 static int
  298 byte_peripheral_outbyte(struct device * dev, char *buffer, int last)
  299 {
  300         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
  301         int error = 0;
  302 
  303         /* Event 7 */
  304         if ((error = do_1284_wait(bus, nBUSY, nBUSY))) {
  305                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 7);
  306                 goto error;
  307         }
  308 
  309         /* check termination */
  310         if (!(ppbus_rstr(dev) & SELECT)) {
  311                 ppbus_peripheral_terminate(dev, PPBUS_WAIT);
  312                 goto error;
  313         }
  314 
  315         /* Event 15 - put byte on data lines */
  316 #ifdef DEBUG_1284
  317         printf("B");
  318 #endif
  319         ppbus_wdtr(dev, *buffer);
  320 
  321         /* Event 9 */
  322         ppbus_wctr(dev, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));
  323 
  324         /* Event 10 - wait data read */
  325         if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
  326                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 16);
  327                 goto error;
  328         }
  329 
  330         /* Event 11 */
  331         if (!last) {
  332                 ppbus_wctr(dev, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
  333         } else {
  334                 ppbus_wctr(dev, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
  335         }
  336 
  337 #if 0
  338         /* Event 16 - wait strobe */
  339         if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) {
  340                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 16);
  341                 goto error;
  342         }
  343 #endif
  344 
  345         /* check termination */
  346         if (!(ppbus_rstr(dev) & SELECT)) {
  347                 ppbus_peripheral_terminate(dev, PPBUS_WAIT);
  348                 goto error;
  349         }
  350 
  351 error:
  352         return (error);
  353 }
  354 
  355 
  356 /* Write n bytes to host in BYTE mode (peripheral side) */
  357 int
  358 byte_peripheral_write(struct device * dev, char *buffer, int len, 
  359         int *sent)
  360 {
  361         int error = 0, i;
  362         char r;
  363 
  364         ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_TRANSFER);
  365 
  366         /* wait forever, the remote host is master and should initiate
  367          * termination
  368          */
  369         for(i = 0; i < len; i++) {
  370                 /* force remote nFAULT low to release the remote waiting
  371                  * process, if any
  372                  */
  373                 r = ppbus_rctr(dev);
  374                 ppbus_wctr(dev, r & ~nINIT);
  375 
  376 #ifdef DEBUG_1284
  377                 printf("y");
  378 #endif
  379                 /* Event 7 */
  380                 error = ppbus_poll_bus(dev, PPBUS_FOREVER, nBUSY, nBUSY,
  381                                         PPBUS_INTR);
  382 
  383                 if (error && error != EWOULDBLOCK)
  384                         goto error;
  385 
  386 #ifdef DEBUG_1284
  387                 printf("b");
  388 #endif
  389                 if ((error = byte_peripheral_outbyte(dev, buffer+i, (i == len-1))))
  390                         goto error;
  391         }
  392 error:
  393         if (!error)
  394                 ppbus_1284_set_state(dev, PPBUS_PERIPHERAL_IDLE);
  395 
  396         *sent = i;
  397         return (error);
  398 }
  399 
  400 
  401 /* Read the device ID using the specified mode */
  402 int
  403 ppbus_1284_read_id(struct device * dev, int mode, char ** buffer,
  404                 size_t * size, size_t * read)
  405 {
  406         u_int16_t msg_sz;
  407         u_int8_t length_field;
  408         u_int8_t old_mode;
  409         int error;
  410         int old_ivar;
  411         int new_ivar = 1;
  412         
  413         error = ppbus_read_ivar(dev, PPBUS_IVAR_IEEE, &old_ivar);
  414         if(error) {
  415                 printf("%s(%s): error reading PPBUS_IVAR_IEEE.\n", __func__,
  416                         dev->dv_xname);
  417                 return error;
  418         }
  419         if(old_ivar == 0) {
  420                 error = ppbus_write_ivar(dev, PPBUS_IVAR_IEEE, &new_ivar);
  421                 if(error) {
  422                         printf("%s(%s): error enabling IEEE usage.\n", __func__,
  423                                 dev->dv_xname);
  424                         return error;
  425                 }
  426         }
  427 
  428         old_mode = ppbus_get_mode(dev);
  429         switch (mode) {
  430         case PPBUS_NIBBLE:
  431         case PPBUS_ECP:
  432         case PPBUS_BYTE:
  433                 error = ppbus_set_mode(dev, mode, PPBUS_REQUEST_ID);
  434                 if(error) {
  435                         goto end_read_id;
  436                         printf("%s(%s): error setting bus mode.\n", __func__, 
  437                                 dev->dv_xname);
  438                 }
  439                 break;
  440         default:
  441                 printf("%s(%s): mode does not support returning device ID.\n",
  442                         __func__, dev->dv_xname);
  443                 error = ENODEV; 
  444                 goto end_read_id;
  445         }
  446         
  447         error = ppbus_read(dev, &length_field, 1, 0, read); 
  448         if(error) {
  449                 printf("%s(%s): error reading first byte.\n", __func__, 
  450                         dev->dv_xname);
  451                 goto end_read_id;
  452         }
  453         msg_sz = length_field;
  454         error = ppbus_read(dev, &length_field, 1, 0, read); 
  455         if(error) { 
  456                 printf("%s(%s): error reading second byte.\n", 
  457                         __func__, dev->dv_xname);
  458                 goto end_read_id;
  459         }
  460         msg_sz <<= 8;
  461         msg_sz |= length_field;
  462         msg_sz -= 2;
  463         if(msg_sz <= 0) {
  464                 printf("%s(%s): device ID length <= 0.\n", __func__,
  465                         dev->dv_xname);
  466                 goto end_read_id;
  467         }
  468         *buffer = malloc(msg_sz, M_DEVBUF, M_WAITOK);
  469         *size = msg_sz;
  470         error = ppbus_read(dev, *buffer, msg_sz, 0, read); 
  471 
  472 end_read_id:
  473         ppbus_set_mode(dev, old_mode, 0);
  474         if(old_ivar == 0) {
  475                 if(ppbus_write_ivar(dev, PPBUS_IVAR_IEEE, &old_ivar)) {
  476                         printf("%s(%s): error restoring PPBUS_IVAR_IEEE.\n", 
  477                                 __func__, dev->dv_xname);
  478                 }
  479         }
  480         return (error);
  481 }
  482 
  483 /*
  484  * IEEE1284 negotiation phase: after negotiation, nFAULT is low if data is 
  485  * available for reverse modes.
  486  */
  487 int
  488 ppbus_1284_negotiate(struct device * dev, int mode, int options)
  489 {
  490         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
  491         int error;
  492         int request_mode;
  493 
  494 #ifdef DEBUG_1284
  495         printf("n");
  496 #endif
  497 
  498         if (ppbus_1284_get_state(dev) >= PPBUS_PERIPHERAL_NEGOTIATION)
  499                 ppbus_peripheral_terminate(dev, PPBUS_WAIT);
  500 
  501 #ifdef DEBUG_1284
  502         printf("%d", mode);
  503 #endif
  504 
  505         /* ensure the host is in compatible mode */
  506         ppbus_1284_terminate(dev);
  507 
  508         /* reset error to catch the actual negotiation error */
  509         ppbus_1284_reset_error(bus, PPBUS_FORWARD_IDLE);
  510 
  511         /* calculate ext. value */
  512         request_mode = ppbus_request_mode(mode, options);
  513 
  514         /* default state */
  515         ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
  516         DELAY(1);
  517 
  518         /* enter negotiation phase */
  519         ppbus_1284_set_state(dev, PPBUS_NEGOTIATION);
  520 
  521         /* Event 0 - put the exten. value on the data lines */
  522         ppbus_wdtr(dev, request_mode);
  523 
  524 #ifdef PERIPH_1284
  525         /* request remote host attention */
  526         ppbus_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN));
  527         DELAY(1);
  528         ppbus_wctr(dev, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN));
  529 #else
  530         DELAY(1);
  531 
  532 #endif /* !PERIPH_1284 */
  533 
  534         /* Event 1 - enter IEEE1284 mode */
  535         ppbus_wctr(dev, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));
  536 
  537 #ifdef PERIPH_1284
  538         /* ignore the PError line, wait a bit more, remote host's 
  539          * interrupts don't respond fast enough */
  540         if (ppbus_poll_bus(bus, 40, nACK | SELECT | nFAULT,
  541                                 SELECT | nFAULT, PPBUS_NOINTR | PPBUS_POLL)) {
  542                 ppbus_1284_set_error(bus, PPBUS_NOT_IEEE1284, 2);
  543                 error = ENODEV;
  544                 goto error;
  545         }
  546 #else
  547         /* Event 2 - trying IEEE1284 dialog */
  548         if (do_1284_wait(bus, nACK | PERROR | SELECT | nFAULT,
  549                         PERROR  | SELECT | nFAULT)) {
  550                 ppbus_1284_set_error(bus, PPBUS_NOT_IEEE1284, 2);
  551                 error = ENODEV;
  552                 goto error;
  553         }
  554 #endif /* !PERIPH_1284 */
  555 
  556         /* Event 3 - latch the ext. value to the peripheral */
  557         ppbus_wctr(dev, (nINIT | STROBE | AUTOFEED) & ~SELECTIN);
  558         DELAY(1);
  559 
  560         /* Event 4 - IEEE1284 device recognized */
  561         ppbus_wctr(dev, nINIT & ~(SELECTIN | AUTOFEED | STROBE));
  562 
  563         /* Event 6 - waiting for status lines */
  564         if (do_1284_wait(bus, nACK, nACK)) {
  565                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 6);
  566                 error = EBUSY;
  567                 goto error;
  568         }
  569 
  570         /* Event 7 - quering result consider nACK not to misunderstand
  571          * a remote computer terminate sequence */
  572         if (options & PPBUS_EXTENSIBILITY_LINK) {
  573                 /* XXX not fully supported yet */
  574                 ppbus_1284_terminate(dev);
  575                 error = ENODEV;
  576                 goto error;
  577                 /* return (0); */
  578         }
  579         if (request_mode == NIBBLE_1284_NORMAL) {
  580                 if (do_1284_wait(bus, nACK | SELECT, nACK)) {
  581                         ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 7);
  582                         error = ENODEV;
  583                         goto error;
  584                 }
  585         } else {
  586                 if (do_1284_wait(bus, nACK | SELECT, SELECT | nACK)) {
  587                         ppbus_1284_set_error(bus, PPBUS_MODE_UNSUPPORTED, 7);
  588                         error = ENODEV;
  589                         goto error;
  590                 }
  591         }
  592 
  593         switch (mode) {
  594         case PPBUS_NIBBLE:
  595         case PPBUS_PS2:
  596                 /* enter reverse idle phase */
  597                 ppbus_1284_set_state(dev, PPBUS_REVERSE_IDLE);
  598                 break;
  599         case PPBUS_ECP:
  600                 /* negotiation ok, now setup the communication */
  601                 ppbus_1284_set_state(dev, PPBUS_SETUP);
  602                 ppbus_wctr(dev, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE));
  603 
  604 #ifdef PERIPH_1284
  605                 /* ignore PError line */
  606                 if (do_1284_wait(bus, nACK | SELECT | nBUSY,
  607                                         nACK | SELECT | nBUSY)) {
  608                         ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 30);
  609                         error = ENODEV;
  610                         goto error;
  611                 }
  612 #else
  613                 if (do_1284_wait(bus, nACK | SELECT | PERROR | nBUSY,
  614                                         nACK | SELECT | PERROR | nBUSY)) {
  615                         ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 30);
  616                         error = ENODEV;
  617                         goto error;
  618                 }
  619 #endif /* !PERIPH_1284 */
  620 
  621                 /* ok, the host enters the ForwardIdle state */
  622                 ppbus_1284_set_state(dev, PPBUS_ECP_FORWARD_IDLE);
  623                 break;
  624         case PPBUS_EPP:
  625                 ppbus_1284_set_state(dev, PPBUS_EPP_IDLE);
  626                 break;
  627         default:
  628                 panic("%s: unknown mode (%d)!", __func__, mode);
  629         }
  630         
  631         return 0;
  632 
  633 error:
  634         ppbus_1284_terminate(dev);
  635         return error;
  636 }
  637 
  638 /*
  639  * IEEE1284 termination phase, return code should ignored since the host
  640  * is _always_ in compatible mode after ppbus_1284_terminate()  
  641  */
  642 int
  643 ppbus_1284_terminate(struct device * dev)
  644 {
  645         struct ppbus_softc * bus = (struct ppbus_softc *) dev;
  646 
  647 #ifdef DEBUG_1284
  648         printf("T");
  649 #endif
  650 
  651         /* do not reset error here to keep the error that
  652          * may occurred before the ppbus_1284_terminate() call */
  653         ppbus_1284_set_state(dev, PPBUS_TERMINATION);
  654 
  655 #ifdef PERIPH_1284
  656         /* request remote host attention */
  657         ppbus_wctr(dev, (nINIT | STROBE | SELECTIN) & ~(AUTOFEED));
  658         DELAY(1);
  659 #endif /* PERIPH_1284 */
  660 
  661         /* Event 22 - set nSelectin low and nAutoFeed high */
  662         ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
  663 
  664         /* Event 24 - waiting for peripheral, Xflag ignored */
  665         if (do_1284_wait(bus, nACK | nBUSY | nFAULT, nFAULT)) {
  666                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 24);
  667                 goto error;
  668         }
  669 
  670         /* Event 25 - set nAutoFd low */
  671         ppbus_wctr(dev, (nINIT | SELECTIN | AUTOFEED) & ~STROBE);
  672 
  673         /* Event 26 - compatible mode status is set */
  674 
  675         /* Event 27 - peripheral set nAck high */
  676         if (do_1284_wait(bus, nACK, nACK)) {
  677                 ppbus_1284_set_error(bus, PPBUS_TIMEOUT, 27);
  678         }
  679 
  680         /* Event 28 - end termination, return to idle phase */
  681         ppbus_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED));
  682 
  683 error:
  684         ppbus_1284_set_state(dev, PPBUS_FORWARD_IDLE);
  685 
  686         return (0);
  687 }

Cache object: 936854b5469fa6db502d069c7bb61914


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.