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

Cache object: 205861095127bc817539c99816d0cadb


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