The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

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

Cache object: 8f7a76a43ff64c011eb376b718496a38


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