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

Cache object: 33a5cccd38c52a5ea33c0b16e92330f1


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