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

Cache object: 2dcdb4683751d1fbcb88a895d3b86968


[ 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.