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

Cache object: 0b5998c306bc9d5f11b9b2012cc69b97


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