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/ic/atppc.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: atppc.c,v 1.41 2022/11/01 19:45:35 andvar Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2001 Alcove - Nicolas Souchu
    5  * Copyright (c) 2003, 2004 Gary Thorpe <gathorpe@users.sourceforge.net>
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * FreeBSD: src/sys/isa/ppc.c,v 1.26.2.5 2001/10/02 05:21:45 nsouch Exp
   30  *
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: atppc.c,v 1.41 2022/11/01 19:45:35 andvar Exp $");
   35 
   36 #include "opt_atppc.h"
   37 
   38 #include <sys/types.h>
   39 #include <sys/param.h>
   40 #include <sys/kernel.h>
   41 #include <sys/device.h>
   42 #include <sys/kmem.h>
   43 #include <sys/proc.h>
   44 #include <sys/systm.h>
   45 #include <sys/vnode.h>
   46 #include <sys/syslog.h>
   47 
   48 #include <sys/bus.h>
   49 /*#include <sys/intr.h>*/
   50 
   51 #include <dev/isa/isareg.h>
   52 
   53 #include <dev/ic/atppcreg.h>
   54 #include <dev/ic/atppcvar.h>
   55 
   56 #include <dev/ppbus/ppbus_conf.h>
   57 #include <dev/ppbus/ppbus_msq.h>
   58 #include <dev/ppbus/ppbus_io.h>
   59 #include <dev/ppbus/ppbus_var.h>
   60 
   61 #ifdef ATPPC_DEBUG
   62 int atppc_debug = 1;
   63 #endif
   64 
   65 #ifdef ATPPC_VERBOSE
   66 int atppc_verbose = 1;
   67 #endif
   68 
   69 /* List of supported chipsets detection routines */
   70 static int (*chipset_detect[])(struct atppc_softc *) = {
   71 /* XXX Add these LATER: maybe as separate devices?
   72                 atppc_pc873xx_detect,
   73                 atppc_smc37c66xgt_detect,
   74                 atppc_w83877f_detect,
   75                 atppc_smc37c935_detect,
   76 */
   77                 NULL
   78 };
   79 
   80 
   81 /* Prototypes for functions. */
   82 
   83 /* Print function for config_found() */
   84 static int atppc_print(void *, const char *);
   85 
   86 /* Detection routines */
   87 static int atppc_detect_fifo(struct atppc_softc *);
   88 static int atppc_detect_chipset(struct atppc_softc *);
   89 static int atppc_detect_generic(struct atppc_softc *);
   90 
   91 /* Routines for ppbus interface (bus + device) */
   92 static int atppc_read(device_t, char *, int, int, size_t *);
   93 static int atppc_write(device_t, char *, int, int, size_t *);
   94 static int atppc_setmode(device_t, int);
   95 static int atppc_getmode(device_t);
   96 static int atppc_check_epp_timeout(device_t);
   97 static void atppc_reset_epp_timeout(device_t);
   98 static void atppc_ecp_sync(device_t);
   99 static int atppc_exec_microseq(device_t, struct ppbus_microseq * *);
  100 static u_int8_t atppc_io(device_t, int, u_char *, int, u_char);
  101 static int atppc_read_ivar(device_t, int, unsigned int *);
  102 static int atppc_write_ivar(device_t, int, unsigned int *);
  103 static int atppc_add_handler(device_t, void (*)(void *), void *);
  104 static int atppc_remove_handler(device_t, void (*)(void *));
  105 
  106 /* Utility functions */
  107 
  108 /* Functions to read bytes into device's input buffer */
  109 static void atppc_nibble_read(struct atppc_softc * const);
  110 static void atppc_byte_read(struct atppc_softc * const);
  111 static void atppc_epp_read(struct atppc_softc * const);
  112 static void atppc_ecp_read(struct atppc_softc * const);
  113 static void atppc_ecp_read_dma(struct atppc_softc *, unsigned int *,
  114         unsigned char);
  115 static void atppc_ecp_read_pio(struct atppc_softc *, unsigned int *,
  116         unsigned char);
  117 static void atppc_ecp_read_error(struct atppc_softc *);
  118 
  119 
  120 /* Functions to write bytes to device's output buffer */
  121 static void atppc_std_write(struct atppc_softc * const);
  122 static void atppc_epp_write(struct atppc_softc * const);
  123 static void atppc_fifo_write(struct atppc_softc * const);
  124 static void atppc_fifo_write_dma(struct atppc_softc * const, unsigned char,
  125         unsigned char);
  126 static void atppc_fifo_write_pio(struct atppc_softc * const, unsigned char,
  127         unsigned char);
  128 static void atppc_fifo_write_error(struct atppc_softc * const,
  129         const unsigned int);
  130 
  131 /* Miscellaneous */
  132 static int atppc_poll_str(const struct atppc_softc * const, const u_int8_t,
  133         const u_int8_t);
  134 static int atppc_wait_interrupt(struct atppc_softc * const, kcondvar_t *,
  135         const u_int8_t);
  136 
  137 
  138 /*
  139  * Generic attach and detach functions for atppc device. If sc_dev_ok in soft
  140  * configuration data is not ATPPC_ATTACHED, these should be skipped altogether.
  141  */
  142 
  143 /* Soft configuration attach for atppc */
  144 void
  145 atppc_sc_attach(struct atppc_softc *lsc)
  146 {
  147         /* Adapter used to configure ppbus device */
  148         struct parport_adapter sc_parport_adapter;
  149         char buf[64];
  150 
  151         mutex_init(&lsc->sc_lock, MUTEX_DEFAULT, IPL_TTY);
  152         cv_init(&lsc->sc_out_cv, "atppcout");
  153         cv_init(&lsc->sc_in_cv, "atppcin");
  154 
  155         /* Probe and set up chipset */
  156         if (atppc_detect_chipset(lsc) != 0) {
  157                 if (atppc_detect_generic(lsc) != 0) {
  158                         ATPPC_DPRINTF(("%s: Error detecting chipset\n",
  159                                 device_xname(lsc->sc_dev)));
  160                 }
  161         }
  162 
  163         /* Probe and setup FIFO queue */
  164         if (atppc_detect_fifo(lsc) == 0) {
  165                 printf("%s: FIFO <depth,wthr,rthr>=<%d,%d,%d>\n",
  166                         device_xname(lsc->sc_dev), lsc->sc_fifo, lsc->sc_wthr,
  167                         lsc->sc_rthr);
  168         }
  169 
  170         /* Print out chipset capabilities */
  171         snprintb(buf, sizeof(buf), "\2\1INTR\2DMA\3FIFO\4PS2\5ECP\6EPP",
  172             lsc->sc_has);
  173         printf("%s: capabilities=%s\n", device_xname(lsc->sc_dev), buf);
  174 
  175         /* Initialize device's buffer pointers */
  176         lsc->sc_outb = lsc->sc_outbstart = lsc->sc_inb = lsc->sc_inbstart
  177                 = NULL;
  178         lsc->sc_inb_nbytes = lsc->sc_outb_nbytes = 0;
  179 
  180         /* Last configuration step: set mode to standard mode */
  181         if (atppc_setmode(lsc->sc_dev, PPBUS_COMPATIBLE) != 0) {
  182                 ATPPC_DPRINTF(("%s: unable to initialize mode.\n",
  183                         device_xname(lsc->sc_dev)));
  184         }
  185 
  186         /* Set up parport_adapter structure */
  187 
  188         /* Set capabilities */
  189         sc_parport_adapter.capabilities = 0;
  190         if (lsc->sc_has & ATPPC_HAS_INTR) {
  191                 sc_parport_adapter.capabilities |= PPBUS_HAS_INTR;
  192         }
  193         if (lsc->sc_has & ATPPC_HAS_DMA) {
  194                 sc_parport_adapter.capabilities |= PPBUS_HAS_DMA;
  195         }
  196         if (lsc->sc_has & ATPPC_HAS_FIFO) {
  197                 sc_parport_adapter.capabilities |= PPBUS_HAS_FIFO;
  198         }
  199         if (lsc->sc_has & ATPPC_HAS_PS2) {
  200                 sc_parport_adapter.capabilities |= PPBUS_HAS_PS2;
  201         }
  202         if (lsc->sc_has & ATPPC_HAS_EPP) {
  203                 sc_parport_adapter.capabilities |= PPBUS_HAS_EPP;
  204         }
  205         if (lsc->sc_has & ATPPC_HAS_ECP) {
  206                 sc_parport_adapter.capabilities |= PPBUS_HAS_ECP;
  207         }
  208 
  209         /* Set function pointers */
  210         sc_parport_adapter.parport_io = atppc_io;
  211         sc_parport_adapter.parport_exec_microseq = atppc_exec_microseq;
  212         sc_parport_adapter.parport_reset_epp_timeout =
  213                 atppc_reset_epp_timeout;
  214         sc_parport_adapter.parport_setmode = atppc_setmode;
  215         sc_parport_adapter.parport_getmode = atppc_getmode;
  216         sc_parport_adapter.parport_ecp_sync = atppc_ecp_sync;
  217         sc_parport_adapter.parport_read = atppc_read;
  218         sc_parport_adapter.parport_write = atppc_write;
  219         sc_parport_adapter.parport_read_ivar = atppc_read_ivar;
  220         sc_parport_adapter.parport_write_ivar = atppc_write_ivar;
  221         sc_parport_adapter.parport_dma_malloc = lsc->sc_dma_malloc;
  222         sc_parport_adapter.parport_dma_free = lsc->sc_dma_free;
  223         sc_parport_adapter.parport_add_handler = atppc_add_handler;
  224         sc_parport_adapter.parport_remove_handler = atppc_remove_handler;
  225 
  226         /* Initialize handler list, may be added to by grandchildren */
  227         SLIST_INIT(&(lsc->sc_handler_listhead));
  228 
  229         /* Initialize interrupt state */
  230         lsc->sc_irqstat = ATPPC_IRQ_NONE;
  231         lsc->sc_ecr_intr = lsc->sc_ctr_intr = lsc->sc_str_intr = 0;
  232 
  233         /* Disable DMA/interrupts (each ppbus driver selects usage itself) */
  234         lsc->sc_use = 0;
  235 
  236         /* Configure child of the device. */
  237         lsc->child = config_found(lsc->sc_dev, &(sc_parport_adapter),
  238                 atppc_print, CFARGS_NONE);
  239 
  240         return;
  241 }
  242 
  243 /* Soft configuration detach */
  244 int
  245 atppc_sc_detach(struct atppc_softc *lsc, int flag)
  246 {
  247         device_t dev = lsc->sc_dev;
  248 
  249         /* Detach children devices */
  250         if (config_detach(lsc->child, flag) && !(flag & DETACH_QUIET)) {
  251                 aprint_error_dev(dev, "not able to detach child device, ");
  252 
  253                 if (!(flag & DETACH_FORCE)) {
  254                         printf("cannot detach\n");
  255                         return 1;
  256                 } else {
  257                         printf("continuing (DETACH_FORCE)\n");
  258                 }
  259         }
  260 
  261         if (!(flag & DETACH_QUIET))
  262                 printf("%s detached", device_xname(dev));
  263 
  264         return 0;
  265 }
  266 
  267 /* Used by config_found() to print out device information */
  268 static int
  269 atppc_print(void *aux, const char *name)
  270 {
  271         /* Print out something on failure. */
  272         if (name != NULL) {
  273                 printf("%s: child devices", name);
  274                 return UNCONF;
  275         }
  276 
  277         return QUIET;
  278 }
  279 
  280 /*
  281  * Machine independent detection routines for atppc driver.
  282  */
  283 
  284 /* Detect parallel port I/O port: taken from FreeBSD code directly. */
  285 int
  286 atppc_detect_port(bus_space_tag_t iot, bus_space_handle_t ioh)
  287 {
  288         /*
  289          * Much shorter than scheme used by lpt_isa_probe() and lpt_port_test()
  290          * in original lpt driver.
  291          * Write to data register common to all controllers and read back the
  292          * values. Also tests control and status registers.
  293          */
  294 
  295         /*
  296          * Cannot use convenient macros because the device's config structure
  297          * may not have been created yet: major change from FreeBSD code.
  298          */
  299 
  300         int rval;
  301         u_int8_t ctr_sav, dtr_sav, str_sav;
  302 
  303         /* Store writtable registers' values and test if they can be read */
  304         str_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_STR);
  305         ctr_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_CTR);
  306         dtr_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_DTR);
  307         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  308                 BUS_SPACE_BARRIER_READ);
  309 
  310         /*
  311          * Ensure PS2 ports in output mode, also read back value of control
  312          * register.
  313          */
  314         bus_space_write_1(iot, ioh, ATPPC_SPP_CTR, 0x0c);
  315         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  316                 BUS_SPACE_BARRIER_WRITE);
  317 
  318         if (bus_space_read_1(iot, ioh, ATPPC_SPP_CTR) != 0x0c) {
  319                 rval = 0;
  320         } else {
  321                 /*
  322                  * Test if two values can be written and read from the data
  323                  * register.
  324                  */
  325                 bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  326                         BUS_SPACE_BARRIER_READ);
  327                 bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, 0xaa);
  328                 bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  329                         BUS_SPACE_BARRIER_WRITE);
  330                 if (bus_space_read_1(iot, ioh, ATPPC_SPP_DTR) != 0xaa) {
  331                         rval = 1;
  332                 } else {
  333                         /* Second value to test */
  334                         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  335                                 BUS_SPACE_BARRIER_READ);
  336                         bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, 0x55);
  337                         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  338                                 BUS_SPACE_BARRIER_WRITE);
  339                         if (bus_space_read_1(iot, ioh, ATPPC_SPP_DTR) != 0x55) {
  340                                 rval = 1;
  341                         } else {
  342                                 rval = 0;
  343                         }
  344                 }
  345 
  346         }
  347 
  348         /* Restore registers */
  349         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  350                 BUS_SPACE_BARRIER_READ);
  351         bus_space_write_1(iot, ioh, ATPPC_SPP_CTR, ctr_sav);
  352         bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, dtr_sav);
  353         bus_space_write_1(iot, ioh, ATPPC_SPP_STR, str_sav);
  354         bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
  355                 BUS_SPACE_BARRIER_WRITE);
  356 
  357         return rval;
  358 }
  359 
  360 /* Detect parallel port chipset. */
  361 static int
  362 atppc_detect_chipset(struct atppc_softc *atppc)
  363 {
  364         /* Try each detection routine. */
  365         int i, mode;
  366         for (i = 0; chipset_detect[i] != NULL; i++) {
  367                 if ((mode = chipset_detect[i](atppc)) != -1) {
  368                         atppc->sc_mode = mode;
  369                         return 0;
  370                 }
  371         }
  372 
  373         return 1;
  374 }
  375 
  376 /* Detect generic capabilities. */
  377 static int
  378 atppc_detect_generic(struct atppc_softc *atppc)
  379 {
  380         u_int8_t ecr_sav = atppc_r_ecr(atppc);
  381         u_int8_t ctr_sav = atppc_r_ctr(atppc);
  382         u_int8_t str_sav = atppc_r_str(atppc);
  383         u_int8_t tmp;
  384         atppc_barrier_r(atppc);
  385 
  386         /* Default to generic */
  387         atppc->sc_type = ATPPC_TYPE_GENERIC;
  388         atppc->sc_model = GENERIC;
  389 
  390         /* Check for ECP */
  391         tmp = atppc_r_ecr(atppc);
  392         atppc_barrier_r(atppc);
  393         if ((tmp & ATPPC_FIFO_EMPTY) && !(tmp & ATPPC_FIFO_FULL)) {
  394                 atppc_w_ecr(atppc, 0x34);
  395                 atppc_barrier_w(atppc);
  396                 tmp = atppc_r_ecr(atppc);
  397                 atppc_barrier_r(atppc);
  398                 if (tmp == 0x35) {
  399                         atppc->sc_has |= ATPPC_HAS_ECP;
  400                 }
  401         }
  402 
  403         /* Allow search for SMC style ECP+EPP mode */
  404         if (atppc->sc_has & ATPPC_HAS_ECP) {
  405                 atppc_w_ecr(atppc, ATPPC_ECR_EPP);
  406                 atppc_barrier_w(atppc);
  407         }
  408         /* Check for EPP by checking for timeout bit */
  409         if (atppc_check_epp_timeout(atppc->sc_dev) != 0) {
  410                 atppc->sc_has |= ATPPC_HAS_EPP;
  411                 atppc->sc_epp = ATPPC_EPP_1_9;
  412                 if (atppc->sc_has & ATPPC_HAS_ECP) {
  413                         /* SMC like chipset found */
  414                         atppc->sc_model = SMC_LIKE;
  415                         atppc->sc_type = ATPPC_TYPE_SMCLIKE;
  416                 }
  417         }
  418 
  419         /* Detect PS2 mode */
  420         if (atppc->sc_has & ATPPC_HAS_ECP) {
  421                 /* Put ECP port into PS2 mode */
  422                 atppc_w_ecr(atppc, ATPPC_ECR_PS2);
  423                 atppc_barrier_w(atppc);
  424         }
  425         /* Put PS2 port in input mode: writes should not be readable */
  426         atppc_w_ctr(atppc, 0x20);
  427         atppc_barrier_w(atppc);
  428         /*
  429          * Write two values to data port: if neither are read back,
  430          * bidirectional mode is functional.
  431          */
  432         atppc_w_dtr(atppc, 0xaa);
  433         atppc_barrier_w(atppc);
  434         tmp = atppc_r_dtr(atppc);
  435         atppc_barrier_r(atppc);
  436         if (tmp != 0xaa) {
  437                 atppc_w_dtr(atppc, 0x55);
  438                 atppc_barrier_w(atppc);
  439                 tmp = atppc_r_dtr(atppc);
  440                 atppc_barrier_r(atppc);
  441                 if (tmp != 0x55) {
  442                         atppc->sc_has |= ATPPC_HAS_PS2;
  443                 }
  444         }
  445 
  446         /* Restore to previous state */
  447         atppc_w_ecr(atppc, ecr_sav);
  448         atppc_w_ctr(atppc, ctr_sav);
  449         atppc_w_str(atppc, str_sav);
  450         atppc_barrier_w(atppc);
  451 
  452         return 0;
  453 }
  454 
  455 /*
  456  * Detect parallel port FIFO: taken from FreeBSD code directly.
  457  */
  458 static int
  459 atppc_detect_fifo(struct atppc_softc *atppc)
  460 {
  461 #ifdef ATPPC_DEBUG
  462         device_t dev = atppc->sc_dev;
  463 #endif
  464         u_int8_t ecr_sav;
  465         u_int8_t ctr_sav;
  466         u_int8_t str_sav;
  467         u_int8_t cc;
  468         short i;
  469 
  470         /* If there is no ECP mode, we cannot config a FIFO */
  471         if (!(atppc->sc_has & ATPPC_HAS_ECP)) {
  472                 return (EINVAL);
  473         }
  474 
  475         /* save registers */
  476         ecr_sav = atppc_r_ecr(atppc);
  477         ctr_sav = atppc_r_ctr(atppc);
  478         str_sav = atppc_r_str(atppc);
  479         atppc_barrier_r(atppc);
  480 
  481         /* Enter ECP configuration mode, no interrupt, no DMA */
  482         atppc_w_ecr(atppc, (ATPPC_ECR_CFG | ATPPC_SERVICE_INTR) &
  483                 ~ATPPC_ENABLE_DMA);
  484         atppc_barrier_w(atppc);
  485 
  486         /* read PWord size - transfers in FIFO mode must be PWord aligned */
  487         atppc->sc_pword = (atppc_r_cnfgA(atppc) & ATPPC_PWORD_MASK);
  488         atppc_barrier_r(atppc);
  489 
  490         /* XXX 16 and 32 bits implementations not supported */
  491         if (atppc->sc_pword != ATPPC_PWORD_8) {
  492                 ATPPC_DPRINTF(("%s(%s): FIFO PWord(%d) not supported.\n",
  493                         __func__, device_xname(dev), atppc->sc_pword));
  494                 goto error;
  495         }
  496 
  497         /* Byte mode, reverse direction, no interrupt, no DMA */
  498         atppc_w_ecr(atppc, ATPPC_ECR_PS2 | ATPPC_SERVICE_INTR);
  499         atppc_w_ctr(atppc, (ctr_sav & ~IRQENABLE) | PCD);
  500         /* enter ECP test mode, no interrupt, no DMA */
  501         atppc_w_ecr(atppc, ATPPC_ECR_TST | ATPPC_SERVICE_INTR);
  502         atppc_barrier_w(atppc);
  503 
  504         /* flush the FIFO */
  505         for (i = 0; i < 1024; i++) {
  506                 atppc_r_fifo(atppc);
  507                 atppc_barrier_r(atppc);
  508                 cc = atppc_r_ecr(atppc);
  509                 atppc_barrier_r(atppc);
  510                 if (cc & ATPPC_FIFO_EMPTY)
  511                         break;
  512         }
  513         if (i >= 1024) {
  514                 ATPPC_DPRINTF(("%s(%s): cannot flush FIFO.\n", __func__,
  515                         device_xname(dev)));
  516                 goto error;
  517         }
  518 
  519         /* Test mode, enable interrupts, no DMA */
  520         atppc_w_ecr(atppc, ATPPC_ECR_TST);
  521         atppc_barrier_w(atppc);
  522 
  523         /* Determine readIntrThreshold - fill FIFO until serviceIntr is set */
  524         for (i = atppc->sc_rthr = atppc->sc_fifo = 0; i < 1024; i++) {
  525                 atppc_w_fifo(atppc, (char)i);
  526                 atppc_barrier_w(atppc);
  527                 cc = atppc_r_ecr(atppc);
  528                 atppc_barrier_r(atppc);
  529                 if ((atppc->sc_rthr == 0) && (cc & ATPPC_SERVICE_INTR)) {
  530                         /* readThreshold reached */
  531                         atppc->sc_rthr = i + 1;
  532                 }
  533                 if (cc & ATPPC_FIFO_FULL) {
  534                         atppc->sc_fifo = i + 1;
  535                         break;
  536                 }
  537         }
  538         if (i >= 1024) {
  539                 ATPPC_DPRINTF(("%s(%s): cannot fill FIFO.\n", __func__,
  540                         device_xname(dev)));
  541                 goto error;
  542         }
  543 
  544         /* Change direction */
  545         atppc_w_ctr(atppc, (ctr_sav & ~IRQENABLE) & ~PCD);
  546         atppc_barrier_w(atppc);
  547 
  548         /* Clear the serviceIntr bit we've already set in the above loop */
  549         atppc_w_ecr(atppc, ATPPC_ECR_TST);
  550         atppc_barrier_w(atppc);
  551 
  552         /* Determine writeIntrThreshold - empty FIFO until serviceIntr is set */
  553         for (atppc->sc_wthr = 0; i > -1; i--) {
  554                 cc = atppc_r_fifo(atppc);
  555                 atppc_barrier_r(atppc);
  556                 if (cc != (char)(atppc->sc_fifo - i - 1)) {
  557                         ATPPC_DPRINTF(("%s(%s): invalid data in FIFO.\n",
  558                                 __func__, device_xname(dev)));
  559                         goto error;
  560                 }
  561 
  562                 cc = atppc_r_ecr(atppc);
  563                 atppc_barrier_r(atppc);
  564                 if ((atppc->sc_wthr == 0) && (cc & ATPPC_SERVICE_INTR)) {
  565                         /* writeIntrThreshold reached */
  566                         atppc->sc_wthr = atppc->sc_fifo - i;
  567                 }
  568 
  569                 if (i > 0 && (cc & ATPPC_FIFO_EMPTY)) {
  570                         /* If FIFO empty before the last byte, error */
  571                         ATPPC_DPRINTF(("%s(%s): data lost in FIFO.\n", __func__,
  572                                 device_xname(dev)));
  573                         goto error;
  574                 }
  575         }
  576 
  577         /* FIFO must be empty after the last byte */
  578         cc = atppc_r_ecr(atppc);
  579         atppc_barrier_r(atppc);
  580         if (!(cc & ATPPC_FIFO_EMPTY)) {
  581                 ATPPC_DPRINTF(("%s(%s): cannot empty the FIFO.\n", __func__,
  582                         device_xname(dev)));
  583                 goto error;
  584         }
  585 
  586         /* Restore original registers */
  587         atppc_w_ctr(atppc, ctr_sav);
  588         atppc_w_str(atppc, str_sav);
  589         atppc_w_ecr(atppc, ecr_sav);
  590         atppc_barrier_w(atppc);
  591 
  592         /* Update capabilities */
  593         atppc->sc_has |= ATPPC_HAS_FIFO;
  594 
  595         return 0;
  596 
  597 error:
  598         /* Restore original registers */
  599         atppc_w_ctr(atppc, ctr_sav);
  600         atppc_w_str(atppc, str_sav);
  601         atppc_w_ecr(atppc, ecr_sav);
  602         atppc_barrier_w(atppc);
  603 
  604         return (EINVAL);
  605 }
  606 
  607 /* Interrupt handler for atppc device: wakes up read/write functions */
  608 int
  609 atppcintr(void *arg)
  610 {
  611         device_t dev = arg;
  612         struct atppc_softc *atppc = device_private(dev);
  613         int claim = 1;
  614         enum { NONE, READER, WRITER } wake_up = NONE;
  615 
  616         mutex_enter(&atppc->sc_lock);
  617 
  618         /* Record registers' status */
  619         atppc->sc_str_intr = atppc_r_str(atppc);
  620         atppc->sc_ctr_intr = atppc_r_ctr(atppc);
  621         atppc->sc_ecr_intr = atppc_r_ecr(atppc);
  622         atppc_barrier_r(atppc);
  623 
  624         /* Determine cause of interrupt and wake up top half */
  625         switch (atppc->sc_mode) {
  626         case ATPPC_MODE_STD:
  627                 /* nAck pulsed for 5 usec, too fast to check reliably, assume */
  628                 atppc->sc_irqstat = ATPPC_IRQ_nACK;
  629                 if (atppc->sc_outb)
  630                         wake_up = WRITER;
  631                 else
  632                         claim = 0;
  633                 break;
  634 
  635         case ATPPC_MODE_NIBBLE:
  636         case ATPPC_MODE_PS2:
  637                 /* nAck is set low by device and then high on ack */
  638                 if (!(atppc->sc_str_intr & nACK)) {
  639                         claim = 0;
  640                         break;
  641                 }
  642                 atppc->sc_irqstat = ATPPC_IRQ_nACK;
  643                 if (atppc->sc_inb)
  644                         wake_up = READER;
  645                 break;
  646 
  647         case ATPPC_MODE_ECP:
  648         case ATPPC_MODE_FAST:
  649                 /* Confirm interrupt cause: these are not pulsed as in nAck. */
  650                 if (atppc->sc_ecr_intr & ATPPC_SERVICE_INTR) {
  651                         if (atppc->sc_ecr_intr & ATPPC_ENABLE_DMA)
  652                                 atppc->sc_irqstat |= ATPPC_IRQ_DMA;
  653                         else
  654                                 atppc->sc_irqstat |= ATPPC_IRQ_FIFO;
  655 
  656                         /* Decide where top half will be waiting */
  657                         if (atppc->sc_mode & ATPPC_MODE_ECP) {
  658                                 if (atppc->sc_ctr_intr & PCD) {
  659                                         if (atppc->sc_inb)
  660                                                 wake_up = READER;
  661                                         else
  662                                                 claim = 0;
  663                                 } else {
  664                                         if (atppc->sc_outb)
  665                                                 wake_up = WRITER;
  666                                         else
  667                                                 claim = 0;
  668                                 }
  669                         } else {
  670                                 if (atppc->sc_outb)
  671                                         wake_up = WRITER;
  672                                 else
  673                                         claim = 0;
  674                         }
  675                 }
  676                 /* Determine if nFault has occurred */
  677                 if ((atppc->sc_mode & ATPPC_MODE_ECP) &&
  678                         (atppc->sc_ecr_intr & ATPPC_nFAULT_INTR) &&
  679                         !(atppc->sc_str_intr & nFAULT)) {
  680 
  681                         /* Device is requesting the channel */
  682                         atppc->sc_irqstat |= ATPPC_IRQ_nFAULT;
  683                         claim = 1;
  684                 }
  685                 break;
  686 
  687         case ATPPC_MODE_EPP:
  688                 /* nAck pulsed for 5 usec, too fast to check reliably */
  689                 atppc->sc_irqstat = ATPPC_IRQ_nACK;
  690                 if (atppc->sc_inb)
  691                         wake_up = WRITER;
  692                 else if (atppc->sc_outb)
  693                         wake_up = READER;
  694                 else
  695                         claim = 0;
  696                 break;
  697 
  698         default:
  699                 panic("%s: chipset is in invalid mode.", device_xname(dev));
  700         }
  701 
  702         if (claim) {
  703                 switch (wake_up) {
  704                 case NONE:
  705                         break;
  706 
  707                 case READER:
  708                         cv_broadcast(&atppc->sc_in_cv);
  709                         break;
  710 
  711                 case WRITER:
  712                         cv_broadcast(&atppc->sc_out_cv);
  713                         break;
  714                 }
  715         }
  716 
  717         /* Call all of the installed handlers */
  718         if (claim) {
  719                 struct atppc_handler_node * callback;
  720                 SLIST_FOREACH(callback, &(atppc->sc_handler_listhead),
  721                         entries) {
  722                                 (*callback->func)(callback->arg);
  723                 }
  724         }
  725 
  726         mutex_exit(&atppc->sc_lock);
  727 
  728         return claim;
  729 }
  730 
  731 
  732 /* Functions which support ppbus interface */
  733 
  734 
  735 /* Check EPP mode timeout */
  736 static int
  737 atppc_check_epp_timeout(device_t dev)
  738 {
  739         struct atppc_softc *atppc = device_private(dev);
  740         int error;
  741 
  742         mutex_enter(&atppc->sc_lock);
  743 
  744         atppc_reset_epp_timeout(dev);
  745         error = !(atppc_r_str(atppc) & TIMEOUT);
  746         atppc_barrier_r(atppc);
  747 
  748         mutex_exit(&atppc->sc_lock);
  749 
  750         return (error);
  751 }
  752 
  753 /*
  754  * EPP timeout, according to the PC87332 manual
  755  * Semantics of clearing EPP timeout bit.
  756  * PC87332      - reading SPP_STR does it...
  757  * SMC          - write 1 to EPP timeout bit                    XXX
  758  * Others       - (?) write 0 to EPP timeout bit
  759  */
  760 static void
  761 atppc_reset_epp_timeout(device_t dev)
  762 {
  763         struct atppc_softc *atppc = device_private(dev);
  764         register unsigned char r;
  765 
  766         r = atppc_r_str(atppc);
  767         atppc_barrier_r(atppc);
  768         atppc_w_str(atppc, r | 0x1);
  769         atppc_barrier_w(atppc);
  770         atppc_w_str(atppc, r & 0xfe);
  771         atppc_barrier_w(atppc);
  772 
  773         return;
  774 }
  775 
  776 
  777 /* Read from atppc device: returns 0 on success. */
  778 static int
  779 atppc_read(device_t dev, char *buf, int len, int ioflag,
  780         size_t *cnt)
  781 {
  782         struct atppc_softc *atppc = device_private(dev);
  783         int error = 0;
  784 
  785         mutex_enter(&atppc->sc_lock);
  786 
  787         *cnt = 0;
  788 
  789         /* Initialize buffer */
  790         atppc->sc_inb = atppc->sc_inbstart = buf;
  791         atppc->sc_inb_nbytes = len;
  792 
  793         /* Initialize device input error state for new operation */
  794         atppc->sc_inerr = 0;
  795 
  796         /* Call appropriate function to read bytes */
  797         switch(atppc->sc_mode) {
  798         case ATPPC_MODE_STD:
  799         case ATPPC_MODE_FAST:
  800                 error = ENODEV;
  801                 break;
  802 
  803         case ATPPC_MODE_NIBBLE:
  804                 atppc_nibble_read(atppc);
  805                 break;
  806 
  807         case ATPPC_MODE_PS2:
  808                 atppc_byte_read(atppc);
  809                 break;
  810 
  811         case ATPPC_MODE_ECP:
  812                 atppc_ecp_read(atppc);
  813                 break;
  814 
  815         case ATPPC_MODE_EPP:
  816                 atppc_epp_read(atppc);
  817                 break;
  818 
  819         default:
  820                 panic("%s(%s): chipset in invalid mode.\n", __func__,
  821                         device_xname(dev));
  822         }
  823 
  824         /* Update counter*/
  825         *cnt = (atppc->sc_inbstart - atppc->sc_inb);
  826 
  827         /* Reset buffer */
  828         atppc->sc_inb = atppc->sc_inbstart = NULL;
  829         atppc->sc_inb_nbytes = 0;
  830 
  831         if (!(error))
  832                 error = atppc->sc_inerr;
  833 
  834         mutex_exit(&atppc->sc_lock);
  835 
  836         return (error);
  837 }
  838 
  839 /* Write to atppc device: returns 0 on success. */
  840 static int
  841 atppc_write(device_t dev, char *buf, int len, int ioflag, size_t *cnt)
  842 {
  843         struct atppc_softc * const atppc = device_private(dev);
  844         int error = 0;
  845 
  846         *cnt = 0;
  847 
  848         mutex_enter(&atppc->sc_lock);
  849 
  850         /* Set up line buffer */
  851         atppc->sc_outb = atppc->sc_outbstart = buf;
  852         atppc->sc_outb_nbytes = len;
  853 
  854         /* Initialize device output error state for new operation */
  855         atppc->sc_outerr = 0;
  856 
  857         /* Call appropriate function to write bytes */
  858         switch (atppc->sc_mode) {
  859         case ATPPC_MODE_STD:
  860                 atppc_std_write(atppc);
  861                 break;
  862 
  863         case ATPPC_MODE_NIBBLE:
  864         case ATPPC_MODE_PS2:
  865                 error = ENODEV;
  866                 break;
  867 
  868         case ATPPC_MODE_FAST:
  869         case ATPPC_MODE_ECP:
  870                 atppc_fifo_write(atppc);
  871                 break;
  872 
  873         case ATPPC_MODE_EPP:
  874                 atppc_epp_write(atppc);
  875                 break;
  876 
  877         default:
  878                 panic("%s(%s): chipset in invalid mode.\n", __func__,
  879                         device_xname(dev));
  880         }
  881 
  882         /* Update counter*/
  883         *cnt = (atppc->sc_outbstart - atppc->sc_outb);
  884 
  885         /* Reset output buffer */
  886         atppc->sc_outb = atppc->sc_outbstart = NULL;
  887         atppc->sc_outb_nbytes = 0;
  888 
  889         if (!(error))
  890                 error = atppc->sc_outerr;
  891 
  892         mutex_exit(&atppc->sc_lock);
  893 
  894         return (error);
  895 }
  896 
  897 /*
  898  * Set mode of chipset to mode argument. Modes not supported are ignored. If
  899  * multiple modes are flagged, the mode is not changed. Mode's are those
  900  * defined for ppbus_softc.sc_mode in ppbus_conf.h. Only ECP-capable chipsets
  901  * can change their mode of operation. However, ALL operation modes support
  902  * centronics mode and nibble mode. Modes determine both hardware AND software
  903  * behaviour.
  904  * NOTE: the mode for ECP should only be changed when the channel is in
  905  * forward idle mode. This function does not make sure FIFO's have flushed or
  906  * any consistency checks.
  907  */
  908 static int
  909 atppc_setmode(device_t dev, int mode)
  910 {
  911         struct atppc_softc *atppc = device_private(dev);
  912         u_int8_t ecr;
  913         u_int8_t chipset_mode;
  914         int rval = 0;
  915 
  916         mutex_enter(&atppc->sc_lock);
  917 
  918         /* If ECP capable, configure ecr register */
  919         if (atppc->sc_has & ATPPC_HAS_ECP) {
  920                 /* Read ECR with mode masked out */
  921                 ecr = (atppc_r_ecr(atppc) & 0x1f);
  922                 atppc_barrier_r(atppc);
  923 
  924                 switch (mode) {
  925                 case PPBUS_ECP:
  926                         /* Set ECP mode */
  927                         ecr |= ATPPC_ECR_ECP;
  928                         chipset_mode = ATPPC_MODE_ECP;
  929                         break;
  930 
  931                 case PPBUS_EPP:
  932                         /* Set EPP mode */
  933                         if (atppc->sc_has & ATPPC_HAS_EPP) {
  934                                 ecr |= ATPPC_ECR_EPP;
  935                                 chipset_mode = ATPPC_MODE_EPP;
  936                         } else {
  937                                 rval = ENODEV;
  938                                 goto end;
  939                         }
  940                         break;
  941 
  942                 case PPBUS_FAST:
  943                         /* Set fast centronics mode */
  944                         ecr |= ATPPC_ECR_FIFO;
  945                         chipset_mode = ATPPC_MODE_FAST;
  946                         break;
  947 
  948                 case PPBUS_PS2:
  949                         /* Set PS2 mode */
  950                         ecr |= ATPPC_ECR_PS2;
  951                         chipset_mode = ATPPC_MODE_PS2;
  952                         break;
  953 
  954                 case PPBUS_COMPATIBLE:
  955                         /* Set standard mode */
  956                         ecr |= ATPPC_ECR_STD;
  957                         chipset_mode = ATPPC_MODE_STD;
  958                         break;
  959 
  960                 case PPBUS_NIBBLE:
  961                         /* Set nibble mode: uses chipset standard mode */
  962                         ecr |= ATPPC_ECR_STD;
  963                         chipset_mode = ATPPC_MODE_NIBBLE;
  964                         break;
  965 
  966                 default:
  967                         /* Invalid mode specified for ECP chip */
  968                         ATPPC_DPRINTF(("%s(%s): invalid mode passed as "
  969                                 "argument.\n", __func__, device_xname(dev)));
  970                         rval = ENODEV;
  971                         goto end;
  972                 }
  973 
  974                 /* Switch to byte mode to be able to change modes. */
  975                 atppc_w_ecr(atppc, ATPPC_ECR_PS2);
  976                 atppc_barrier_w(atppc);
  977 
  978                 /* Update mode */
  979                 atppc_w_ecr(atppc, ecr);
  980                 atppc_barrier_w(atppc);
  981         } else {
  982                 switch (mode) {
  983                 case PPBUS_EPP:
  984                         if (atppc->sc_has & ATPPC_HAS_EPP) {
  985                                 chipset_mode = ATPPC_MODE_EPP;
  986                         } else {
  987                                 rval = ENODEV;
  988                                 goto end;
  989                         }
  990                         break;
  991 
  992                 case PPBUS_PS2:
  993                         if (atppc->sc_has & ATPPC_HAS_PS2) {
  994                                 chipset_mode = ATPPC_MODE_PS2;
  995                         } else {
  996                                 rval = ENODEV;
  997                                 goto end;
  998                         }
  999                         break;
 1000 
 1001                 case PPBUS_NIBBLE:
 1002                         /* Set nibble mode (virtual) */
 1003                         chipset_mode = ATPPC_MODE_NIBBLE;
 1004                         break;
 1005 
 1006                 case PPBUS_COMPATIBLE:
 1007                         chipset_mode = ATPPC_MODE_STD;
 1008                         break;
 1009 
 1010                 case PPBUS_ECP:
 1011                         rval = ENODEV;
 1012                         goto end;
 1013 
 1014                 default:
 1015                         ATPPC_DPRINTF(("%s(%s): invalid mode passed as "
 1016                                 "argument.\n", __func__, device_xname(dev)));
 1017                         rval = ENODEV;
 1018                         goto end;
 1019                 }
 1020         }
 1021 
 1022         atppc->sc_mode = chipset_mode;
 1023         if (chipset_mode == ATPPC_MODE_PS2) {
 1024                 /* Set direction bit to reverse */
 1025                 ecr = atppc_r_ctr(atppc);
 1026                 atppc_barrier_r(atppc);
 1027                 ecr |= PCD;
 1028                 atppc_w_ctr(atppc, ecr);
 1029                 atppc_barrier_w(atppc);
 1030         }
 1031 
 1032 end:
 1033         mutex_exit(&atppc->sc_lock);
 1034 
 1035         return rval;
 1036 }
 1037 
 1038 /* Get the current mode of chipset */
 1039 static int
 1040 atppc_getmode(device_t dev)
 1041 {
 1042         struct atppc_softc *atppc = device_private(dev);
 1043         int mode;
 1044 
 1045         mutex_enter(&atppc->sc_lock);
 1046 
 1047         /* The chipset can only be in one mode at a time logically */
 1048         switch (atppc->sc_mode) {
 1049         case ATPPC_MODE_ECP:
 1050                 mode = PPBUS_ECP;
 1051                 break;
 1052 
 1053         case ATPPC_MODE_EPP:
 1054                 mode = PPBUS_EPP;
 1055                 break;
 1056 
 1057         case ATPPC_MODE_PS2:
 1058                 mode = PPBUS_PS2;
 1059                 break;
 1060 
 1061         case ATPPC_MODE_STD:
 1062                 mode = PPBUS_COMPATIBLE;
 1063                 break;
 1064 
 1065         case ATPPC_MODE_NIBBLE:
 1066                 mode = PPBUS_NIBBLE;
 1067                 break;
 1068 
 1069         case ATPPC_MODE_FAST:
 1070                 mode = PPBUS_FAST;
 1071                 break;
 1072 
 1073         default:
 1074                 panic("%s(%s): device is in invalid mode!", __func__,
 1075                         device_xname(dev));
 1076                 break;
 1077         }
 1078 
 1079         mutex_exit(&atppc->sc_lock);
 1080 
 1081         return mode;
 1082 }
 1083 
 1084 
 1085 /* Wait for FIFO buffer to empty for ECP-capable chipset */
 1086 static void
 1087 atppc_ecp_sync(device_t dev)
 1088 {
 1089         struct atppc_softc *atppc = device_private(dev);
 1090         int i;
 1091         u_int8_t r;
 1092 
 1093         mutex_enter(&atppc->sc_lock);
 1094 
 1095         /*
 1096          * Only wait for FIFO to empty if mode is chipset is ECP-capable AND
 1097          * the mode is either ECP or Fast Centronics.
 1098          */
 1099         r = atppc_r_ecr(atppc);
 1100         atppc_barrier_r(atppc);
 1101         r &= 0xe0;
 1102         if (!(atppc->sc_has & ATPPC_HAS_ECP) || ((r != ATPPC_ECR_ECP)
 1103                 && (r != ATPPC_ECR_FIFO))) {
 1104                 goto end;
 1105         }
 1106 
 1107         /* Wait for FIFO to empty */
 1108         for (i = 0; i < ((MAXBUSYWAIT/hz) * 1000000); i += 100) {
 1109                 r = atppc_r_ecr(atppc);
 1110                 atppc_barrier_r(atppc);
 1111                 if (r & ATPPC_FIFO_EMPTY) {
 1112                         goto end;
 1113                 }
 1114                 delay(100); /* Supposed to be a 100 usec delay */
 1115         }
 1116 
 1117         ATPPC_DPRINTF(("%s: ECP sync failed, data still in FIFO.\n",
 1118                 device_xname(dev)));
 1119 
 1120 end:
 1121         mutex_exit(&atppc->sc_lock);
 1122 
 1123         return;
 1124 }
 1125 
 1126 /* Execute a microsequence to handle fast I/O operations. */
 1127 static int
 1128 atppc_exec_microseq(device_t dev, struct ppbus_microseq **p_msq)
 1129 {
 1130         struct atppc_softc *atppc = device_private(dev);
 1131         struct ppbus_microseq *mi = *p_msq;
 1132         char cc, *p;
 1133         int i, iter, len;
 1134         int error;
 1135         register int reg;
 1136         register unsigned char mask;
 1137         register int accum = 0;
 1138         register char *ptr = NULL;
 1139         struct ppbus_microseq *stack = NULL;
 1140 
 1141         mutex_enter(&atppc->sc_lock);
 1142 
 1143 /* microsequence registers are equivalent to PC-like port registers */
 1144 
 1145 #define r_reg(register,atppc) bus_space_read_1((atppc)->sc_iot, \
 1146         (atppc)->sc_ioh, (register))
 1147 #define w_reg(register, atppc, byte) bus_space_write_1((atppc)->sc_iot, \
 1148         (atppc)->sc_ioh, (register), (byte))
 1149 
 1150         /* Loop until microsequence execution finishes (ending op code) */
 1151         for (;;) {
 1152                 switch (mi->opcode) {
 1153                 case MS_OP_RSET:
 1154                         cc = r_reg(mi->arg[0].i, atppc);
 1155                         atppc_barrier_r(atppc);
 1156                         cc &= (char)mi->arg[2].i;       /* clear mask */
 1157                         cc |= (char)mi->arg[1].i;       /* assert mask */
 1158                         w_reg(mi->arg[0].i, atppc, cc);
 1159                         atppc_barrier_w(atppc);
 1160                         mi++;
 1161                         break;
 1162 
 1163                 case MS_OP_RASSERT_P:
 1164                         reg = mi->arg[1].i;
 1165                         ptr = atppc->sc_ptr;
 1166 
 1167                         if ((len = mi->arg[0].i) == MS_ACCUM) {
 1168                                 accum = atppc->sc_accum;
 1169                                 for (; accum; accum--) {
 1170                                         w_reg(reg, atppc, *ptr++);
 1171                                         atppc_barrier_w(atppc);
 1172                                 }
 1173                                 atppc->sc_accum = accum;
 1174                         } else {
 1175                                 for (i = 0; i < len; i++) {
 1176                                         w_reg(reg, atppc, *ptr++);
 1177                                         atppc_barrier_w(atppc);
 1178                                 }
 1179                         }
 1180 
 1181                         atppc->sc_ptr = ptr;
 1182                         mi++;
 1183                         break;
 1184 
 1185                 case MS_OP_RFETCH_P:
 1186                         reg = mi->arg[1].i;
 1187                         mask = (char)mi->arg[2].i;
 1188                         ptr = atppc->sc_ptr;
 1189 
 1190                         if ((len = mi->arg[0].i) == MS_ACCUM) {
 1191                                 accum = atppc->sc_accum;
 1192                                 for (; accum; accum--) {
 1193                                         *ptr++ = r_reg(reg, atppc) & mask;
 1194                                         atppc_barrier_r(atppc);
 1195                                 }
 1196                                 atppc->sc_accum = accum;
 1197                         } else {
 1198                                 for (i = 0; i < len; i++) {
 1199                                         *ptr++ = r_reg(reg, atppc) & mask;
 1200                                         atppc_barrier_r(atppc);
 1201                                 }
 1202                         }
 1203 
 1204                         atppc->sc_ptr = ptr;
 1205                         mi++;
 1206                         break;
 1207 
 1208                 case MS_OP_RFETCH:
 1209                         *((char *)mi->arg[2].p) = r_reg(mi->arg[0].i, atppc) &
 1210                                 (char)mi->arg[1].i;
 1211                         atppc_barrier_r(atppc);
 1212                         mi++;
 1213                         break;
 1214 
 1215                 case MS_OP_RASSERT:
 1216                 case MS_OP_DELAY:
 1217                         /* let's suppose the next instr. is the same */
 1218                         do {
 1219                                 for (;mi->opcode == MS_OP_RASSERT; mi++) {
 1220                                         w_reg(mi->arg[0].i, atppc,
 1221                                                 (char)mi->arg[1].i);
 1222                                         atppc_barrier_w(atppc);
 1223                                 }
 1224 
 1225                                 for (;mi->opcode == MS_OP_DELAY; mi++) {
 1226                                         delay(mi->arg[0].i);
 1227                                 }
 1228                         } while (mi->opcode == MS_OP_RASSERT);
 1229                         break;
 1230 
 1231                 case MS_OP_ADELAY:
 1232                         if (mi->arg[0].i) {
 1233                                 tsleep(atppc, PPBUSPRI, "atppcdelay",
 1234                                         mi->arg[0].i * (hz/1000));
 1235                         }
 1236                         mi++;
 1237                         break;
 1238 
 1239                 case MS_OP_TRIG:
 1240                         reg = mi->arg[0].i;
 1241                         iter = mi->arg[1].i;
 1242                         p = (char *)mi->arg[2].p;
 1243 
 1244                         /* XXX delay limited to 255 us */
 1245                         for (i = 0; i < iter; i++) {
 1246                                 w_reg(reg, atppc, *p++);
 1247                                 atppc_barrier_w(atppc);
 1248                                 delay((unsigned char)*p++);
 1249                         }
 1250 
 1251                         mi++;
 1252                         break;
 1253 
 1254                 case MS_OP_SET:
 1255                         atppc->sc_accum = mi->arg[0].i;
 1256                         mi++;
 1257                         break;
 1258 
 1259                 case MS_OP_DBRA:
 1260                         if (--atppc->sc_accum > 0) {
 1261                                 mi += mi->arg[0].i;
 1262                         }
 1263 
 1264                         mi++;
 1265                         break;
 1266 
 1267                 case MS_OP_BRSET:
 1268                         cc = atppc_r_str(atppc);
 1269                         atppc_barrier_r(atppc);
 1270                         if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) {
 1271                                 mi += mi->arg[1].i;
 1272                         }
 1273                         mi++;
 1274                         break;
 1275 
 1276                 case MS_OP_BRCLEAR:
 1277                         cc = atppc_r_str(atppc);
 1278                         atppc_barrier_r(atppc);
 1279                         if ((cc & (char)mi->arg[0].i) == 0) {
 1280                                 mi += mi->arg[1].i;
 1281                         }
 1282                         mi++;
 1283                         break;
 1284 
 1285                 case MS_OP_BRSTAT:
 1286                         cc = atppc_r_str(atppc);
 1287                         atppc_barrier_r(atppc);
 1288                         if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
 1289                                 (char)mi->arg[0].i) {
 1290                                 mi += mi->arg[2].i;
 1291                         }
 1292                         mi++;
 1293                         break;
 1294 
 1295                 case MS_OP_C_CALL:
 1296                         /*
 1297                          * If the C call returns !0 then end the microseq.
 1298                          * The current state of ptr is passed to the C function
 1299                          */
 1300                         if ((error = mi->arg[0].f(mi->arg[1].p,
 1301                                 atppc->sc_ptr))) {
 1302                                 mutex_exit(&atppc->sc_lock);
 1303                                 return (error);
 1304                         }
 1305                         mi++;
 1306                         break;
 1307 
 1308                 case MS_OP_PTR:
 1309                         atppc->sc_ptr = (char *)mi->arg[0].p;
 1310                         mi++;
 1311                         break;
 1312 
 1313                 case MS_OP_CALL:
 1314                         if (stack) {
 1315                                 panic("%s - %s: too much calls", device_xname(dev),
 1316                                         __func__);
 1317                         }
 1318 
 1319                         if (mi->arg[0].p) {
 1320                                 /* store state of the actual microsequence */
 1321                                 stack = mi;
 1322 
 1323                                 /* jump to the new microsequence */
 1324                                 mi = (struct ppbus_microseq *)mi->arg[0].p;
 1325                         } else {
 1326                                 mi++;
 1327                         }
 1328                         break;
 1329 
 1330                 case MS_OP_SUBRET:
 1331                         /* retrieve microseq and pc state before the call */
 1332                         mi = stack;
 1333 
 1334                         /* reset the stack */
 1335                         stack = 0;
 1336 
 1337                         /* XXX return code */
 1338 
 1339                         mi++;
 1340                         break;
 1341 
 1342                 case MS_OP_PUT:
 1343                 case MS_OP_GET:
 1344                 case MS_OP_RET:
 1345                         /*
 1346                          * Can't return to atppc level during the execution
 1347                          * of a submicrosequence.
 1348                          */
 1349                         if (stack) {
 1350                                 panic("%s: cannot return to atppc level",
 1351                                         __func__);
 1352                         }
 1353                         /* update pc for atppc level of execution */
 1354                         *p_msq = mi;
 1355 
 1356                         mutex_exit(&atppc->sc_lock);
 1357                         return (0);
 1358                         break;
 1359 
 1360                 default:
 1361                         panic("%s: unknown microsequence "
 1362                                 "opcode 0x%x", __func__, mi->opcode);
 1363                         break;
 1364                 }
 1365         }
 1366 
 1367         /* Should not be reached! */
 1368 #ifdef ATPPC_DEBUG
 1369         panic("%s: unexpected code reached!\n", __func__);
 1370 #endif
 1371 }
 1372 
 1373 /* General I/O routine */
 1374 static u_int8_t
 1375 atppc_io(device_t dev, int iop, u_char *addr, int cnt, u_char byte)
 1376 {
 1377         struct atppc_softc *atppc = device_private(dev);
 1378         u_int8_t val = 0;
 1379 
 1380         mutex_enter(&atppc->sc_lock);
 1381 
 1382         switch (iop) {
 1383         case PPBUS_OUTSB_EPP:
 1384                 bus_space_write_multi_1(atppc->sc_iot, atppc->sc_ioh,
 1385                         ATPPC_EPP_DATA, addr, cnt);
 1386                 break;
 1387         case PPBUS_OUTSW_EPP:
 1388                 bus_space_write_multi_2(atppc->sc_iot, atppc->sc_ioh,
 1389                         ATPPC_EPP_DATA, (u_int16_t *)addr, cnt);
 1390                 break;
 1391         case PPBUS_OUTSL_EPP:
 1392                 bus_space_write_multi_4(atppc->sc_iot, atppc->sc_ioh,
 1393                         ATPPC_EPP_DATA, (u_int32_t *)addr, cnt);
 1394                 break;
 1395         case PPBUS_INSB_EPP:
 1396                 bus_space_read_multi_1(atppc->sc_iot, atppc->sc_ioh,
 1397                         ATPPC_EPP_DATA, addr, cnt);
 1398                 break;
 1399         case PPBUS_INSW_EPP:
 1400                 bus_space_read_multi_2(atppc->sc_iot, atppc->sc_ioh,
 1401                         ATPPC_EPP_DATA, (u_int16_t *)addr, cnt);
 1402                 break;
 1403         case PPBUS_INSL_EPP:
 1404                 bus_space_read_multi_4(atppc->sc_iot, atppc->sc_ioh,
 1405                         ATPPC_EPP_DATA, (u_int32_t *)addr, cnt);
 1406                 break;
 1407         case PPBUS_RDTR:
 1408                 val = (atppc_r_dtr(atppc));
 1409                 break;
 1410         case PPBUS_RSTR:
 1411                 val = (atppc_r_str(atppc));
 1412                 break;
 1413         case PPBUS_RCTR:
 1414                 val = (atppc_r_ctr(atppc));
 1415                 break;
 1416         case PPBUS_REPP_A:
 1417                 val = (atppc_r_eppA(atppc));
 1418                 break;
 1419         case PPBUS_REPP_D:
 1420                 val = (atppc_r_eppD(atppc));
 1421                 break;
 1422         case PPBUS_RECR:
 1423                 val = (atppc_r_ecr(atppc));
 1424                 break;
 1425         case PPBUS_RFIFO:
 1426                 val = (atppc_r_fifo(atppc));
 1427                 break;
 1428         case PPBUS_WDTR:
 1429                 atppc_w_dtr(atppc, byte);
 1430                 break;
 1431         case PPBUS_WSTR:
 1432                 atppc_w_str(atppc, byte);
 1433                 break;
 1434         case PPBUS_WCTR:
 1435                 atppc_w_ctr(atppc, byte);
 1436                 break;
 1437         case PPBUS_WEPP_A:
 1438                 atppc_w_eppA(atppc, byte);
 1439                 break;
 1440         case PPBUS_WEPP_D:
 1441                 atppc_w_eppD(atppc, byte);
 1442                 break;
 1443         case PPBUS_WECR:
 1444                 atppc_w_ecr(atppc, byte);
 1445                 break;
 1446         case PPBUS_WFIFO:
 1447                 atppc_w_fifo(atppc, byte);
 1448                 break;
 1449         default:
 1450                 panic("%s(%s): unknown I/O operation", device_xname(dev),
 1451                         __func__);
 1452                 break;
 1453         }
 1454 
 1455         atppc_barrier(atppc);
 1456 
 1457         mutex_exit(&atppc->sc_lock);
 1458 
 1459         return val;
 1460 }
 1461 
 1462 /* Read "instance variables" of atppc device */
 1463 static int
 1464 atppc_read_ivar(device_t dev, int index, unsigned int *val)
 1465 {
 1466         struct atppc_softc *atppc = device_private(dev);
 1467         int rval = 0;
 1468 
 1469         mutex_enter(&atppc->sc_lock);
 1470 
 1471         switch(index) {
 1472         case PPBUS_IVAR_EPP_PROTO:
 1473                 if (atppc->sc_epp == ATPPC_EPP_1_9)
 1474                         *val = PPBUS_EPP_1_9;
 1475                 else if (atppc->sc_epp == ATPPC_EPP_1_7)
 1476                         *val = PPBUS_EPP_1_7;
 1477                 /* XXX what if not using EPP ? */
 1478                 break;
 1479 
 1480         case PPBUS_IVAR_INTR:
 1481                 *val = ((atppc->sc_use & ATPPC_USE_INTR) != 0);
 1482                 break;
 1483 
 1484         case PPBUS_IVAR_DMA:
 1485                 *val = ((atppc->sc_use & ATPPC_USE_DMA) != 0);
 1486                 break;
 1487 
 1488         default:
 1489                 rval = ENODEV;
 1490         }
 1491 
 1492         mutex_exit(&atppc->sc_lock);
 1493 
 1494         return rval;
 1495 }
 1496 
 1497 /* Write "instance variables" of atppc device */
 1498 static int
 1499 atppc_write_ivar(device_t dev, int index, unsigned int *val)
 1500 {
 1501         struct atppc_softc *atppc = device_private(dev);
 1502         int rval = 0;
 1503 
 1504         mutex_enter(&atppc->sc_lock);
 1505 
 1506         switch(index) {
 1507         case PPBUS_IVAR_EPP_PROTO:
 1508                 if (*val == PPBUS_EPP_1_9 || *val == PPBUS_EPP_1_7)
 1509                         atppc->sc_epp = *val;
 1510                 else
 1511                         rval = EINVAL;
 1512                 break;
 1513 
 1514         case PPBUS_IVAR_INTR:
 1515                 if (*val == 0)
 1516                         atppc->sc_use &= ~ATPPC_USE_INTR;
 1517                 else if (atppc->sc_has & ATPPC_HAS_INTR)
 1518                         atppc->sc_use |= ATPPC_USE_INTR;
 1519                 else
 1520                         rval = ENODEV;
 1521                 break;
 1522 
 1523         case PPBUS_IVAR_DMA:
 1524                 if (*val == 0)
 1525                         atppc->sc_use &= ~ATPPC_USE_DMA;
 1526                 else if (atppc->sc_has & ATPPC_HAS_DMA)
 1527                         atppc->sc_use |= ATPPC_USE_DMA;
 1528                 else
 1529                         rval = ENODEV;
 1530                 break;
 1531 
 1532         default:
 1533                 rval = ENODEV;
 1534         }
 1535 
 1536         mutex_exit(&atppc->sc_lock);
 1537 
 1538         return rval;
 1539 }
 1540 
 1541 /* Add a handler routine to be called by the interrupt handler */
 1542 static int
 1543 atppc_add_handler(device_t dev, void (*handler)(void *), void *arg)
 1544 {
 1545         struct atppc_softc *atppc = device_private(dev);
 1546         struct atppc_handler_node *callback;
 1547 
 1548         if (handler == NULL) {
 1549                 ATPPC_DPRINTF(("%s(%s): attempt to register NULL handler.\n",
 1550                         __func__, device_xname(dev)));
 1551                 return EINVAL;
 1552         }
 1553 
 1554         callback = kmem_alloc(sizeof(*callback), KM_SLEEP);
 1555         callback->func = handler;
 1556         callback->arg = arg;
 1557         mutex_enter(&atppc->sc_lock);
 1558         SLIST_INSERT_HEAD(&(atppc->sc_handler_listhead),
 1559                 callback, entries);
 1560         mutex_exit(&atppc->sc_lock);
 1561 
 1562         return 0;
 1563 }
 1564 
 1565 /* Remove a handler added by atppc_add_handler() */
 1566 static int
 1567 atppc_remove_handler(device_t dev, void (*handler)(void *))
 1568 {
 1569         struct atppc_softc *atppc = device_private(dev);
 1570         struct atppc_handler_node *callback;
 1571         int rval = EINVAL;
 1572 
 1573         mutex_enter(&atppc->sc_lock);
 1574 
 1575         if (SLIST_EMPTY(&(atppc->sc_handler_listhead)))
 1576                 panic("%s(%s): attempt to remove handler from empty list.\n",
 1577                         __func__, device_xname(dev));
 1578 
 1579         /* Search list for handler */
 1580         SLIST_FOREACH(callback, &(atppc->sc_handler_listhead), entries) {
 1581                 if (callback->func == handler) {
 1582                         SLIST_REMOVE(&(atppc->sc_handler_listhead), callback,
 1583                                 atppc_handler_node, entries);
 1584                         rval = 0;
 1585                         break;
 1586                 }
 1587         }
 1588 
 1589         mutex_exit(&atppc->sc_lock);
 1590 
 1591         if (rval == 0) {
 1592                 kmem_free(callback, sizeof(*callback));
 1593         }
 1594 
 1595         return rval;
 1596 }
 1597 
 1598 /* Utility functions */
 1599 
 1600 
 1601 /*
 1602  * Functions that read bytes from port into buffer: called from interrupt
 1603  * handler depending on current chipset mode and cause of interrupt. Return
 1604  * value: number of bytes moved.
 1605  */
 1606 
 1607 /* Only the lower 4 bits of the final value are valid */
 1608 #define nibble2char(s) ((((s) & ~nACK) >> 3) | (~(s) & nBUSY) >> 4)
 1609 
 1610 /* Read bytes in nibble mode */
 1611 static void
 1612 atppc_nibble_read(struct atppc_softc *atppc)
 1613 {
 1614         int i;
 1615         u_int8_t nibble[2];
 1616         u_int8_t ctr;
 1617         u_int8_t str;
 1618 
 1619         /* Enable interrupts if needed */
 1620         if (atppc->sc_use & ATPPC_USE_INTR) {
 1621                 ctr = atppc_r_ctr(atppc);
 1622                 atppc_barrier_r(atppc);
 1623                 if (!(ctr & IRQENABLE)) {
 1624                         ctr |= IRQENABLE;
 1625                         atppc_w_ctr(atppc, ctr);
 1626                         atppc_barrier_w(atppc);
 1627                 }
 1628         }
 1629 
 1630         while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
 1631                 /* Check if device has data to send in idle phase */
 1632                 str = atppc_r_str(atppc);
 1633                 atppc_barrier_r(atppc);
 1634                 if (str & nDATAVAIL) {
 1635                         return;
 1636                 }
 1637 
 1638                 /* Nibble-mode handshake transfer */
 1639                 for (i = 0; i < 2; i++) {
 1640                         /* Event 7 - ready to take data (HOSTBUSY low) */
 1641                         ctr = atppc_r_ctr(atppc);
 1642                         atppc_barrier_r(atppc);
 1643                         ctr |= HOSTBUSY;
 1644                         atppc_w_ctr(atppc, ctr);
 1645                         atppc_barrier_w(atppc);
 1646 
 1647                         /* Event 8 - peripheral writes the first nibble */
 1648 
 1649                         /* Event 9 - peripheral set nAck low */
 1650                         atppc->sc_inerr = atppc_poll_str(atppc, 0, PTRCLK);
 1651                         if (atppc->sc_inerr)
 1652                                 return;
 1653 
 1654                         /* read nibble */
 1655                         nibble[i] = atppc_r_str(atppc);
 1656 
 1657                         /* Event 10 - ack, nibble received */
 1658                         ctr &= ~HOSTBUSY;
 1659                         atppc_w_ctr(atppc, ctr);
 1660 
 1661                         /* Event 11 - wait ack from peripheral */
 1662                         if (atppc->sc_use & ATPPC_USE_INTR)
 1663                                 atppc->sc_inerr = atppc_wait_interrupt(atppc,
 1664                                         &atppc->sc_in_cv, ATPPC_IRQ_nACK);
 1665                         else
 1666                                 atppc->sc_inerr = atppc_poll_str(atppc, PTRCLK,
 1667                                         PTRCLK);
 1668                         if (atppc->sc_inerr)
 1669                                 return;
 1670                 }
 1671 
 1672                 /* Store byte transferred */
 1673                 *(atppc->sc_inbstart) = ((nibble2char(nibble[1]) << 4) & 0xf0) |
 1674                         (nibble2char(nibble[0]) & 0x0f);
 1675                 atppc->sc_inbstart++;
 1676         }
 1677 }
 1678 
 1679 /* Read bytes in bidirectional mode */
 1680 static void
 1681 atppc_byte_read(struct atppc_softc * const atppc)
 1682 {
 1683         u_int8_t ctr;
 1684         u_int8_t str;
 1685 
 1686         /* Check direction bit */
 1687         ctr = atppc_r_ctr(atppc);
 1688         atppc_barrier_r(atppc);
 1689         if (!(ctr & PCD)) {
 1690                 ATPPC_DPRINTF(("%s: byte-mode read attempted without direction "
 1691                         "bit set.", device_xname(atppc->sc_dev)));
 1692                 atppc->sc_inerr = ENODEV;
 1693                 return;
 1694         }
 1695         /* Enable interrupts if needed */
 1696         if (atppc->sc_use & ATPPC_USE_INTR) {
 1697                 if (!(ctr & IRQENABLE)) {
 1698                         ctr |= IRQENABLE;
 1699                         atppc_w_ctr(atppc, ctr);
 1700                         atppc_barrier_w(atppc);
 1701                 }
 1702         }
 1703 
 1704         /* Byte-mode handshake transfer */
 1705         while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
 1706                 /* Check if device has data to send */
 1707                 str = atppc_r_str(atppc);
 1708                 atppc_barrier_r(atppc);
 1709                 if (str & nDATAVAIL) {
 1710                         return;
 1711                 }
 1712 
 1713                 /* Event 7 - ready to take data (nAUTO low) */
 1714                 ctr |= HOSTBUSY;
 1715                 atppc_w_ctr(atppc, ctr);
 1716                 atppc_barrier_w(atppc);
 1717 
 1718                 /* Event 9 - peripheral set nAck low */
 1719                 atppc->sc_inerr = atppc_poll_str(atppc, 0, PTRCLK);
 1720                 if (atppc->sc_inerr)
 1721                         return;
 1722 
 1723                 /* Store byte transferred */
 1724                 *(atppc->sc_inbstart) = atppc_r_dtr(atppc);
 1725                 atppc_barrier_r(atppc);
 1726 
 1727                 /* Event 10 - data received, can't accept more */
 1728                 ctr &= ~HOSTBUSY;
 1729                 atppc_w_ctr(atppc, ctr);
 1730                 atppc_barrier_w(atppc);
 1731 
 1732                 /* Event 11 - peripheral ack */
 1733                 if (atppc->sc_use & ATPPC_USE_INTR)
 1734                         atppc->sc_inerr = atppc_wait_interrupt(atppc,
 1735                                 &atppc->sc_in_cv, ATPPC_IRQ_nACK);
 1736                 else
 1737                         atppc->sc_inerr = atppc_poll_str(atppc, PTRCLK, PTRCLK);
 1738                 if (atppc->sc_inerr)
 1739                         return;
 1740 
 1741                 /* Event 16 - strobe */
 1742                 str |= HOSTCLK;
 1743                 atppc_w_str(atppc, str);
 1744                 atppc_barrier_w(atppc);
 1745                 DELAY(1);
 1746                 str &= ~HOSTCLK;
 1747                 atppc_w_str(atppc, str);
 1748                 atppc_barrier_w(atppc);
 1749 
 1750                 /* Update counter */
 1751                 atppc->sc_inbstart++;
 1752         }
 1753 }
 1754 
 1755 /* Read bytes in EPP mode */
 1756 static void
 1757 atppc_epp_read(struct atppc_softc * atppc)
 1758 {
 1759         if (atppc->sc_epp == ATPPC_EPP_1_9) {
 1760                 {
 1761                         uint8_t str;
 1762                         int i;
 1763 
 1764                         atppc_reset_epp_timeout(atppc->sc_dev);
 1765                         for (i = 0; i < atppc->sc_inb_nbytes; i++) {
 1766                                  *(atppc->sc_inbstart) = atppc_r_eppD(atppc);
 1767                                 atppc_barrier_r(atppc);
 1768                                 str = atppc_r_str(atppc);
 1769                                 atppc_barrier_r(atppc);
 1770                                 if (str & TIMEOUT) {
 1771                                         atppc->sc_inerr = EIO;
 1772                                         break;
 1773                                 }
 1774                                 atppc->sc_inbstart++;
 1775                         }
 1776                 }
 1777         } else {
 1778                 /* Read data block from EPP data register */
 1779                 atppc_r_eppD_multi(atppc, atppc->sc_inbstart,
 1780                         atppc->sc_inb_nbytes);
 1781                 atppc_barrier_r(atppc);
 1782                 /* Update buffer position, byte count and counter */
 1783                 atppc->sc_inbstart += atppc->sc_inb_nbytes;
 1784         }
 1785 
 1786         return;
 1787 }
 1788 
 1789 /* Read bytes in ECP mode */
 1790 static void
 1791 atppc_ecp_read(struct atppc_softc *atppc)
 1792 {
 1793         u_int8_t ecr;
 1794         u_int8_t ctr;
 1795         u_int8_t str;
 1796         const unsigned char ctr_sav = atppc_r_ctr(atppc);
 1797         const unsigned char ecr_sav = atppc_r_ecr(atppc);
 1798         unsigned int worklen;
 1799 
 1800         /* Check direction bit */
 1801         ctr = ctr_sav;
 1802         atppc_barrier_r(atppc);
 1803         if (!(ctr & PCD)) {
 1804                 ATPPC_DPRINTF(("%s: ecp-mode read attempted without direction "
 1805                         "bit set.", device_xname(atppc->sc_dev)));
 1806                 atppc->sc_inerr = ENODEV;
 1807                 goto end;
 1808         }
 1809 
 1810         /* Clear device request if any */
 1811         if (atppc->sc_use & ATPPC_USE_INTR)
 1812                 atppc->sc_irqstat &= ~ATPPC_IRQ_nFAULT;
 1813 
 1814         while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
 1815                 ecr = atppc_r_ecr(atppc);
 1816                 atppc_barrier_r(atppc);
 1817                 if (ecr & ATPPC_FIFO_EMPTY) {
 1818                         /* Check for invalid state */
 1819                         if (ecr & ATPPC_FIFO_FULL) {
 1820                                 atppc_ecp_read_error(atppc);
 1821                                 break;
 1822                         }
 1823 
 1824                         /* Check if device has data to send */
 1825                         str = atppc_r_str(atppc);
 1826                         atppc_barrier_r(atppc);
 1827                         if (str & nDATAVAIL) {
 1828                                 break;
 1829                         }
 1830 
 1831                         if (atppc->sc_use & ATPPC_USE_INTR) {
 1832                                 /* Enable interrupts */
 1833                                 ecr &= ~ATPPC_SERVICE_INTR;
 1834                                 atppc_w_ecr(atppc, ecr);
 1835                                 atppc_barrier_w(atppc);
 1836                                 /* Wait for FIFO to fill */
 1837                                 atppc->sc_inerr = atppc_wait_interrupt(atppc,
 1838                                         &atppc->sc_in_cv, ATPPC_IRQ_FIFO);
 1839                                 if (atppc->sc_inerr)
 1840                                         break;
 1841                         } else {
 1842                                 DELAY(1);
 1843                         }
 1844                         continue;
 1845                 }
 1846                 else if (ecr & ATPPC_FIFO_FULL) {
 1847                         /* Transfer sc_fifo bytes */
 1848                         worklen = atppc->sc_fifo;
 1849                 }
 1850                 else if (ecr & ATPPC_SERVICE_INTR) {
 1851                         /* Transfer sc_rthr bytes */
 1852                         worklen = atppc->sc_rthr;
 1853                 } else {
 1854                         /* At least one byte is in the FIFO */
 1855                         worklen = 1;
 1856                 }
 1857 
 1858                 if ((atppc->sc_use & ATPPC_USE_INTR) &&
 1859                         (atppc->sc_use & ATPPC_USE_DMA)) {
 1860 
 1861                         atppc_ecp_read_dma(atppc, &worklen, ecr);
 1862                 } else {
 1863                         atppc_ecp_read_pio(atppc, &worklen, ecr);
 1864                 }
 1865 
 1866                 if (atppc->sc_inerr) {
 1867                         atppc_ecp_read_error(atppc);
 1868                         break;
 1869                 }
 1870 
 1871                 /* Update counter */
 1872                 atppc->sc_inbstart += worklen;
 1873         }
 1874 end:
 1875         atppc_w_ctr(atppc, ctr_sav);
 1876         atppc_w_ecr(atppc, ecr_sav);
 1877         atppc_barrier_w(atppc);
 1878 }
 1879 
 1880 /* Read bytes in ECP mode using DMA transfers */
 1881 static void
 1882 atppc_ecp_read_dma(struct atppc_softc *atppc, unsigned int *length,
 1883         unsigned char ecr)
 1884 {
 1885         /* Limit transfer to maximum DMA size and start it */
 1886         *length = uimin(*length, atppc->sc_dma_maxsize);
 1887         atppc->sc_dmastat = ATPPC_DMA_INIT;
 1888         atppc->sc_dma_start(atppc, atppc->sc_inbstart, *length,
 1889                 ATPPC_DMA_MODE_READ);
 1890 
 1891         atppc->sc_dmastat = ATPPC_DMA_STARTED;
 1892 
 1893         /* Enable interrupts, DMA */
 1894         ecr &= ~ATPPC_SERVICE_INTR;
 1895         ecr |= ATPPC_ENABLE_DMA;
 1896         atppc_w_ecr(atppc, ecr);
 1897         atppc_barrier_w(atppc);
 1898 
 1899         /* Wait for DMA completion */
 1900         atppc->sc_inerr = atppc_wait_interrupt(atppc, &atppc->sc_in_cv,
 1901                 ATPPC_IRQ_DMA);
 1902         if (atppc->sc_inerr)
 1903                 return;
 1904 
 1905         /* Get register value recorded by interrupt handler */
 1906         ecr = atppc->sc_ecr_intr;
 1907         /* Clear DMA programming */
 1908         atppc->sc_dma_finish(atppc);
 1909         atppc->sc_dmastat = ATPPC_DMA_COMPLETE;
 1910         /* Disable DMA */
 1911         ecr &= ~ATPPC_ENABLE_DMA;
 1912         atppc_w_ecr(atppc, ecr);
 1913         atppc_barrier_w(atppc);
 1914 }
 1915 
 1916 /* Read bytes in ECP mode using PIO transfers */
 1917 static void
 1918 atppc_ecp_read_pio(struct atppc_softc *atppc, unsigned int *length,
 1919         unsigned char ecr)
 1920 {
 1921         /* Disable DMA */
 1922         ecr &= ~ATPPC_ENABLE_DMA;
 1923         atppc_w_ecr(atppc, ecr);
 1924         atppc_barrier_w(atppc);
 1925 
 1926         /* Read from FIFO */
 1927         atppc_r_fifo_multi(atppc, atppc->sc_inbstart, *length);
 1928 }
 1929 
 1930 /* Handle errors for ECP reads */
 1931 static void
 1932 atppc_ecp_read_error(struct atppc_softc *atppc)
 1933 {
 1934         unsigned char ecr = atppc_r_ecr(atppc);
 1935 
 1936         /* Abort DMA if not finished */
 1937         if (atppc->sc_dmastat == ATPPC_DMA_STARTED) {
 1938                 atppc->sc_dma_abort(atppc);
 1939                 ATPPC_DPRINTF(("%s: DMA interrupted.\n", __func__));
 1940         }
 1941 
 1942         /* Check for invalid states */
 1943         if ((ecr & ATPPC_FIFO_EMPTY) && (ecr & ATPPC_FIFO_FULL)) {
 1944                 ATPPC_DPRINTF(("%s: FIFO full+empty bits set.\n", __func__));
 1945                 ATPPC_DPRINTF(("%s: resetting FIFO.\n", __func__));
 1946                 atppc_w_ecr(atppc, ATPPC_ECR_PS2);
 1947                 atppc_barrier_w(atppc);
 1948         }
 1949 }
 1950 
 1951 /*
 1952  * Functions that write bytes to port from buffer: called from atppc_write()
 1953  * function depending on current chipset mode. Returns number of bytes moved.
 1954  */
 1955 
 1956 /* Write bytes in std/bidirectional mode */
 1957 static void
 1958 atppc_std_write(struct atppc_softc * const atppc)
 1959 {
 1960         unsigned char ctr;
 1961 
 1962         ctr = atppc_r_ctr(atppc);
 1963         atppc_barrier_r(atppc);
 1964         /* Enable interrupts if needed */
 1965         if (atppc->sc_use & ATPPC_USE_INTR) {
 1966                 if (!(ctr & IRQENABLE)) {
 1967                         ctr |= IRQENABLE;
 1968                         atppc_w_ctr(atppc, ctr);
 1969                         atppc_barrier_w(atppc);
 1970                 }
 1971         }
 1972 
 1973         while (atppc->sc_outbstart < (atppc->sc_outb + atppc->sc_outb_nbytes)) {
 1974                 /* Wait for peripheral to become ready for MAXBUSYWAIT */
 1975                 atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
 1976                 if (atppc->sc_outerr)
 1977                         return;
 1978 
 1979                 /* Put data in data register */
 1980                 atppc_w_dtr(atppc, *(atppc->sc_outbstart));
 1981                 atppc_barrier_w(atppc);
 1982                 DELAY(1);
 1983 
 1984                 /* Pulse strobe to indicate valid data on lines */
 1985                 ctr |= STROBE;
 1986                 atppc_w_ctr(atppc, ctr);
 1987                 atppc_barrier_w(atppc);
 1988                 DELAY(1);
 1989                 ctr &= ~STROBE;
 1990                 atppc_w_ctr(atppc, ctr);
 1991                 atppc_barrier_w(atppc);
 1992 
 1993                 /* Wait for nACK for MAXBUSYWAIT */
 1994                 if (atppc->sc_use & ATPPC_USE_INTR) {
 1995                         atppc->sc_outerr = atppc_wait_interrupt(atppc,
 1996                                 &atppc->sc_out_cv, ATPPC_IRQ_nACK);
 1997                         if (atppc->sc_outerr)
 1998                                 return;
 1999                 } else {
 2000                         /* Try to catch the pulsed acknowledgement */
 2001                         atppc->sc_outerr = atppc_poll_str(atppc, 0, nACK);
 2002                         if (atppc->sc_outerr)
 2003                                 return;
 2004                         atppc->sc_outerr = atppc_poll_str(atppc, nACK, nACK);
 2005                         if (atppc->sc_outerr)
 2006                                 return;
 2007                 }
 2008 
 2009                 /* Update buffer position, byte count and counter */
 2010                 atppc->sc_outbstart++;
 2011         }
 2012 }
 2013 
 2014 
 2015 /* Write bytes in EPP mode */
 2016 static void
 2017 atppc_epp_write(struct atppc_softc *atppc)
 2018 {
 2019         if (atppc->sc_epp == ATPPC_EPP_1_9) {
 2020                 {
 2021                         uint8_t str;
 2022                         int i;
 2023 
 2024                         atppc_reset_epp_timeout(atppc->sc_dev);
 2025                         for (i = 0; i < atppc->sc_outb_nbytes; i++) {
 2026                                 atppc_w_eppD(atppc, *(atppc->sc_outbstart));
 2027                                 atppc_barrier_w(atppc);
 2028                                 str = atppc_r_str(atppc);
 2029                                 atppc_barrier_r(atppc);
 2030                                 if (str & TIMEOUT) {
 2031                                         atppc->sc_outerr = EIO;
 2032                                         break;
 2033                                 }
 2034                                 atppc->sc_outbstart++;
 2035                         }
 2036                 }
 2037         } else {
 2038                 /* Write data block to EPP data register */
 2039                 atppc_w_eppD_multi(atppc, atppc->sc_outbstart,
 2040                         atppc->sc_outb_nbytes);
 2041                 atppc_barrier_w(atppc);
 2042                 /* Update buffer position, byte count and counter */
 2043                 atppc->sc_outbstart += atppc->sc_outb_nbytes;
 2044         }
 2045 
 2046         return;
 2047 }
 2048 
 2049 
 2050 /* Write bytes in ECP/Fast Centronics mode */
 2051 static void
 2052 atppc_fifo_write(struct atppc_softc * const atppc)
 2053 {
 2054         unsigned char ctr;
 2055         unsigned char ecr;
 2056         const unsigned char ctr_sav = atppc_r_ctr(atppc);
 2057         const unsigned char ecr_sav = atppc_r_ecr(atppc);
 2058 
 2059         ctr = ctr_sav;
 2060         ecr = ecr_sav;
 2061         atppc_barrier_r(atppc);
 2062 
 2063         /* Reset and flush FIFO */
 2064         atppc_w_ecr(atppc, ATPPC_ECR_PS2);
 2065         atppc_barrier_w(atppc);
 2066         /* Disable nAck interrupts and initialize port bits */
 2067         ctr &= ~(IRQENABLE | STROBE | AUTOFEED);
 2068         atppc_w_ctr(atppc, ctr);
 2069         atppc_barrier_w(atppc);
 2070         /* Restore mode */
 2071         atppc_w_ecr(atppc, ecr);
 2072         atppc_barrier_w(atppc);
 2073 
 2074         /* DMA or Programmed IO */
 2075         if ((atppc->sc_use & ATPPC_USE_DMA) &&
 2076                 (atppc->sc_use & ATPPC_USE_INTR)) {
 2077 
 2078                 atppc_fifo_write_dma(atppc, ecr, ctr);
 2079         } else {
 2080                 atppc_fifo_write_pio(atppc, ecr, ctr);
 2081         }
 2082 
 2083         /* Restore original register values */
 2084         atppc_w_ctr(atppc, ctr_sav);
 2085         atppc_w_ecr(atppc, ecr_sav);
 2086         atppc_barrier_w(atppc);
 2087 }
 2088 
 2089 static void
 2090 atppc_fifo_write_dma(struct atppc_softc * const atppc, unsigned char ecr,
 2091         unsigned char ctr)
 2092 {
 2093         unsigned int len;
 2094         unsigned int worklen;
 2095 
 2096         for (len = (atppc->sc_outb + atppc->sc_outb_nbytes) -
 2097                 atppc->sc_outbstart; len > 0; len = (atppc->sc_outb +
 2098                 atppc->sc_outb_nbytes) - atppc->sc_outbstart) {
 2099 
 2100                 /* Wait for device to become ready */
 2101                 atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
 2102                 if (atppc->sc_outerr)
 2103                         return;
 2104 
 2105                 /* Reset chipset for next DMA transfer */
 2106                 atppc_w_ecr(atppc, ATPPC_ECR_PS2);
 2107                 atppc_barrier_w(atppc);
 2108                 atppc_w_ecr(atppc, ecr);
 2109                 atppc_barrier_w(atppc);
 2110 
 2111                 /* Limit transfer to maximum DMA size and start it */
 2112                 worklen = uimin(len, atppc->sc_dma_maxsize);
 2113                 atppc->sc_dmastat = ATPPC_DMA_INIT;
 2114                 atppc->sc_dma_start(atppc, atppc->sc_outbstart,
 2115                         worklen, ATPPC_DMA_MODE_WRITE);
 2116                 atppc->sc_dmastat = ATPPC_DMA_STARTED;
 2117 
 2118                 /* Enable interrupts, DMA */
 2119                 ecr &= ~ATPPC_SERVICE_INTR;
 2120                 ecr |= ATPPC_ENABLE_DMA;
 2121                 atppc_w_ecr(atppc, ecr);
 2122                 atppc_barrier_w(atppc);
 2123 
 2124                 /* Wait for DMA completion */
 2125                 atppc->sc_outerr = atppc_wait_interrupt(atppc,
 2126                         &atppc->sc_out_cv, ATPPC_IRQ_DMA);
 2127                 if (atppc->sc_outerr) {
 2128                         atppc_fifo_write_error(atppc, worklen);
 2129                         return;
 2130                 }
 2131                 /* Get register value recorded by interrupt handler */
 2132                 ecr = atppc->sc_ecr_intr;
 2133                 /* Clear DMA programming */
 2134                 atppc->sc_dma_finish(atppc);
 2135                 atppc->sc_dmastat = ATPPC_DMA_COMPLETE;
 2136                 /* Disable DMA */
 2137                 ecr &= ~ATPPC_ENABLE_DMA;
 2138                 atppc_w_ecr(atppc, ecr);
 2139                 atppc_barrier_w(atppc);
 2140 
 2141                 /* Wait for FIFO to empty */
 2142                 for (;;) {
 2143                         if (ecr & ATPPC_FIFO_EMPTY) {
 2144                                 if (ecr & ATPPC_FIFO_FULL) {
 2145                                         atppc->sc_outerr = EIO;
 2146                                         atppc_fifo_write_error(atppc, worklen);
 2147                                         return;
 2148                                 } else {
 2149                                         break;
 2150                                 }
 2151                         }
 2152 
 2153                         /* Enable service interrupt */
 2154                         ecr &= ~ATPPC_SERVICE_INTR;
 2155                         atppc_w_ecr(atppc, ecr);
 2156                         atppc_barrier_w(atppc);
 2157 
 2158                         atppc->sc_outerr = atppc_wait_interrupt(atppc,
 2159                                 &atppc->sc_out_cv, ATPPC_IRQ_FIFO);
 2160                         if (atppc->sc_outerr) {
 2161                                 atppc_fifo_write_error(atppc, worklen);
 2162                                 return;
 2163                         }
 2164 
 2165                         /* Get register value recorded by interrupt handler */
 2166                         ecr = atppc->sc_ecr_intr;
 2167                 }
 2168 
 2169                 /* Update pointer */
 2170                 atppc->sc_outbstart += worklen;
 2171         }
 2172 }
 2173 
 2174 static void
 2175 atppc_fifo_write_pio(struct atppc_softc * const atppc, unsigned char ecr,
 2176         unsigned char ctr)
 2177 {
 2178         unsigned int len;
 2179         unsigned int worklen;
 2180         unsigned int timecount;
 2181 
 2182         /* Disable DMA */
 2183         ecr &= ~ATPPC_ENABLE_DMA;
 2184         atppc_w_ecr(atppc, ecr);
 2185         atppc_barrier_w(atppc);
 2186 
 2187         for (len = (atppc->sc_outb + atppc->sc_outb_nbytes) -
 2188                 atppc->sc_outbstart; len > 0; len = (atppc->sc_outb +
 2189                 atppc->sc_outb_nbytes) - atppc->sc_outbstart) {
 2190 
 2191                 /* Wait for device to become ready */
 2192                 atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
 2193                 if (atppc->sc_outerr)
 2194                         return;
 2195 
 2196                 /* Limit transfer to minimum of space in FIFO and buffer */
 2197                 worklen = uimin(len, atppc->sc_fifo);
 2198 
 2199                 /* Write to FIFO */
 2200                 atppc_w_fifo_multi(atppc, atppc->sc_outbstart, worklen);
 2201 
 2202                 timecount = 0;
 2203                 if (atppc->sc_use & ATPPC_USE_INTR) {
 2204                         ecr = atppc_r_ecr(atppc);
 2205                         atppc_barrier_w(atppc);
 2206 
 2207                         /* Wait for interrupt */
 2208                         for (;;) {
 2209                                 if (ecr & ATPPC_FIFO_EMPTY) {
 2210                                         if (ecr & ATPPC_FIFO_FULL) {
 2211                                                 atppc->sc_outerr = EIO;
 2212                                                 atppc_fifo_write_error(atppc,
 2213                                                         worklen);
 2214                                                 return;
 2215                                         } else {
 2216                                                 break;
 2217                                         }
 2218                                 }
 2219 
 2220                                 /* Enable service interrupt */
 2221                                 ecr &= ~ATPPC_SERVICE_INTR;
 2222                                 atppc_w_ecr(atppc, ecr);
 2223                                 atppc_barrier_w(atppc);
 2224 
 2225                                 atppc->sc_outerr = atppc_wait_interrupt(atppc,
 2226                                         &atppc->sc_out_cv, ATPPC_IRQ_FIFO);
 2227                                 if (atppc->sc_outerr) {
 2228                                         atppc_fifo_write_error(atppc, worklen);
 2229                                         return;
 2230                                 }
 2231 
 2232                                 /* Get ECR value saved by interrupt handler */
 2233                                 ecr = atppc->sc_ecr_intr;
 2234                         }
 2235                 } else {
 2236                         for (; timecount < ((MAXBUSYWAIT/hz)*1000000);
 2237                                 timecount++) {
 2238 
 2239                                 ecr = atppc_r_ecr(atppc);
 2240                                 atppc_barrier_r(atppc);
 2241                                 if (ecr & ATPPC_FIFO_EMPTY) {
 2242                                         if (ecr & ATPPC_FIFO_FULL) {
 2243                                                 atppc->sc_outerr = EIO;
 2244                                                 atppc_fifo_write_error(atppc,
 2245                                                         worklen);
 2246                                                 return;
 2247                                         } else {
 2248                                                 break;
 2249                                         }
 2250                                 }
 2251                                 DELAY(1);
 2252                         }
 2253 
 2254                         if (((timecount*hz)/1000000) >= MAXBUSYWAIT) {
 2255                                 atppc->sc_outerr = EIO;
 2256                                 atppc_fifo_write_error(atppc, worklen);
 2257                                 return;
 2258                         }
 2259                 }
 2260 
 2261                 /* Update pointer */
 2262                 atppc->sc_outbstart += worklen;
 2263         }
 2264 }
 2265 
 2266 static void
 2267 atppc_fifo_write_error(struct atppc_softc * const atppc,
 2268         const unsigned int worklen)
 2269 {
 2270         unsigned char ecr = atppc_r_ecr(atppc);
 2271 
 2272         /* Abort DMA if not finished */
 2273         if (atppc->sc_dmastat == ATPPC_DMA_STARTED) {
 2274                 atppc->sc_dma_abort(atppc);
 2275                 ATPPC_DPRINTF(("%s: DMA interrupted.\n", __func__));
 2276         }
 2277 
 2278         /* Check for invalid states */
 2279         if ((ecr & ATPPC_FIFO_EMPTY) && (ecr & ATPPC_FIFO_FULL)) {
 2280                 ATPPC_DPRINTF(("%s: FIFO full+empty bits set.\n", __func__));
 2281         } else if (!(ecr & ATPPC_FIFO_EMPTY)) {
 2282                 unsigned char ctr = atppc_r_ctr(atppc);
 2283                 int bytes_left;
 2284                 int i;
 2285 
 2286                 ATPPC_DPRINTF(("%s(%s): FIFO not empty.\n", __func__,
 2287                         device_xname(atppc->sc_dev)));
 2288 
 2289                 /* Drive strobe low to stop data transfer */
 2290                 ctr &= ~STROBE;
 2291                 atppc_w_ctr(atppc, ctr);
 2292                 atppc_barrier_w(atppc);
 2293 
 2294                 /* Determine how many bytes remain in FIFO */
 2295                 for (i = 0; i < atppc->sc_fifo; i++) {
 2296                         atppc_w_fifo(atppc, (unsigned char)i);
 2297                         ecr = atppc_r_ecr(atppc);
 2298                         atppc_barrier_r(atppc);
 2299                         if (ecr & ATPPC_FIFO_FULL)
 2300                                 break;
 2301                 }
 2302                 bytes_left = (atppc->sc_fifo) - (i + 1);
 2303                 ATPPC_DPRINTF(("%s: %d bytes left in FIFO.\n",  __func__,
 2304                         bytes_left));
 2305 
 2306                 /* Update counter */
 2307                 atppc->sc_outbstart += (worklen - bytes_left);
 2308         } else {
 2309                 /* Update counter */
 2310                 atppc->sc_outbstart += worklen;
 2311         }
 2312 
 2313         ATPPC_DPRINTF(("%s: resetting FIFO.\n", __func__));
 2314         atppc_w_ecr(atppc, ATPPC_ECR_PS2);
 2315         atppc_barrier_w(atppc);
 2316 }
 2317 
 2318 /*
 2319  * Poll status register using mask and status for MAXBUSYWAIT.
 2320  * Returns 0 if device ready, error value otherwise.
 2321  */
 2322 static int
 2323 atppc_poll_str(const struct atppc_softc * const atppc, const u_int8_t status,
 2324         const u_int8_t mask)
 2325 {
 2326         unsigned int timecount;
 2327         u_int8_t str;
 2328         int error = EIO;
 2329 
 2330         /* Wait for str to have status for MAXBUSYWAIT */
 2331         for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*1000000);
 2332                 timecount++) {
 2333 
 2334                 str = atppc_r_str(atppc);
 2335                 atppc_barrier_r(atppc);
 2336                 if ((str & mask) == status) {
 2337                         error = 0;
 2338                         break;
 2339                 }
 2340                 DELAY(1);
 2341         }
 2342 
 2343         return error;
 2344 }
 2345 
 2346 /* Wait for interrupt for MAXBUSYWAIT: returns 0 if acknowledge received. */
 2347 static int
 2348 atppc_wait_interrupt(struct atppc_softc * const atppc, kcondvar_t *cv,
 2349         const u_int8_t irqstat)
 2350 {
 2351         int error = EIO;
 2352 
 2353         atppc->sc_irqstat &= ~irqstat;
 2354 
 2355         /* Wait for interrupt for MAXBUSYWAIT */
 2356         error = cv_timedwait_sig(cv, &atppc->sc_lock, MAXBUSYWAIT);
 2357 
 2358         if (!(error) && (atppc->sc_irqstat & irqstat)) {
 2359                 atppc->sc_irqstat &= ~irqstat;
 2360                 error = 0;
 2361         }
 2362 
 2363         return error;
 2364 }

Cache object: 1e2ad2709ed21cb1810cce19ef27bff6


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