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/isa/ppc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1997-2000 Nicolas Souchu
    3  * Copyright (c) 2001 Alcove - Nicolas Souchu
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD: releng/5.0/sys/isa/ppc.c 93021 2002-03-23 15:36:13Z nsouch $
   28  *
   29  */
   30 
   31 #include "opt_ppc.h"
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/bus.h>
   37 #include <sys/malloc.h>
   38   
   39 #include <vm/vm.h>
   40 #include <vm/pmap.h>
   41 #include <machine/clock.h>
   42 #include <machine/bus.h>
   43 #include <machine/resource.h>
   44 #include <machine/vmparam.h>
   45 #include <sys/rman.h>
   46 
   47 #include <isa/isareg.h>
   48 #include <isa/isavar.h>
   49 
   50 #include <dev/ppbus/ppbconf.h>
   51 #include <dev/ppbus/ppb_msq.h>
   52 
   53 #include <isa/ppcreg.h>
   54 
   55 #include "ppbus_if.h"
   56 
   57 #define LOG_PPC(function, ppc, string) \
   58                 if (bootverbose) printf("%s: %s\n", function, string)
   59 
   60 
   61 #define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev))
   62   
   63 devclass_t ppc_devclass;
   64 
   65 static int ppc_probe(device_t dev);
   66 static int ppc_attach(device_t dev);
   67 static int ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val);
   68 
   69 static void ppc_reset_epp(device_t);
   70 static void ppc_ecp_sync(device_t);
   71 static void ppcintr(void *arg);
   72 
   73 static int ppc_exec_microseq(device_t, struct ppb_microseq **);
   74 static int ppc_setmode(device_t, int);
   75 
   76 static int ppc_read(device_t, char *, int, int);
   77 static int ppc_write(device_t, char *, int, int);
   78 
   79 static u_char ppc_io(device_t, int, u_char *, int, u_char);
   80 
   81 static int ppc_setup_intr(device_t, device_t, struct resource *, int,
   82                 void (*)(void *), void *, void **);
   83 static int ppc_teardown_intr(device_t, device_t, struct resource *, void *);
   84 
   85 static device_method_t ppc_methods[] = {
   86         /* device interface */
   87         DEVMETHOD(device_probe,         ppc_probe),
   88         DEVMETHOD(device_attach,        ppc_attach),
   89 
   90         /* bus interface */
   91         DEVMETHOD(bus_read_ivar,        ppc_read_ivar),
   92         DEVMETHOD(bus_setup_intr,       ppc_setup_intr),
   93         DEVMETHOD(bus_teardown_intr,    ppc_teardown_intr),
   94         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
   95 
   96         /* ppbus interface */
   97         DEVMETHOD(ppbus_io,             ppc_io),
   98         DEVMETHOD(ppbus_exec_microseq,  ppc_exec_microseq),
   99         DEVMETHOD(ppbus_reset_epp,      ppc_reset_epp),
  100         DEVMETHOD(ppbus_setmode,        ppc_setmode),
  101         DEVMETHOD(ppbus_ecp_sync,       ppc_ecp_sync),
  102         DEVMETHOD(ppbus_read,           ppc_read),
  103         DEVMETHOD(ppbus_write,          ppc_write),
  104 
  105         { 0, 0 }
  106   };
  107   
  108 static driver_t ppc_driver = {
  109         "ppc",
  110         ppc_methods,
  111         sizeof(struct ppc_data),
  112 };
  113   
  114 static char *ppc_models[] = {
  115         "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
  116         "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334",
  117         "SMC FDC37C935", "PC87303", 0
  118 };
  119 
  120 /* list of available modes */
  121 static char *ppc_avms[] = {
  122         "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
  123         "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
  124         "ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
  125         "ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
  126 };
  127 
  128 /* list of current executing modes
  129  * Note that few modes do not actually exist.
  130  */
  131 static char *ppc_modes[] = {
  132         "COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
  133         "EPP", "EPP", "EPP", "ECP",
  134         "ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
  135         "ECP+EPP", "ECP+EPP", "ECP+EPP", 0
  136 };
  137 
  138 static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
  139 
  140 #ifdef __i386__
  141 /*
  142  * BIOS printer list - used by BIOS probe.
  143  */
  144 #define BIOS_PPC_PORTS  0x408
  145 #define BIOS_PORTS      (short *)(KERNBASE+BIOS_PPC_PORTS)
  146 #define BIOS_MAX_PPC    4
  147 #endif
  148 
  149 /*
  150  * ppc_ecp_sync()               XXX
  151  */
  152 static void
  153 ppc_ecp_sync(device_t dev) {
  154 
  155         int i, r;
  156         struct ppc_data *ppc = DEVTOSOFTC(dev);
  157 
  158         if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
  159                 return;
  160 
  161         r = r_ecr(ppc);
  162         if ((r & 0xe0) != PPC_ECR_EPP)
  163                 return;
  164 
  165         for (i = 0; i < 100; i++) {
  166                 r = r_ecr(ppc);
  167                 if (r & 0x1)
  168                         return;
  169                 DELAY(100);
  170         }
  171 
  172         printf("ppc%d: ECP sync failed as data still " \
  173                 "present in FIFO.\n", ppc->ppc_unit);
  174 
  175         return;
  176 }
  177 
  178 /*
  179  * ppc_detect_fifo()
  180  *
  181  * Detect parallel port FIFO
  182  */
  183 static int
  184 ppc_detect_fifo(struct ppc_data *ppc)
  185 {
  186         char ecr_sav;
  187         char ctr_sav, ctr, cc;
  188         short i;
  189         
  190         /* save registers */
  191         ecr_sav = r_ecr(ppc);
  192         ctr_sav = r_ctr(ppc);
  193 
  194         /* enter ECP configuration mode, no interrupt, no DMA */
  195         w_ecr(ppc, 0xf4);
  196 
  197         /* read PWord size - transfers in FIFO mode must be PWord aligned */
  198         ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
  199 
  200         /* XXX 16 and 32 bits implementations not supported */
  201         if (ppc->ppc_pword != PPC_PWORD_8) {
  202                 LOG_PPC(__func__, ppc, "PWord not supported");
  203                 goto error;
  204         }
  205 
  206         w_ecr(ppc, 0x34);               /* byte mode, no interrupt, no DMA */
  207         ctr = r_ctr(ppc);
  208         w_ctr(ppc, ctr | PCD);          /* set direction to 1 */
  209 
  210         /* enter ECP test mode, no interrupt, no DMA */
  211         w_ecr(ppc, 0xd4);
  212 
  213         /* flush the FIFO */
  214         for (i=0; i<1024; i++) {
  215                 if (r_ecr(ppc) & PPC_FIFO_EMPTY)
  216                         break;
  217                 cc = r_fifo(ppc);
  218         }
  219 
  220         if (i >= 1024) {
  221                 LOG_PPC(__func__, ppc, "can't flush FIFO");
  222                 goto error;
  223         }
  224 
  225         /* enable interrupts, no DMA */
  226         w_ecr(ppc, 0xd0);
  227 
  228         /* determine readIntrThreshold
  229          * fill the FIFO until serviceIntr is set
  230          */
  231         for (i=0; i<1024; i++) {
  232                 w_fifo(ppc, (char)i);
  233                 if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
  234                         /* readThreshold reached */
  235                         ppc->ppc_rthr = i+1;
  236                 }
  237                 if (r_ecr(ppc) & PPC_FIFO_FULL) {
  238                         ppc->ppc_fifo = i+1;
  239                         break;
  240                 }
  241         }
  242 
  243         if (i >= 1024) {
  244                 LOG_PPC(__func__, ppc, "can't fill FIFO");
  245                 goto error;
  246         }
  247 
  248         w_ecr(ppc, 0xd4);               /* test mode, no interrupt, no DMA */
  249         w_ctr(ppc, ctr & ~PCD);         /* set direction to 0 */
  250         w_ecr(ppc, 0xd0);               /* enable interrupts */
  251 
  252         /* determine writeIntrThreshold
  253          * empty the FIFO until serviceIntr is set
  254          */
  255         for (i=ppc->ppc_fifo; i>0; i--) {
  256                 if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
  257                         LOG_PPC(__func__, ppc, "invalid data in FIFO");
  258                         goto error;
  259                 }
  260                 if (r_ecr(ppc) & PPC_SERVICE_INTR) {
  261                         /* writeIntrThreshold reached */
  262                         ppc->ppc_wthr = ppc->ppc_fifo - i+1;
  263                 }
  264                 /* if FIFO empty before the last byte, error */
  265                 if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
  266                         LOG_PPC(__func__, ppc, "data lost in FIFO");
  267                         goto error;
  268                 }
  269         }
  270 
  271         /* FIFO must be empty after the last byte */
  272         if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
  273                 LOG_PPC(__func__, ppc, "can't empty the FIFO");
  274                 goto error;
  275         }
  276         
  277         w_ctr(ppc, ctr_sav);
  278         w_ecr(ppc, ecr_sav);
  279 
  280         return (0);
  281 
  282 error:
  283         w_ctr(ppc, ctr_sav);
  284         w_ecr(ppc, ecr_sav);
  285 
  286         return (EINVAL);
  287 }
  288 
  289 static int
  290 ppc_detect_port(struct ppc_data *ppc)
  291 {
  292 
  293         w_ctr(ppc, 0x0c);       /* To avoid missing PS2 ports */
  294         w_dtr(ppc, 0xaa);
  295         if (r_dtr(ppc) != 0xaa)
  296                 return (0);
  297 
  298         return (1);
  299 }
  300 
  301 /*
  302  * EPP timeout, according to the PC87332 manual
  303  * Semantics of clearing EPP timeout bit.
  304  * PC87332      - reading SPP_STR does it...
  305  * SMC          - write 1 to EPP timeout bit                    XXX
  306  * Others       - (?) write 0 to EPP timeout bit
  307  */
  308 static void
  309 ppc_reset_epp_timeout(struct ppc_data *ppc)
  310 {
  311         register char r;
  312 
  313         r = r_str(ppc);
  314         w_str(ppc, r | 0x1);
  315         w_str(ppc, r & 0xfe);
  316 
  317         return;
  318 }
  319 
  320 static int
  321 ppc_check_epp_timeout(struct ppc_data *ppc)
  322 {
  323         ppc_reset_epp_timeout(ppc);
  324 
  325         return (!(r_str(ppc) & TIMEOUT));
  326 }
  327 
  328 /*
  329  * Configure current operating mode
  330  */
  331 static int
  332 ppc_generic_setmode(struct ppc_data *ppc, int mode)
  333 {
  334         u_char ecr = 0;
  335 
  336         /* check if mode is available */
  337         if (mode && !(ppc->ppc_avm & mode))
  338                 return (EINVAL);
  339 
  340         /* if ECP mode, configure ecr register */
  341         if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
  342                 /* return to byte mode (keeping direction bit),
  343                  * no interrupt, no DMA to be able to change to
  344                  * ECP
  345                  */
  346                 w_ecr(ppc, PPC_ECR_RESET);
  347                 ecr = PPC_DISABLE_INTR;
  348 
  349                 if (mode & PPB_EPP)
  350                         return (EINVAL);
  351                 else if (mode & PPB_ECP)
  352                         /* select ECP mode */
  353                         ecr |= PPC_ECR_ECP;
  354                 else if (mode & PPB_PS2)
  355                         /* select PS2 mode with ECP */
  356                         ecr |= PPC_ECR_PS2;
  357                 else
  358                         /* select COMPATIBLE/NIBBLE mode */
  359                         ecr |= PPC_ECR_STD;
  360 
  361                 w_ecr(ppc, ecr);
  362         }
  363 
  364         ppc->ppc_mode = mode;
  365 
  366         return (0);
  367 }
  368 
  369 /*
  370  * The ppc driver is free to choose options like FIFO or DMA
  371  * if ECP mode is available.
  372  *
  373  * The 'RAW' option allows the upper drivers to force the ppc mode
  374  * even with FIFO, DMA available.
  375  */
  376 static int
  377 ppc_smclike_setmode(struct ppc_data *ppc, int mode)
  378 {
  379         u_char ecr = 0;
  380 
  381         /* check if mode is available */
  382         if (mode && !(ppc->ppc_avm & mode))
  383                 return (EINVAL);
  384 
  385         /* if ECP mode, configure ecr register */
  386         if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
  387                 /* return to byte mode (keeping direction bit),
  388                  * no interrupt, no DMA to be able to change to
  389                  * ECP or EPP mode
  390                  */
  391                 w_ecr(ppc, PPC_ECR_RESET);
  392                 ecr = PPC_DISABLE_INTR;
  393 
  394                 if (mode & PPB_EPP)
  395                         /* select EPP mode */
  396                         ecr |= PPC_ECR_EPP;
  397                 else if (mode & PPB_ECP)
  398                         /* select ECP mode */
  399                         ecr |= PPC_ECR_ECP;
  400                 else if (mode & PPB_PS2)
  401                         /* select PS2 mode with ECP */
  402                         ecr |= PPC_ECR_PS2;
  403                 else
  404                         /* select COMPATIBLE/NIBBLE mode */
  405                         ecr |= PPC_ECR_STD;
  406 
  407                 w_ecr(ppc, ecr);
  408         }
  409 
  410         ppc->ppc_mode = mode;
  411 
  412         return (0);
  413 }
  414 
  415 #ifdef PPC_PROBE_CHIPSET
  416 /*
  417  * ppc_pc873xx_detect
  418  *
  419  * Probe for a Natsemi PC873xx-family part.
  420  *
  421  * References in this function are to the National Semiconductor
  422  * PC87332 datasheet TL/C/11930, May 1995 revision.
  423  */
  424 static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
  425 static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
  426 static int pc873xx_irqtab[] = {5, 7, 5, 0};
  427 
  428 static int pc873xx_regstab[] = {
  429         PC873_FER, PC873_FAR, PC873_PTR,
  430         PC873_FCR, PC873_PCR, PC873_PMC,
  431         PC873_TUP, PC873_SID, PC873_PNP0,
  432         PC873_PNP1, PC873_LPTBA, -1
  433 };
  434 
  435 static char *pc873xx_rnametab[] = {
  436         "FER", "FAR", "PTR", "FCR", "PCR",
  437         "PMC", "TUP", "SID", "PNP0", "PNP1",
  438         "LPTBA", NULL
  439 };
  440 
  441 static int
  442 ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode)      /* XXX mode never forced */
  443 {
  444     static int  index = 0;
  445     int         idport, irq;
  446     int         ptr, pcr, val, i;
  447     
  448     while ((idport = pc873xx_basetab[index++])) {
  449         
  450         /* XXX should check first to see if this location is already claimed */
  451 
  452         /*
  453          * Pull the 873xx through the power-on ID cycle (2.2,1.).
  454          * We can't use this to locate the chip as it may already have
  455          * been used by the BIOS.
  456          */
  457         (void)inb(idport); (void)inb(idport);
  458         (void)inb(idport); (void)inb(idport);
  459 
  460         /*
  461          * Read the SID byte.  Possible values are :
  462          *
  463          * 01010xxx     PC87334
  464          * 0001xxxx     PC87332
  465          * 01110xxx     PC87306
  466          * 00110xxx     PC87303
  467          */
  468         outb(idport, PC873_SID);
  469         val = inb(idport + 1);
  470         if ((val & 0xf0) == 0x10) {
  471             ppc->ppc_model = NS_PC87332;
  472         } else if ((val & 0xf8) == 0x70) {
  473             ppc->ppc_model = NS_PC87306;
  474         } else if ((val & 0xf8) == 0x50) {
  475             ppc->ppc_model = NS_PC87334;
  476         } else if ((val & 0xf8) == 0x40) { /* Should be 0x30 by the
  477                                               documentation, but probing
  478                                               yielded 0x40... */
  479             ppc->ppc_model = NS_PC87303;
  480         } else {
  481             if (bootverbose && (val != 0xff))
  482                 printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
  483             continue ;          /* not recognised */
  484         }
  485 
  486         /* print registers */
  487         if (bootverbose) {
  488                 printf("PC873xx");
  489                 for (i=0; pc873xx_regstab[i] != -1; i++) {
  490                         outb(idport, pc873xx_regstab[i]);
  491                         printf(" %s=0x%x", pc873xx_rnametab[i],
  492                                                 inb(idport + 1) & 0xff);
  493                 }
  494                 printf("\n");
  495         }
  496         
  497         /*
  498          * We think we have one.  Is it enabled and where we want it to be?
  499          */
  500         outb(idport, PC873_FER);
  501         val = inb(idport + 1);
  502         if (!(val & PC873_PPENABLE)) {
  503             if (bootverbose)
  504                 printf("PC873xx parallel port disabled\n");
  505             continue;
  506         }
  507         outb(idport, PC873_FAR);
  508         val = inb(idport + 1);
  509         /* XXX we should create a driver instance for every port found */
  510         if (pc873xx_porttab[val & 0x3] != ppc->ppc_base) {
  511 
  512             /* First try to change the port address to that requested... */
  513 
  514             switch(ppc->ppc_base) {
  515                 case 0x378:
  516                 val &= 0xfc;
  517                 break;
  518 
  519                 case 0x3bc:
  520                 val &= 0xfd;
  521                 break;
  522 
  523                 case 0x278:
  524                 val &= 0xfe;
  525                 break;
  526 
  527                 default:
  528                 val &= 0xfd;
  529                 break;
  530             }
  531 
  532             outb(idport, PC873_FAR);
  533             outb(idport + 1, val);
  534             outb(idport + 1, val);
  535 
  536             /* Check for success by reading back the value we supposedly
  537                wrote and comparing...*/
  538 
  539             outb(idport, PC873_FAR);
  540             val = inb(idport + 1) & 0x3;
  541 
  542             /* If we fail, report the failure... */
  543 
  544             if (pc873xx_porttab[val] != ppc->ppc_base) {
  545                 if (bootverbose)
  546                     printf("PC873xx at 0x%x not for driver at port 0x%x\n",
  547                            pc873xx_porttab[val], ppc->ppc_base);
  548             }
  549             continue;
  550         }
  551 
  552         outb(idport, PC873_PTR);
  553         ptr = inb(idport + 1);
  554 
  555         /* get irq settings */
  556         if (ppc->ppc_base == 0x378)
  557                 irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
  558         else
  559                 irq = pc873xx_irqtab[val];
  560 
  561         if (bootverbose)
  562                 printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
  563         
  564         /*
  565          * Check if irq settings are correct
  566          */
  567         if (irq != ppc->ppc_irq) {
  568                 /*
  569                  * If the chipset is not locked and base address is 0x378,
  570                  * we have another chance
  571                  */
  572                 if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
  573                         if (ppc->ppc_irq == 7) {
  574                                 outb(idport + 1, (ptr | PC873_LPTBIRQ7));
  575                                 outb(idport + 1, (ptr | PC873_LPTBIRQ7));
  576                         } else {
  577                                 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
  578                                 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
  579                         }
  580                         if (bootverbose)
  581                            printf("PC873xx irq set to %d\n", ppc->ppc_irq);
  582                 } else {
  583                         if (bootverbose)
  584                            printf("PC873xx sorry, can't change irq setting\n");
  585                 }
  586         } else {
  587                 if (bootverbose)
  588                         printf("PC873xx irq settings are correct\n");
  589         }
  590 
  591         outb(idport, PC873_PCR);
  592         pcr = inb(idport + 1);
  593         
  594         if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
  595             if (bootverbose)
  596                 printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
  597 
  598             ppc->ppc_avm |= PPB_NIBBLE;
  599             if (bootverbose)
  600                 printf(", NIBBLE");
  601 
  602             if (pcr & PC873_EPPEN) {
  603                 ppc->ppc_avm |= PPB_EPP;
  604 
  605                 if (bootverbose)
  606                         printf(", EPP");
  607 
  608                 if (pcr & PC873_EPP19)
  609                         ppc->ppc_epp = EPP_1_9;
  610                 else
  611                         ppc->ppc_epp = EPP_1_7;
  612 
  613                 if ((ppc->ppc_model == NS_PC87332) && bootverbose) {
  614                         outb(idport, PC873_PTR);
  615                         ptr = inb(idport + 1);
  616                         if (ptr & PC873_EPPRDIR)
  617                                 printf(", Regular mode");
  618                         else
  619                                 printf(", Automatic mode");
  620                 }
  621             } else if (pcr & PC873_ECPEN) {
  622                 ppc->ppc_avm |= PPB_ECP;
  623                 if (bootverbose)
  624                         printf(", ECP");
  625 
  626                 if (pcr & PC873_ECPCLK) {               /* XXX */
  627                         ppc->ppc_avm |= PPB_PS2;
  628                         if (bootverbose)
  629                                 printf(", PS/2");
  630                 }
  631             } else {
  632                 outb(idport, PC873_PTR);
  633                 ptr = inb(idport + 1);
  634                 if (ptr & PC873_EXTENDED) {
  635                         ppc->ppc_avm |= PPB_SPP;
  636                         if (bootverbose)
  637                                 printf(", SPP");
  638                 }
  639             }
  640         } else {
  641                 if (bootverbose)
  642                         printf("PC873xx unlocked");
  643 
  644                 if (chipset_mode & PPB_ECP) {
  645                         if ((chipset_mode & PPB_EPP) && bootverbose)
  646                                 printf(", ECP+EPP not supported");
  647 
  648                         pcr &= ~PC873_EPPEN;
  649                         pcr |= (PC873_ECPEN | PC873_ECPCLK);    /* XXX */
  650                         outb(idport + 1, pcr);
  651                         outb(idport + 1, pcr);
  652 
  653                         if (bootverbose)
  654                                 printf(", ECP");
  655 
  656                 } else if (chipset_mode & PPB_EPP) {
  657                         pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
  658                         pcr |= (PC873_EPPEN | PC873_EPP19);
  659                         outb(idport + 1, pcr);
  660                         outb(idport + 1, pcr);
  661 
  662                         ppc->ppc_epp = EPP_1_9;                 /* XXX */
  663 
  664                         if (bootverbose)
  665                                 printf(", EPP1.9");
  666 
  667                         /* enable automatic direction turnover */
  668                         if (ppc->ppc_model == NS_PC87332) {
  669                                 outb(idport, PC873_PTR);
  670                                 ptr = inb(idport + 1);
  671                                 ptr &= ~PC873_EPPRDIR;
  672                                 outb(idport + 1, ptr);
  673                                 outb(idport + 1, ptr);
  674 
  675                                 if (bootverbose)
  676                                         printf(", Automatic mode");
  677                         }
  678                 } else {
  679                         pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
  680                         outb(idport + 1, pcr);
  681                         outb(idport + 1, pcr);
  682 
  683                         /* configure extended bit in PTR */
  684                         outb(idport, PC873_PTR);
  685                         ptr = inb(idport + 1);
  686 
  687                         if (chipset_mode & PPB_PS2) {
  688                                 ptr |= PC873_EXTENDED;
  689 
  690                                 if (bootverbose)
  691                                         printf(", PS/2");
  692                         
  693                         } else {
  694                                 /* default to NIBBLE mode */
  695                                 ptr &= ~PC873_EXTENDED;
  696 
  697                                 if (bootverbose)
  698                                         printf(", NIBBLE");
  699                         }
  700                         outb(idport + 1, ptr);
  701                         outb(idport + 1, ptr);
  702                 }
  703 
  704                 ppc->ppc_avm = chipset_mode;
  705         }
  706 
  707         if (bootverbose)
  708                 printf("\n");
  709 
  710         ppc->ppc_type = PPC_TYPE_GENERIC;
  711         ppc_generic_setmode(ppc, chipset_mode);
  712 
  713         return(chipset_mode);
  714     }
  715     return(-1);
  716 }
  717 
  718 /*
  719  * ppc_smc37c66xgt_detect
  720  *
  721  * SMC FDC37C66xGT configuration.
  722  */
  723 static int
  724 ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
  725 {
  726         int s, i;
  727         u_char r;
  728         int type = -1;
  729         int csr = SMC66x_CSR;   /* initial value is 0x3F0 */
  730 
  731         int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
  732 
  733 
  734 #define cio csr+1       /* config IO port is either 0x3F1 or 0x371 */
  735 
  736         /*
  737          * Detection: enter configuration mode and read CRD register.
  738          */
  739          
  740         s = splhigh();
  741         outb(csr, SMC665_iCODE);
  742         outb(csr, SMC665_iCODE);
  743         splx(s);
  744 
  745         outb(csr, 0xd);
  746         if (inb(cio) == 0x65) {
  747                 type = SMC_37C665GT;
  748                 goto config;
  749         }
  750 
  751         for (i = 0; i < 2; i++) {
  752                 s = splhigh();
  753                 outb(csr, SMC666_iCODE);
  754                 outb(csr, SMC666_iCODE);
  755                 splx(s);
  756 
  757                 outb(csr, 0xd);
  758                 if (inb(cio) == 0x66) {
  759                         type = SMC_37C666GT;
  760                         break;
  761                 }
  762 
  763                 /* Another chance, CSR may be hard-configured to be at 0x370 */
  764                 csr = SMC666_CSR;
  765         }
  766 
  767 config:
  768         /*
  769          * If chipset not found, do not continue.
  770          */
  771         if (type == -1)
  772                 return (-1);
  773 
  774         /* select CR1 */
  775         outb(csr, 0x1);
  776 
  777         /* read the port's address: bits 0 and 1 of CR1 */
  778         r = inb(cio) & SMC_CR1_ADDR;
  779         if (port_address[(int)r] != ppc->ppc_base)
  780                 return (-1);
  781 
  782         ppc->ppc_model = type;
  783 
  784         /*
  785          * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
  786          * If SPP mode is detected, try to set ECP+EPP mode
  787          */
  788 
  789         if (bootverbose) {
  790                 outb(csr, 0x1);
  791                 printf("ppc%d: SMC registers CR1=0x%x", ppc->ppc_unit,
  792                         inb(cio) & 0xff);
  793 
  794                 outb(csr, 0x4);
  795                 printf(" CR4=0x%x", inb(cio) & 0xff);
  796         }
  797 
  798         /* select CR1 */
  799         outb(csr, 0x1);
  800 
  801         if (!chipset_mode) {
  802                 /* autodetect mode */
  803 
  804                 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
  805                 if (type == SMC_37C666GT) {
  806                         ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
  807                         if (bootverbose)
  808                                 printf(" configuration hardwired, supposing " \
  809                                         "ECP+EPP SPP");
  810 
  811                 } else
  812                    if ((inb(cio) & SMC_CR1_MODE) == 0) {
  813                         /* already in extended parallel port mode, read CR4 */
  814                         outb(csr, 0x4);
  815                         r = (inb(cio) & SMC_CR4_EMODE);
  816 
  817                         switch (r) {
  818                         case SMC_SPP:
  819                                 ppc->ppc_avm |= PPB_SPP;
  820                                 if (bootverbose)
  821                                         printf(" SPP");
  822                                 break;
  823 
  824                         case SMC_EPPSPP:
  825                                 ppc->ppc_avm |= PPB_EPP | PPB_SPP;
  826                                 if (bootverbose)
  827                                         printf(" EPP SPP");
  828                                 break;
  829 
  830                         case SMC_ECP:
  831                                 ppc->ppc_avm |= PPB_ECP | PPB_SPP;
  832                                 if (bootverbose)
  833                                         printf(" ECP SPP");
  834                                 break;
  835 
  836                         case SMC_ECPEPP:
  837                                 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
  838                                 if (bootverbose)
  839                                         printf(" ECP+EPP SPP");
  840                                 break;
  841                         }
  842                    } else {
  843                         /* not an extended port mode */
  844                         ppc->ppc_avm |= PPB_SPP;
  845                         if (bootverbose)
  846                                 printf(" SPP");
  847                    }
  848 
  849         } else {
  850                 /* mode forced */
  851                 ppc->ppc_avm = chipset_mode;
  852 
  853                 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
  854                 if (type == SMC_37C666GT)
  855                         goto end_detect;
  856 
  857                 r = inb(cio);
  858                 if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
  859                         /* do not use ECP when the mode is not forced to */
  860                         outb(cio, r | SMC_CR1_MODE);
  861                         if (bootverbose)
  862                                 printf(" SPP");
  863                 } else {
  864                         /* an extended mode is selected */
  865                         outb(cio, r & ~SMC_CR1_MODE);
  866 
  867                         /* read CR4 register and reset mode field */
  868                         outb(csr, 0x4);
  869                         r = inb(cio) & ~SMC_CR4_EMODE;
  870 
  871                         if (chipset_mode & PPB_ECP) {
  872                                 if (chipset_mode & PPB_EPP) {
  873                                         outb(cio, r | SMC_ECPEPP);
  874                                         if (bootverbose)
  875                                                 printf(" ECP+EPP");
  876                                 } else {
  877                                         outb(cio, r | SMC_ECP);
  878                                         if (bootverbose)
  879                                                 printf(" ECP");
  880                                 }
  881                         } else {
  882                                 /* PPB_EPP is set */
  883                                 outb(cio, r | SMC_EPPSPP);
  884                                 if (bootverbose)
  885                                         printf(" EPP SPP");
  886                         }
  887                 }
  888                 ppc->ppc_avm = chipset_mode;
  889         }
  890 
  891         /* set FIFO threshold to 16 */
  892         if (ppc->ppc_avm & PPB_ECP) {
  893                 /* select CRA */
  894                 outb(csr, 0xa);
  895                 outb(cio, 16);
  896         }
  897 
  898 end_detect:
  899 
  900         if (bootverbose)
  901                 printf ("\n");
  902 
  903         if (ppc->ppc_avm & PPB_EPP) {
  904                 /* select CR4 */
  905                 outb(csr, 0x4);
  906                 r = inb(cio);
  907 
  908                 /*
  909                  * Set the EPP protocol...
  910                  * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
  911                  */
  912                 if (ppc->ppc_epp == EPP_1_9)
  913                         outb(cio, (r & ~SMC_CR4_EPPTYPE));
  914                 else
  915                         outb(cio, (r | SMC_CR4_EPPTYPE));
  916         }
  917 
  918         /* end config mode */
  919         outb(csr, 0xaa);
  920 
  921         ppc->ppc_type = PPC_TYPE_SMCLIKE;
  922         ppc_smclike_setmode(ppc, chipset_mode);
  923 
  924         return (chipset_mode);
  925 }
  926 
  927 /*
  928  * SMC FDC37C935 configuration
  929  * Found on many Alpha machines
  930  */
  931 static int
  932 ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode)
  933 {
  934         int s;
  935         int type = -1;
  936 
  937         s = splhigh();
  938         outb(SMC935_CFG, 0x55); /* enter config mode */
  939         outb(SMC935_CFG, 0x55);
  940         splx(s);
  941 
  942         outb(SMC935_IND, SMC935_ID); /* check device id */
  943         if (inb(SMC935_DAT) == 0x2)
  944                 type = SMC_37C935;
  945 
  946         if (type == -1) {
  947                 outb(SMC935_CFG, 0xaa); /* exit config mode */
  948                 return (-1);
  949         }
  950 
  951         ppc->ppc_model = type;
  952 
  953         outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */
  954         outb(SMC935_DAT, 3);             /* which is logical device 3 */
  955 
  956         /* set io port base */
  957         outb(SMC935_IND, SMC935_PORTHI);
  958         outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8));
  959         outb(SMC935_IND, SMC935_PORTLO);
  960         outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff));
  961 
  962         if (!chipset_mode)
  963                 ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */
  964         else {
  965                 ppc->ppc_avm = chipset_mode;
  966                 outb(SMC935_IND, SMC935_PPMODE);
  967                 outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */
  968 
  969                 /* SPP + EPP or just plain SPP */
  970                 if (chipset_mode & (PPB_SPP)) {
  971                         if (chipset_mode & PPB_EPP) {
  972                                 if (ppc->ppc_epp == EPP_1_9) {
  973                                         outb(SMC935_IND, SMC935_PPMODE);
  974                                         outb(SMC935_DAT, SMC935_EPP19SPP);
  975                                 }
  976                                 if (ppc->ppc_epp == EPP_1_7) {
  977                                         outb(SMC935_IND, SMC935_PPMODE);
  978                                         outb(SMC935_DAT, SMC935_EPP17SPP);
  979                                 }
  980                         } else {
  981                                 outb(SMC935_IND, SMC935_PPMODE);
  982                                 outb(SMC935_DAT, SMC935_SPP);
  983                         }
  984                 }
  985 
  986                 /* ECP + EPP or just plain ECP */
  987                 if (chipset_mode & PPB_ECP) {
  988                         if (chipset_mode & PPB_EPP) {
  989                                 if (ppc->ppc_epp == EPP_1_9) {
  990                                         outb(SMC935_IND, SMC935_PPMODE);
  991                                         outb(SMC935_DAT, SMC935_ECPEPP19);
  992                                 }
  993                                 if (ppc->ppc_epp == EPP_1_7) {
  994                                         outb(SMC935_IND, SMC935_PPMODE);
  995                                         outb(SMC935_DAT, SMC935_ECPEPP17);
  996                                 }
  997                         } else {
  998                                 outb(SMC935_IND, SMC935_PPMODE);
  999                                 outb(SMC935_DAT, SMC935_ECP);
 1000                         }
 1001                 }
 1002         }
 1003 
 1004         outb(SMC935_CFG, 0xaa); /* exit config mode */
 1005 
 1006         ppc->ppc_type = PPC_TYPE_SMCLIKE;
 1007         ppc_smclike_setmode(ppc, chipset_mode);
 1008 
 1009         return (chipset_mode);
 1010 }
 1011 
 1012 /*
 1013  * Winbond W83877F stuff
 1014  *
 1015  * EFER: extended function enable register
 1016  * EFIR: extended function index register
 1017  * EFDR: extended function data register
 1018  */
 1019 #define efir ((efer == 0x250) ? 0x251 : 0x3f0)
 1020 #define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
 1021 
 1022 static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
 1023 static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 }; 
 1024 static int w83877f_keyiter[] = { 1, 2, 2, 1 };
 1025 static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
 1026 
 1027 static int
 1028 ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
 1029 {
 1030         int i, j, efer;
 1031         unsigned char r, hefere, hefras;
 1032 
 1033         for (i = 0; i < 4; i ++) {
 1034                 /* first try to enable configuration registers */
 1035                 efer = w83877f_efers[i];
 1036 
 1037                 /* write the key to the EFER */
 1038                 for (j = 0; j < w83877f_keyiter[i]; j ++)
 1039                         outb (efer, w83877f_keys[i]);
 1040 
 1041                 /* then check HEFERE and HEFRAS bits */
 1042                 outb (efir, 0x0c);
 1043                 hefere = inb(efdr) & WINB_HEFERE;
 1044 
 1045                 outb (efir, 0x16);
 1046                 hefras = inb(efdr) & WINB_HEFRAS;
 1047 
 1048                 /*
 1049                  * HEFRAS       HEFERE
 1050                  *   0             1    write 89h to 250h (power-on default)
 1051                  *   1             0    write 86h twice to 3f0h
 1052                  *   1             1    write 87h twice to 3f0h
 1053                  *   0             0    write 88h to 250h
 1054                  */
 1055                 if ((hefere | hefras) == w83877f_hefs[i])
 1056                         goto found;
 1057         }
 1058 
 1059         return (-1);    /* failed */
 1060 
 1061 found:
 1062         /* check base port address - read from CR23 */
 1063         outb(efir, 0x23);
 1064         if (ppc->ppc_base != inb(efdr) * 4)             /* 4 bytes boundaries */
 1065                 return (-1);
 1066 
 1067         /* read CHIP ID from CR9/bits0-3 */
 1068         outb(efir, 0x9);
 1069 
 1070         switch (inb(efdr) & WINB_CHIPID) {
 1071                 case WINB_W83877F_ID:
 1072                         ppc->ppc_model = WINB_W83877F;
 1073                         break;
 1074 
 1075                 case WINB_W83877AF_ID:
 1076                         ppc->ppc_model = WINB_W83877AF;
 1077                         break;
 1078 
 1079                 default:
 1080                         ppc->ppc_model = WINB_UNKNOWN;
 1081         }
 1082 
 1083         if (bootverbose) {
 1084                 /* dump of registers */
 1085                 printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
 1086                 for (i = 0; i <= 0xd; i ++) {
 1087                         outb(efir, i);
 1088                         printf("0x%x ", inb(efdr));
 1089                 }
 1090                 for (i = 0x10; i <= 0x17; i ++) {
 1091                         outb(efir, i);
 1092                         printf("0x%x ", inb(efdr));
 1093                 }
 1094                 outb(efir, 0x1e);
 1095                 printf("0x%x ", inb(efdr));
 1096                 for (i = 0x20; i <= 0x29; i ++) {
 1097                         outb(efir, i);
 1098                         printf("0x%x ", inb(efdr));
 1099                 }
 1100                 printf("\n");
 1101                 printf("ppc%d:", ppc->ppc_unit);
 1102         }
 1103 
 1104         ppc->ppc_type = PPC_TYPE_GENERIC;
 1105 
 1106         if (!chipset_mode) {
 1107                 /* autodetect mode */
 1108 
 1109                 /* select CR0 */
 1110                 outb(efir, 0x0);
 1111                 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
 1112 
 1113                 /* select CR9 */
 1114                 outb(efir, 0x9);
 1115                 r |= (inb(efdr) & WINB_PRTMODS2);
 1116 
 1117                 switch (r) {
 1118                 case WINB_W83757:
 1119                         if (bootverbose)
 1120                                 printf("ppc%d: W83757 compatible mode\n",
 1121                                         ppc->ppc_unit);
 1122                         return (-1);    /* generic or SMC-like */
 1123 
 1124                 case WINB_EXTFDC:
 1125                 case WINB_EXTADP:
 1126                 case WINB_EXT2FDD:
 1127                 case WINB_JOYSTICK:
 1128                         if (bootverbose)
 1129                                 printf(" not in parallel port mode\n");
 1130                         return (-1);
 1131 
 1132                 case (WINB_PARALLEL | WINB_EPP_SPP):
 1133                         ppc->ppc_avm |= PPB_EPP | PPB_SPP;
 1134                         if (bootverbose)
 1135                                 printf(" EPP SPP");
 1136                         break;
 1137 
 1138                 case (WINB_PARALLEL | WINB_ECP):
 1139                         ppc->ppc_avm |= PPB_ECP | PPB_SPP;
 1140                         if (bootverbose)
 1141                                 printf(" ECP SPP");
 1142                         break;
 1143 
 1144                 case (WINB_PARALLEL | WINB_ECP_EPP):
 1145                         ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
 1146                         ppc->ppc_type = PPC_TYPE_SMCLIKE;
 1147 
 1148                         if (bootverbose)
 1149                                 printf(" ECP+EPP SPP");
 1150                         break;
 1151                 default:
 1152                         printf("%s: unknown case (0x%x)!\n", __func__, r);
 1153                 }
 1154 
 1155         } else {
 1156                 /* mode forced */
 1157 
 1158                 /* select CR9 and set PRTMODS2 bit */
 1159                 outb(efir, 0x9);
 1160                 outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
 1161 
 1162                 /* select CR0 and reset PRTMODSx bits */
 1163                 outb(efir, 0x0);
 1164                 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
 1165 
 1166                 if (chipset_mode & PPB_ECP) {
 1167                         if (chipset_mode & PPB_EPP) {
 1168                                 outb(efdr, inb(efdr) | WINB_ECP_EPP);
 1169                                 if (bootverbose)
 1170                                         printf(" ECP+EPP");
 1171 
 1172                                 ppc->ppc_type = PPC_TYPE_SMCLIKE;
 1173 
 1174                         } else {
 1175                                 outb(efdr, inb(efdr) | WINB_ECP);
 1176                                 if (bootverbose)
 1177                                         printf(" ECP");
 1178                         }
 1179                 } else {
 1180                         /* select EPP_SPP otherwise */
 1181                         outb(efdr, inb(efdr) | WINB_EPP_SPP);
 1182                         if (bootverbose)
 1183                                 printf(" EPP SPP");
 1184                 }
 1185                 ppc->ppc_avm = chipset_mode;
 1186         }
 1187 
 1188         if (bootverbose)
 1189                 printf("\n");
 1190         
 1191         /* exit configuration mode */
 1192         outb(efer, 0xaa);
 1193 
 1194         switch (ppc->ppc_type) {
 1195         case PPC_TYPE_SMCLIKE:
 1196                 ppc_smclike_setmode(ppc, chipset_mode);
 1197                 break;
 1198         default:
 1199                 ppc_generic_setmode(ppc, chipset_mode);
 1200                 break;
 1201         }
 1202 
 1203         return (chipset_mode);
 1204 }
 1205 #endif
 1206 
 1207 /*
 1208  * ppc_generic_detect
 1209  */
 1210 static int
 1211 ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
 1212 {
 1213         /* default to generic */
 1214         ppc->ppc_type = PPC_TYPE_GENERIC;
 1215 
 1216         if (bootverbose)
 1217                 printf("ppc%d:", ppc->ppc_unit);
 1218 
 1219         /* first, check for ECP */
 1220         w_ecr(ppc, PPC_ECR_PS2);
 1221         if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
 1222                 ppc->ppc_dtm |= PPB_ECP | PPB_SPP;
 1223                 if (bootverbose)
 1224                         printf(" ECP SPP");
 1225 
 1226                 /* search for SMC style ECP+EPP mode */
 1227                 w_ecr(ppc, PPC_ECR_EPP);
 1228         }
 1229 
 1230         /* try to reset EPP timeout bit */
 1231         if (ppc_check_epp_timeout(ppc)) {
 1232                 ppc->ppc_dtm |= PPB_EPP;
 1233 
 1234                 if (ppc->ppc_dtm & PPB_ECP) {
 1235                         /* SMC like chipset found */
 1236                         ppc->ppc_model = SMC_LIKE;
 1237                         ppc->ppc_type = PPC_TYPE_SMCLIKE;
 1238 
 1239                         if (bootverbose)
 1240                                 printf(" ECP+EPP");
 1241                 } else {
 1242                         if (bootverbose)
 1243                                 printf(" EPP");
 1244                 }
 1245         } else {
 1246                 /* restore to standard mode */
 1247                 w_ecr(ppc, PPC_ECR_STD);
 1248         }
 1249 
 1250         /* XXX try to detect NIBBLE and PS2 modes */
 1251         ppc->ppc_dtm |= PPB_NIBBLE;
 1252 
 1253         if (bootverbose)
 1254                 printf(" SPP");
 1255 
 1256         if (chipset_mode)
 1257                 ppc->ppc_avm = chipset_mode;
 1258         else
 1259                 ppc->ppc_avm = ppc->ppc_dtm;
 1260 
 1261         if (bootverbose)
 1262                 printf("\n");
 1263 
 1264         switch (ppc->ppc_type) {
 1265         case PPC_TYPE_SMCLIKE:
 1266                 ppc_smclike_setmode(ppc, chipset_mode);
 1267                 break;
 1268         default:
 1269                 ppc_generic_setmode(ppc, chipset_mode);
 1270                 break;
 1271         }
 1272 
 1273         return (chipset_mode);
 1274 }
 1275 
 1276 /*
 1277  * ppc_detect()
 1278  *
 1279  * mode is the mode suggested at boot
 1280  */
 1281 static int
 1282 ppc_detect(struct ppc_data *ppc, int chipset_mode) {
 1283 
 1284 #ifdef PPC_PROBE_CHIPSET
 1285         int i, mode;
 1286 
 1287         /* list of supported chipsets */
 1288         int (*chipset_detect[])(struct ppc_data *, int) = {
 1289                 ppc_pc873xx_detect,
 1290                 ppc_smc37c66xgt_detect,
 1291                 ppc_w83877f_detect,
 1292                 ppc_smc37c935_detect,
 1293                 ppc_generic_detect,
 1294                 NULL
 1295         };
 1296 #endif
 1297 
 1298         /* if can't find the port and mode not forced return error */
 1299         if (!ppc_detect_port(ppc) && chipset_mode == 0)
 1300                 return (EIO);                   /* failed, port not present */
 1301 
 1302         /* assume centronics compatible mode is supported */
 1303         ppc->ppc_avm = PPB_COMPATIBLE;
 1304 
 1305 #ifdef PPC_PROBE_CHIPSET
 1306         /* we have to differenciate available chipset modes,
 1307          * chipset running modes and IEEE-1284 operating modes
 1308          *
 1309          * after detection, the port must support running in compatible mode
 1310          */
 1311         if (ppc->ppc_flags & 0x40) {
 1312                 if (bootverbose)
 1313                         printf("ppc: chipset forced to generic\n");
 1314 #endif
 1315 
 1316                 ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
 1317 
 1318 #ifdef PPC_PROBE_CHIPSET
 1319         } else {
 1320                 for (i=0; chipset_detect[i] != NULL; i++) {
 1321                         if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
 1322                                 ppc->ppc_mode = mode;
 1323                                 break;
 1324                         }
 1325                 }
 1326         }
 1327 #endif
 1328 
 1329         /* configure/detect ECP FIFO */
 1330         if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
 1331                 ppc_detect_fifo(ppc);
 1332 
 1333         return (0);
 1334 }
 1335 
 1336 /*
 1337  * ppc_exec_microseq()
 1338  *
 1339  * Execute a microsequence.
 1340  * Microsequence mechanism is supposed to handle fast I/O operations.
 1341  */
 1342 static int
 1343 ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
 1344 {
 1345         struct ppc_data *ppc = DEVTOSOFTC(dev);
 1346         struct ppb_microseq *mi;
 1347         char cc, *p;
 1348         int i, iter, len;
 1349         int error;
 1350 
 1351         register int reg;
 1352         register char mask;
 1353         register int accum = 0;
 1354         register char *ptr = 0;
 1355 
 1356         struct ppb_microseq *stack = 0;
 1357 
 1358 /* microsequence registers are equivalent to PC-like port registers */
 1359 
 1360 #define r_reg(register,ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, register))
 1361 #define w_reg(register, ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, register, byte))
 1362 
 1363 #define INCR_PC (mi ++)         /* increment program counter */
 1364 
 1365         mi = *p_msq;
 1366         for (;;) {
 1367                 switch (mi->opcode) {                                           
 1368                 case MS_OP_RSET:
 1369                         cc = r_reg(mi->arg[0].i, ppc);
 1370                         cc &= (char)mi->arg[2].i;       /* clear mask */
 1371                         cc |= (char)mi->arg[1].i;       /* assert mask */
 1372                         w_reg(mi->arg[0].i, ppc, cc);
 1373                         INCR_PC;
 1374                         break;
 1375 
 1376                 case MS_OP_RASSERT_P:
 1377                         reg = mi->arg[1].i;
 1378                         ptr = ppc->ppc_ptr;
 1379 
 1380                         if ((len = mi->arg[0].i) == MS_ACCUM) {
 1381                                 accum = ppc->ppc_accum;
 1382                                 for (; accum; accum--)
 1383                                         w_reg(reg, ppc, *ptr++);
 1384                                 ppc->ppc_accum = accum;
 1385                         } else
 1386                                 for (i=0; i<len; i++)
 1387                                         w_reg(reg, ppc, *ptr++);
 1388                         ppc->ppc_ptr = ptr;
 1389 
 1390                         INCR_PC;
 1391                         break;
 1392 
 1393                 case MS_OP_RFETCH_P:
 1394                         reg = mi->arg[1].i;
 1395                         mask = (char)mi->arg[2].i;
 1396                         ptr = ppc->ppc_ptr;
 1397 
 1398                         if ((len = mi->arg[0].i) == MS_ACCUM) {
 1399                                 accum = ppc->ppc_accum;
 1400                                 for (; accum; accum--)
 1401                                         *ptr++ = r_reg(reg, ppc) & mask;
 1402                                 ppc->ppc_accum = accum;
 1403                         } else
 1404                                 for (i=0; i<len; i++)
 1405                                         *ptr++ = r_reg(reg, ppc) & mask;
 1406                         ppc->ppc_ptr = ptr;
 1407 
 1408                         INCR_PC;
 1409                         break;                                        
 1410 
 1411                 case MS_OP_RFETCH:
 1412                         *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
 1413                                                         (char)mi->arg[1].i;
 1414                         INCR_PC;
 1415                         break;                                        
 1416 
 1417                 case MS_OP_RASSERT:
 1418                 case MS_OP_DELAY:
 1419                 
 1420                 /* let's suppose the next instr. is the same */
 1421                 prefetch:
 1422                         for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
 1423                                 w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
 1424 
 1425                         if (mi->opcode == MS_OP_DELAY) {
 1426                                 DELAY(mi->arg[0].i);
 1427                                 INCR_PC;
 1428                                 goto prefetch;
 1429                         }
 1430                         break;
 1431 
 1432                 case MS_OP_ADELAY:
 1433                         if (mi->arg[0].i)
 1434                                 tsleep(NULL, PPBPRI, "ppbdelay",
 1435                                                 mi->arg[0].i * (hz/1000));
 1436                         INCR_PC;
 1437                         break;
 1438 
 1439                 case MS_OP_TRIG:
 1440                         reg = mi->arg[0].i;
 1441                         iter = mi->arg[1].i;
 1442                         p = (char *)mi->arg[2].p;
 1443 
 1444                         /* XXX delay limited to 255 us */
 1445                         for (i=0; i<iter; i++) {
 1446                                 w_reg(reg, ppc, *p++);
 1447                                 DELAY((unsigned char)*p++);
 1448                         }
 1449                         INCR_PC;
 1450                         break;
 1451 
 1452                 case MS_OP_SET:
 1453                         ppc->ppc_accum = mi->arg[0].i;
 1454                         INCR_PC;
 1455                         break;                                         
 1456 
 1457                 case MS_OP_DBRA:
 1458                         if (--ppc->ppc_accum > 0)
 1459                                 mi += mi->arg[0].i;
 1460                         INCR_PC;
 1461                         break;                                        
 1462 
 1463                 case MS_OP_BRSET:
 1464                         cc = r_str(ppc);
 1465                         if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) 
 1466                                 mi += mi->arg[1].i;                      
 1467                         INCR_PC;
 1468                         break;
 1469 
 1470                 case MS_OP_BRCLEAR:
 1471                         cc = r_str(ppc);
 1472                         if ((cc & (char)mi->arg[0].i) == 0)    
 1473                                 mi += mi->arg[1].i;                             
 1474                         INCR_PC;
 1475                         break;                                
 1476 
 1477                 case MS_OP_BRSTAT:
 1478                         cc = r_str(ppc);
 1479                         if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
 1480                                                         (char)mi->arg[0].i)
 1481                                 mi += mi->arg[2].i;
 1482                         INCR_PC;
 1483                         break;
 1484 
 1485                 case MS_OP_C_CALL:
 1486                         /*
 1487                          * If the C call returns !0 then end the microseq.
 1488                          * The current state of ptr is passed to the C function
 1489                          */
 1490                         if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
 1491                                 return (error);
 1492 
 1493                         INCR_PC;
 1494                         break;
 1495 
 1496                 case MS_OP_PTR:
 1497                         ppc->ppc_ptr = (char *)mi->arg[0].p;
 1498                         INCR_PC;
 1499                         break;
 1500 
 1501                 case MS_OP_CALL:
 1502                         if (stack)
 1503                                 panic("%s: too much calls", __func__);
 1504 
 1505                         if (mi->arg[0].p) {
 1506                                 /* store the state of the actual
 1507                                  * microsequence
 1508                                  */
 1509                                 stack = mi;
 1510 
 1511                                 /* jump to the new microsequence */
 1512                                 mi = (struct ppb_microseq *)mi->arg[0].p;
 1513                         } else
 1514                                 INCR_PC;
 1515 
 1516                         break;
 1517 
 1518                 case MS_OP_SUBRET:
 1519                         /* retrieve microseq and pc state before the call */
 1520                         mi = stack;
 1521 
 1522                         /* reset the stack */
 1523                         stack = 0;
 1524 
 1525                         /* XXX return code */
 1526 
 1527                         INCR_PC;
 1528                         break;
 1529 
 1530                 case MS_OP_PUT:
 1531                 case MS_OP_GET:
 1532                 case MS_OP_RET:
 1533                         /* can't return to ppb level during the execution
 1534                          * of a submicrosequence */
 1535                         if (stack)
 1536                                 panic("%s: can't return to ppb level",
 1537                                                                 __func__);
 1538 
 1539                         /* update pc for ppb level of execution */
 1540                         *p_msq = mi;
 1541 
 1542                         /* return to ppb level of execution */
 1543                         return (0);
 1544 
 1545                 default:                         
 1546                         panic("%s: unknown microsequence opcode 0x%x",
 1547                                 __func__, mi->opcode);        
 1548                 }
 1549         }
 1550 
 1551         /* unreached */
 1552 }
 1553 
 1554 static void
 1555 ppcintr(void *arg)
 1556 {
 1557         device_t dev = (device_t)arg;
 1558         struct ppc_data *ppc = (struct ppc_data *)device_get_softc(dev);
 1559         u_char ctr, ecr, str;
 1560 
 1561         str = r_str(ppc);
 1562         ctr = r_ctr(ppc);
 1563         ecr = r_ecr(ppc);
 1564 
 1565 #if PPC_DEBUG > 1
 1566                 printf("![%x/%x/%x]", ctr, ecr, str);
 1567 #endif
 1568 
 1569         /* don't use ecp mode with IRQENABLE set */
 1570         if (ctr & IRQENABLE) {
 1571                 return;
 1572         }
 1573 
 1574         /* interrupts are generated by nFault signal
 1575          * only in ECP mode */
 1576         if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
 1577                 /* check if ppc driver has programmed the
 1578                  * nFault interrupt */
 1579                 if  (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
 1580 
 1581                         w_ecr(ppc, ecr | PPC_nFAULT_INTR);
 1582                         ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
 1583                 } else {
 1584                         /* shall be handled by underlying layers XXX */
 1585                         return;
 1586                 }
 1587         }
 1588 
 1589         if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
 1590                 /* disable interrupts (should be done by hardware though) */
 1591                 w_ecr(ppc, ecr | PPC_SERVICE_INTR);
 1592                 ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
 1593                 ecr = r_ecr(ppc);
 1594 
 1595                 /* check if DMA completed */
 1596                 if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
 1597 #ifdef PPC_DEBUG
 1598                         printf("a");
 1599 #endif
 1600                         /* stop DMA */
 1601                         w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
 1602                         ecr = r_ecr(ppc);
 1603 
 1604                         if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
 1605 #ifdef PPC_DEBUG
 1606                                 printf("d");
 1607 #endif
 1608                                 isa_dmadone(
 1609                                         ppc->ppc_dmaflags,
 1610                                         ppc->ppc_dmaddr,
 1611                                         ppc->ppc_dmacnt,
 1612                                         ppc->ppc_dmachan);
 1613 
 1614                                 ppc->ppc_dmastat = PPC_DMA_COMPLETE;
 1615 
 1616                                 /* wakeup the waiting process */
 1617                                 wakeup((caddr_t)ppc);
 1618                         }
 1619                 }
 1620         } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
 1621 
 1622                 /* classic interrupt I/O */
 1623                 ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
 1624         }
 1625 
 1626         return;
 1627 }
 1628 
 1629 static int
 1630 ppc_read(device_t dev, char *buf, int len, int mode)
 1631 {
 1632         return (EINVAL);
 1633 }
 1634 
 1635 /*
 1636  * Call this function if you want to send data in any advanced mode
 1637  * of your parallel port: FIFO, DMA
 1638  *
 1639  * If what you want is not possible (no ECP, no DMA...),
 1640  * EINVAL is returned
 1641  */
 1642 static int
 1643 ppc_write(device_t dev, char *buf, int len, int how)
 1644 {
 1645         struct ppc_data *ppc = DEVTOSOFTC(dev);
 1646         char ecr, ecr_sav, ctr, ctr_sav;
 1647         int s, error = 0;
 1648         int spin;
 1649 
 1650 #ifdef PPC_DEBUG
 1651         printf("w");
 1652 #endif
 1653 
 1654         ecr_sav = r_ecr(ppc);
 1655         ctr_sav = r_ctr(ppc);
 1656 
 1657         /*
 1658          * Send buffer with DMA, FIFO and interrupts
 1659          */
 1660         if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_registered)) {
 1661 
 1662             if (ppc->ppc_dmachan > 0) {
 1663 
 1664                 /* byte mode, no intr, no DMA, dir=0, flush fifo
 1665                  */
 1666                 ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
 1667                 w_ecr(ppc, ecr);
 1668 
 1669                 /* disable nAck interrupts */
 1670                 ctr = r_ctr(ppc);
 1671                 ctr &= ~IRQENABLE;
 1672                 w_ctr(ppc, ctr);
 1673 
 1674                 ppc->ppc_dmaflags = 0;
 1675                 ppc->ppc_dmaddr = (caddr_t)buf;
 1676                 ppc->ppc_dmacnt = (u_int)len;
 1677 
 1678                 switch (ppc->ppc_mode) {
 1679                 case PPB_COMPATIBLE:
 1680                         /* compatible mode with FIFO, no intr, DMA, dir=0 */
 1681                         ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
 1682                         break;
 1683                 case PPB_ECP:
 1684                         ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
 1685                         break;
 1686                 default:
 1687                         error = EINVAL;
 1688                         goto error;
 1689                 }
 1690 
 1691                 w_ecr(ppc, ecr);
 1692                 ecr = r_ecr(ppc);
 1693 
 1694                 /* enter splhigh() not to be preempted
 1695                  * by the dma interrupt, we may miss
 1696                  * the wakeup otherwise
 1697                  */
 1698                 s = splhigh();
 1699 
 1700                 ppc->ppc_dmastat = PPC_DMA_INIT;
 1701 
 1702                 /* enable interrupts */
 1703                 ecr &= ~PPC_SERVICE_INTR;
 1704                 ppc->ppc_irqstat = PPC_IRQ_DMA;
 1705                 w_ecr(ppc, ecr);
 1706 
 1707                 isa_dmastart(
 1708                         ppc->ppc_dmaflags,
 1709                         ppc->ppc_dmaddr,
 1710                         ppc->ppc_dmacnt,
 1711                         ppc->ppc_dmachan);
 1712 #ifdef PPC_DEBUG
 1713                 printf("s%d", ppc->ppc_dmacnt);
 1714 #endif
 1715                 ppc->ppc_dmastat = PPC_DMA_STARTED;
 1716 
 1717                 /* Wait for the DMA completed interrupt. We hope we won't
 1718                  * miss it, otherwise a signal will be necessary to unlock the
 1719                  * process.
 1720                  */
 1721                 do {
 1722                         /* release CPU */
 1723                         error = tsleep((caddr_t)ppc,
 1724                                 PPBPRI | PCATCH, "ppcdma", 0);
 1725 
 1726                 } while (error == EWOULDBLOCK);
 1727 
 1728                 splx(s);
 1729 
 1730                 if (error) {
 1731 #ifdef PPC_DEBUG
 1732                         printf("i");
 1733 #endif
 1734                         /* stop DMA */
 1735                         isa_dmadone(
 1736                                 ppc->ppc_dmaflags, ppc->ppc_dmaddr,
 1737                                 ppc->ppc_dmacnt, ppc->ppc_dmachan);
 1738 
 1739                         /* no dma, no interrupt, flush the fifo */
 1740                         w_ecr(ppc, PPC_ECR_RESET);
 1741 
 1742                         ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
 1743                         goto error;
 1744                 }
 1745 
 1746                 /* wait for an empty fifo */
 1747                 while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
 1748 
 1749                         for (spin=100; spin; spin--)
 1750                                 if (r_ecr(ppc) & PPC_FIFO_EMPTY)
 1751                                         goto fifo_empty;
 1752 #ifdef PPC_DEBUG
 1753                         printf("Z");
 1754 #endif
 1755                         error = tsleep((caddr_t)ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
 1756                         if (error != EWOULDBLOCK) {
 1757 #ifdef PPC_DEBUG
 1758                                 printf("I");
 1759 #endif
 1760                                 /* no dma, no interrupt, flush the fifo */
 1761                                 w_ecr(ppc, PPC_ECR_RESET);
 1762 
 1763                                 ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
 1764                                 error = EINTR;
 1765                                 goto error;
 1766                         }
 1767                 }
 1768 
 1769 fifo_empty:
 1770                 /* no dma, no interrupt, flush the fifo */
 1771                 w_ecr(ppc, PPC_ECR_RESET);
 1772 
 1773             } else
 1774                 error = EINVAL;                 /* XXX we should FIFO and
 1775                                                  * interrupts */
 1776         } else
 1777                 error = EINVAL;
 1778 
 1779 error:
 1780 
 1781         /* PDRQ must be kept unasserted until nPDACK is
 1782          * deasserted for a minimum of 350ns (SMC datasheet)
 1783          *
 1784          * Consequence may be a FIFO that never empty
 1785          */
 1786         DELAY(1);
 1787 
 1788         w_ecr(ppc, ecr_sav);
 1789         w_ctr(ppc, ctr_sav);
 1790 
 1791         return (error);
 1792 }
 1793 
 1794 static void
 1795 ppc_reset_epp(device_t dev)
 1796 {
 1797         struct ppc_data *ppc = DEVTOSOFTC(dev);
 1798         
 1799         ppc_reset_epp_timeout(ppc);
 1800 
 1801         return;
 1802 }
 1803 
 1804 static int
 1805 ppc_setmode(device_t dev, int mode)
 1806 {
 1807         struct ppc_data *ppc = DEVTOSOFTC(dev);
 1808 
 1809         switch (ppc->ppc_type) {
 1810         case PPC_TYPE_SMCLIKE:
 1811                 return (ppc_smclike_setmode(ppc, mode));
 1812                 break;
 1813 
 1814         case PPC_TYPE_GENERIC:
 1815         default:
 1816                 return (ppc_generic_setmode(ppc, mode));
 1817                 break;
 1818         }
 1819 
 1820         /* not reached */
 1821         return (ENXIO);
 1822 }
 1823 
 1824 static struct isa_pnp_id lpc_ids[] = {
 1825         { 0x0004d041, "Standard parallel printer port" }, /* PNP0400 */
 1826         { 0x0104d041, "ECP parallel printer port" }, /* PNP0401 */
 1827         { 0 }
 1828 };
 1829 
 1830 static int
 1831 ppc_probe(device_t dev)
 1832 {
 1833 #ifdef __i386__
 1834         static short next_bios_ppc = 0;
 1835 #endif
 1836         struct ppc_data *ppc;
 1837         device_t parent;
 1838         int error;
 1839         u_long port;
 1840 
 1841         parent = device_get_parent(dev);
 1842 
 1843         error = ISA_PNP_PROBE(parent, dev, lpc_ids);
 1844         if (error == ENXIO)
 1845                 return (ENXIO);
 1846         else if (error != 0)    /* XXX shall be set after detection */
 1847                 device_set_desc(dev, "Parallel port");
 1848 
 1849         /*
 1850          * Allocate the ppc_data structure.
 1851          */
 1852         ppc = DEVTOSOFTC(dev);
 1853         bzero(ppc, sizeof(struct ppc_data));
 1854 
 1855         ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0;
 1856         ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0;
 1857 
 1858         /* retrieve ISA parameters */
 1859         error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port, NULL);
 1860 
 1861 #ifdef __i386__
 1862         /*
 1863          * If port not specified, use bios list.
 1864          */
 1865         if (error) {
 1866                 if((next_bios_ppc < BIOS_MAX_PPC) &&
 1867                                 (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
 1868                         port = *(BIOS_PORTS+next_bios_ppc++);
 1869                         if (bootverbose)
 1870                           device_printf(dev, "parallel port found at 0x%x\n",
 1871                                         (int) port);
 1872                 } else {
 1873                         device_printf(dev, "parallel port not found.\n");
 1874                         return ENXIO;
 1875                 }
 1876                 bus_set_resource(dev, SYS_RES_IOPORT, 0, port,
 1877                                  IO_LPTSIZE_EXTENDED);
 1878         }
 1879 #endif
 1880 #ifdef __alpha__
 1881         /*
 1882          * There isn't a bios list on alpha. Put it in the usual place.
 1883          */
 1884         if (error) {
 1885                 bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc,
 1886                                  IO_LPTSIZE_NORMAL);
 1887         }
 1888 #endif
 1889 
 1890         /* IO port is mandatory */
 1891 
 1892         /* Try "extended" IO port range...*/
 1893         ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
 1894                                              &ppc->rid_ioport, 0, ~0,
 1895                                              IO_LPTSIZE_EXTENDED, RF_ACTIVE);
 1896 
 1897         if (ppc->res_ioport != 0) {
 1898                 if (bootverbose)
 1899                         device_printf(dev, "using extended I/O port range\n");
 1900         } else {
 1901                 /* Failed? If so, then try the "normal" IO port range... */
 1902                  ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
 1903                                                       &ppc->rid_ioport, 0, ~0,
 1904                                                       IO_LPTSIZE_NORMAL,
 1905                                                       RF_ACTIVE);
 1906                 if (ppc->res_ioport != 0) {
 1907                         if (bootverbose)
 1908                                 device_printf(dev, "using normal I/O port range\n");
 1909                 } else {
 1910                         device_printf(dev, "cannot reserve I/O port range\n");
 1911                         goto error;
 1912                 }
 1913         }
 1914 
 1915         ppc->ppc_base = rman_get_start(ppc->res_ioport);
 1916 
 1917         ppc->bsh = rman_get_bushandle(ppc->res_ioport);
 1918         ppc->bst = rman_get_bustag(ppc->res_ioport);
 1919 
 1920         ppc->ppc_flags = device_get_flags(dev);
 1921 
 1922         if (!(ppc->ppc_flags & 0x20)) {
 1923                 ppc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &ppc->rid_irq,
 1924                                                   0ul, ~0ul, 1, RF_SHAREABLE);
 1925                 ppc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, &ppc->rid_drq,
 1926                                                   0ul, ~0ul, 1, RF_ACTIVE);
 1927         }
 1928 
 1929         if (ppc->res_irq)
 1930                 ppc->ppc_irq = rman_get_start(ppc->res_irq);
 1931         if (ppc->res_drq)
 1932                 ppc->ppc_dmachan = rman_get_start(ppc->res_drq);
 1933 
 1934         ppc->ppc_unit = device_get_unit(dev);
 1935         ppc->ppc_model = GENERIC;
 1936 
 1937         ppc->ppc_mode = PPB_COMPATIBLE;
 1938         ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;
 1939 
 1940         ppc->ppc_type = PPC_TYPE_GENERIC;
 1941 
 1942         /*
 1943          * Try to detect the chipset and its mode.
 1944          */
 1945         if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
 1946                 goto error;
 1947 
 1948         return (0);
 1949 
 1950 error:
 1951         if (ppc->res_irq != 0) {
 1952                 bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
 1953                                      ppc->res_irq);
 1954         }
 1955         if (ppc->res_ioport != 0) {
 1956                 bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
 1957                                         ppc->res_ioport);
 1958                 bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
 1959                                      ppc->res_ioport);
 1960         }
 1961         if (ppc->res_drq != 0) {
 1962                 bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
 1963                                         ppc->res_drq);
 1964                 bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
 1965                                      ppc->res_drq);
 1966         }
 1967         return (ENXIO);
 1968 }
 1969 
 1970 static int
 1971 ppc_attach(device_t dev)
 1972 {
 1973         struct ppc_data *ppc = DEVTOSOFTC(dev);
 1974 
 1975         device_t ppbus;
 1976         device_t parent = device_get_parent(dev);
 1977 
 1978         device_printf(dev, "%s chipset (%s) in %s mode%s\n",
 1979                       ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
 1980                       ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
 1981                       ppc_epp_protocol[ppc->ppc_epp] : "");
 1982         
 1983         if (ppc->ppc_fifo)
 1984                 device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
 1985                               ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
 1986 
 1987         if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
 1988                 /* acquire the DMA channel forever */   /* XXX */
 1989                 isa_dma_acquire(ppc->ppc_dmachan);
 1990                 isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
 1991         }
 1992 
 1993         /* add ppbus as a child of this isa to parallel bridge */
 1994         ppbus = device_add_child(dev, "ppbus", -1);
 1995 
 1996         /*
 1997          * Probe the ppbus and attach devices found.
 1998          */
 1999         device_probe_and_attach(ppbus);
 2000 
 2001         /* register the ppc interrupt handler as default */
 2002         if (ppc->res_irq) {
 2003                 /* default to the tty mask for registration */  /* XXX */
 2004                 if (BUS_SETUP_INTR(parent, dev, ppc->res_irq, INTR_TYPE_TTY,
 2005                                             ppcintr, dev, &ppc->intr_cookie) == 0) {
 2006 
 2007                         /* remember the ppcintr is registered */
 2008                         ppc->ppc_registered = 1;
 2009                 }
 2010         }
 2011 
 2012         return (0);
 2013 }
 2014 
 2015 static u_char
 2016 ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
 2017 {
 2018         struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
 2019         switch (iop) {
 2020         case PPB_OUTSB_EPP:
 2021             bus_space_write_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
 2022                 break;
 2023         case PPB_OUTSW_EPP:
 2024             bus_space_write_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
 2025                 break;
 2026         case PPB_OUTSL_EPP:
 2027             bus_space_write_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
 2028                 break;
 2029         case PPB_INSB_EPP:
 2030             bus_space_read_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
 2031                 break;
 2032         case PPB_INSW_EPP:
 2033             bus_space_read_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
 2034                 break;
 2035         case PPB_INSL_EPP:
 2036             bus_space_read_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
 2037                 break;
 2038         case PPB_RDTR:
 2039                 return (r_dtr(ppc));
 2040                 break;
 2041         case PPB_RSTR:
 2042                 return (r_str(ppc));
 2043                 break;
 2044         case PPB_RCTR:
 2045                 return (r_ctr(ppc));
 2046                 break;
 2047         case PPB_REPP_A:
 2048                 return (r_epp_A(ppc));
 2049                 break;
 2050         case PPB_REPP_D:
 2051                 return (r_epp_D(ppc));
 2052                 break;
 2053         case PPB_RECR:
 2054                 return (r_ecr(ppc));
 2055                 break;
 2056         case PPB_RFIFO:
 2057                 return (r_fifo(ppc));
 2058                 break;
 2059         case PPB_WDTR:
 2060                 w_dtr(ppc, byte);
 2061                 break;
 2062         case PPB_WSTR:
 2063                 w_str(ppc, byte);
 2064                 break;
 2065         case PPB_WCTR:
 2066                 w_ctr(ppc, byte);
 2067                 break;
 2068         case PPB_WEPP_A:
 2069                 w_epp_A(ppc, byte);
 2070                 break;
 2071         case PPB_WEPP_D:
 2072                 w_epp_D(ppc, byte);
 2073                 break;
 2074         case PPB_WECR:
 2075                 w_ecr(ppc, byte);
 2076                 break;
 2077         case PPB_WFIFO:
 2078                 w_fifo(ppc, byte);
 2079                 break;
 2080         default:
 2081                 panic("%s: unknown I/O operation", __func__);
 2082                 break;
 2083         }
 2084 
 2085         return (0);     /* not significative */
 2086 }
 2087 
 2088 static int
 2089 ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
 2090 {
 2091         struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
 2092 
 2093         switch (index) {
 2094         case PPC_IVAR_EPP_PROTO:
 2095                 *val = (u_long)ppc->ppc_epp;
 2096                 break;
 2097         case PPC_IVAR_IRQ:
 2098                 *val = (u_long)ppc->ppc_irq;
 2099                 break;
 2100         default:
 2101                 return (ENOENT);
 2102         }
 2103 
 2104         return (0);
 2105 }
 2106 
 2107 /*
 2108  * Resource is useless here since ppbus devices' interrupt handlers are
 2109  * multiplexed to the same resource initially allocated by ppc
 2110  */
 2111 static int
 2112 ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
 2113                         void (*ihand)(void *), void *arg, void **cookiep)
 2114 {
 2115         int error;
 2116         struct ppc_data *ppc = DEVTOSOFTC(bus);
 2117 
 2118         if (ppc->ppc_registered) {
 2119                 /* XXX refuse registration if DMA is in progress */
 2120 
 2121                 /* first, unregister the default interrupt handler */
 2122                 if ((error = BUS_TEARDOWN_INTR(device_get_parent(bus),
 2123                                 bus, ppc->res_irq, ppc->intr_cookie)))
 2124                         return (error);
 2125 
 2126 /*              bus_deactivate_resource(bus, SYS_RES_IRQ, ppc->rid_irq, */
 2127 /*                                      ppc->res_irq); */
 2128 
 2129                 /* DMA/FIFO operation won't be possible anymore */
 2130                 ppc->ppc_registered = 0;
 2131         }
 2132 
 2133         /* pass registration to the upper layer, ignore the incoming resource */
 2134         return (BUS_SETUP_INTR(device_get_parent(bus), child,
 2135                                r, flags, ihand, arg, cookiep));
 2136 }
 2137 
 2138 /*
 2139  * When no underlying device has a registered interrupt, register the ppc
 2140  * layer one
 2141  */
 2142 static int
 2143 ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
 2144 {
 2145         int error;
 2146         struct ppc_data *ppc = DEVTOSOFTC(bus);
 2147         device_t parent = device_get_parent(bus);
 2148 
 2149         /* pass unregistration to the upper layer */
 2150         if ((error = BUS_TEARDOWN_INTR(parent, child, r, ih)))
 2151                 return (error);
 2152 
 2153         /* default to the tty mask for registration */          /* XXX */
 2154         if (ppc->ppc_irq &&
 2155                 !(error = BUS_SETUP_INTR(parent, bus, ppc->res_irq,
 2156                         INTR_TYPE_TTY, ppcintr, bus, &ppc->intr_cookie))) {
 2157 
 2158                 /* remember the ppcintr is registered */
 2159                 ppc->ppc_registered = 1;
 2160         }
 2161 
 2162         return (error);
 2163 }
 2164 
 2165 DRIVER_MODULE(ppc, isa, ppc_driver, ppc_devclass, 0, 0);
 2166 DRIVER_MODULE(ppc, acpi, ppc_driver, ppc_devclass, 0, 0);

Cache object: 14283704688c9e97e4945a791ecec55a


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