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  -  FREEBSD11  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 9df6ba23fb5396351e755f691bc29c08


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