root/dev/isa/isa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isamatch
  2. isaattach
  3. isaprint
  4. isascan
  5. isa_intr_typename

    1 /*      $OpenBSD: isa.c,v 1.39 2003/06/03 21:09:02 deraadt Exp $        */
    2 /*      $NetBSD: isa.c,v 1.85 1996/05/14 00:31:04 thorpej Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1997, Jason Downs.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
   17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
   20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*-
   30  * Copyright (c) 1993, 1994 Charles Hannum.  All rights reserved.
   31  *
   32  * Redistribution and use in source and binary forms, with or without
   33  * modification, are permitted provided that the following conditions
   34  * are met:
   35  * 1. Redistributions of source code must retain the above copyright
   36  *    notice, this list of conditions and the following disclaimer.
   37  * 2. Redistributions in binary form must reproduce the above copyright
   38  *    notice, this list of conditions and the following disclaimer in the
   39  *    documentation and/or other materials provided with the distribution.
   40  * 3. All advertising materials mentioning features or use of this software
   41  *    must display the following acknowledgement:
   42  *      This product includes software developed by Charles Hannum.
   43  * 4. The name of the author may not be used to endorse or promote products
   44  *    derived from this software without specific prior written permission.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   49  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   50  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   51  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   52  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   53  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   54  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   55  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   56  */
   57 
   58 #include <sys/param.h>
   59 #include <sys/systm.h>
   60 #include <sys/kernel.h>
   61 #include <sys/conf.h>
   62 #include <sys/malloc.h>
   63 #include <sys/device.h>
   64 #include <sys/extent.h>
   65 
   66 #include <machine/intr.h>
   67 
   68 #include <dev/isa/isareg.h>
   69 #include <dev/isa/isavar.h>
   70 #include <dev/isa/isadmareg.h>
   71 
   72 int isamatch(struct device *, void *, void *);
   73 void isaattach(struct device *, struct device *, void *);
   74 
   75 extern int autoconf_verbose;
   76 
   77 struct cfattach isa_ca = {
   78         sizeof(struct isa_softc), isamatch, isaattach
   79 };
   80 
   81 struct cfdriver isa_cd = {
   82         NULL, "isa", DV_DULL, 1
   83 };
   84 
   85 int
   86 isamatch(parent, match, aux)
   87         struct device *parent;
   88         void *match, *aux;
   89 {
   90         struct cfdata *cf = match;
   91         struct isabus_attach_args *iba = aux;
   92 
   93         if (strcmp(iba->iba_busname, cf->cf_driver->cd_name))
   94                 return (0);
   95 
   96         /* XXX check other indicators */
   97 
   98         return (1);
   99 }
  100 
  101 void
  102 isaattach(parent, self, aux)
  103         struct device *parent, *self;
  104         void *aux;
  105 {
  106         struct isa_softc *sc = (struct isa_softc *)self;
  107         struct isabus_attach_args *iba = aux;
  108 
  109         isa_attach_hook(parent, self, iba);
  110         printf("\n");
  111 
  112         sc->sc_iot = iba->iba_iot;
  113         sc->sc_memt = iba->iba_memt;
  114 #if NISADMA > 0
  115         sc->sc_dmat = iba->iba_dmat;
  116 #endif /* NISADMA > 0 */
  117         sc->sc_ic = iba->iba_ic;
  118 
  119 #if NISAPNP > 0
  120         isapnp_isa_attach_hook(sc);
  121 #endif
  122 
  123 #if NISADMA > 0
  124         /*
  125          * Map the registers used by the ISA DMA controller.
  126          * XXX Should be done in the isadmaattach routine.. but the delay
  127          * XXX port makes it troublesome.  Note that these aren't really
  128          * XXX valid on ISA busses without DMA.
  129          */
  130         if (bus_space_map(sc->sc_iot, IO_DMA1, DMA1_IOSIZE, 0, &sc->sc_dma1h))
  131                 panic("isaattach: can't map DMA controller #1");
  132         if (bus_space_map(sc->sc_iot, IO_DMA2, DMA2_IOSIZE, 0, &sc->sc_dma2h))
  133                 panic("isaattach: can't map DMA controller #2");
  134         if (bus_space_map(sc->sc_iot, IO_DMAPG, 0xf, 0, &sc->sc_dmapgh))
  135                 panic("isaattach: can't map DMA page registers");
  136 
  137         /*
  138          * Map port 0x84, which causes a 1.25us delay when read.
  139          * We do this now, since several drivers need it.
  140          * XXX this port doesn't exist on all ISA busses...
  141          */
  142         if (bus_space_subregion(sc->sc_iot, sc->sc_dmapgh, 0x04, 1,
  143             &sc->sc_delaybah))
  144 #else /* NISADMA > 0 */
  145         if (bus_space_map(sc->sc_iot, IO_DMAPG + 0x4, 0x1, 0,
  146             &sc->sc_delaybah))
  147 #endif /* NISADMA > 0 */
  148                 panic("isaattach: can't map `delay port'");     /* XXX */
  149 
  150         TAILQ_INIT(&sc->sc_subdevs);
  151         config_scan(isascan, self);
  152 }
  153 
  154 int
  155 isaprint(aux, isa)
  156         void *aux;
  157         const char *isa;
  158 {
  159         struct isa_attach_args *ia = aux;
  160 
  161         if (ia->ia_iosize)
  162                 printf(" port 0x%x", ia->ia_iobase);
  163         if (ia->ia_iosize > 1)
  164                 printf("/%d", ia->ia_iosize);
  165         if (ia->ia_msize)
  166                 printf(" iomem 0x%x", ia->ia_maddr);
  167         if (ia->ia_msize > 1)
  168                 printf("/%d", ia->ia_msize);
  169         if (ia->ia_irq != IRQUNK)
  170                 printf(" irq %d", ia->ia_irq);
  171         if (ia->ia_drq != DRQUNK)
  172                 printf(" drq %d", ia->ia_drq);
  173         if (ia->ia_drq2 != DRQUNK)
  174                 printf(" drq2 %d", ia->ia_drq2);
  175         return (UNCONF);
  176 }
  177 
  178 void
  179 isascan(parent, match)
  180         struct device *parent;
  181         void *match;
  182 {
  183         struct isa_softc *sc = (struct isa_softc *)parent;
  184         struct device *dev = match;
  185         struct cfdata *cf = dev->dv_cfdata;
  186         struct isa_attach_args ia;
  187 
  188         ia.ia_iot = sc->sc_iot;
  189         ia.ia_memt = sc->sc_memt;
  190 #if NISADMA > 0
  191         ia.ia_dmat = sc->sc_dmat;
  192 #endif /* NISADMA > 0 */
  193         ia.ia_ic = sc->sc_ic;
  194         ia.ia_iobase = cf->cf_iobase;
  195         ia.ia_iosize = 0x666;
  196         ia.ia_maddr = cf->cf_maddr;
  197         ia.ia_msize = cf->cf_msize;
  198         ia.ia_irq = cf->cf_irq == 2 ? 9 : cf->cf_irq;
  199         ia.ia_drq = cf->cf_drq;
  200         ia.ia_drq2 = cf->cf_drq2;
  201         ia.ia_delaybah = sc->sc_delaybah;
  202 
  203         if (cf->cf_fstate == FSTATE_STAR) {
  204                 struct isa_attach_args ia2 = ia;
  205 
  206                 if (autoconf_verbose)
  207                         printf(">>> probing for %s*\n",
  208                             cf->cf_driver->cd_name);
  209                 while ((*cf->cf_attach->ca_match)(parent, dev, &ia2) > 0) {
  210 #if !defined(__NO_ISA_INTR_CHECK)
  211                         if ((ia2.ia_irq != IRQUNK) &&
  212                             !isa_intr_check(sc->sc_ic, ia2.ia_irq, IST_EDGE)) {
  213                                 printf("%s%d: irq %d already in use\n",
  214                                     cf->cf_driver->cd_name, cf->cf_unit,
  215                                     ia2.ia_irq);
  216                                 ia2 = ia;
  217                                 break;
  218                         }
  219 #endif
  220 
  221                         if (autoconf_verbose)
  222                                 printf(">>> probe for %s* clone into %s%d\n",
  223                                     cf->cf_driver->cd_name,
  224                                     cf->cf_driver->cd_name, cf->cf_unit);
  225                         if (ia2.ia_iosize == 0x666) {
  226                                 printf("%s: iosize not repaired by driver\n",
  227                                     sc->sc_dev.dv_xname);
  228                                 ia2.ia_iosize = 0;
  229                         }
  230                         config_attach(parent, dev, &ia2, isaprint);
  231                         dev = config_make_softc(parent, cf);
  232 #if NISADMA > 0
  233                         if (ia2.ia_drq != DRQUNK)
  234                                 ISA_DRQ_ALLOC((struct device *)sc, ia2.ia_drq);
  235                         if (ia2.ia_drq2 != DRQUNK)
  236                                 ISA_DRQ_ALLOC((struct device *)sc, ia2.ia_drq2);
  237 #endif /* NISAMDA > 0 */
  238                         ia2 = ia;
  239                 }
  240                 if (autoconf_verbose)
  241                         printf(">>> probing for %s* finished\n",
  242                             cf->cf_driver->cd_name);
  243                 free(dev, M_DEVBUF);
  244                 return;
  245         }
  246 
  247         if (autoconf_verbose)
  248                 printf(">>> probing for %s%d\n", cf->cf_driver->cd_name,
  249                     cf->cf_unit);
  250         if ((*cf->cf_attach->ca_match)(parent, dev, &ia) > 0) {
  251 #if !defined(__NO_ISA_INTR_CHECK)
  252                 if ((ia.ia_irq != IRQUNK) &&
  253                     !isa_intr_check(sc->sc_ic, ia.ia_irq, IST_EDGE)) {
  254                         printf("%s%d: irq %d already in use\n",
  255                             cf->cf_driver->cd_name, cf->cf_unit, ia.ia_irq);
  256                         free(dev, M_DEVBUF);
  257                 } else {
  258 #endif
  259                         if (autoconf_verbose)
  260                                 printf(">>> probing for %s%d succeeded\n",
  261                                     cf->cf_driver->cd_name, cf->cf_unit);
  262                         config_attach(parent, dev, &ia, isaprint);
  263 
  264 #if NISADMA > 0
  265                         if (ia.ia_drq != DRQUNK)
  266                                 ISA_DRQ_ALLOC((struct device *)sc, ia.ia_drq);
  267                         if (ia.ia_drq2 != DRQUNK)
  268                                 ISA_DRQ_ALLOC((struct device *)sc, ia.ia_drq2);
  269 #endif /* NISAMDA > 0 */
  270 #if !defined(__NO_ISA_INTR_CHECK)
  271                 }
  272 #endif
  273         } else {
  274                 if (autoconf_verbose)
  275                         printf(">>> probing for %s%d failed\n",
  276                             cf->cf_driver->cd_name, cf->cf_unit);
  277                 free(dev, M_DEVBUF);
  278         }
  279 }
  280 
  281 char *
  282 isa_intr_typename(type)
  283         int type;
  284 {
  285 
  286         switch (type) {
  287         case IST_NONE:
  288                 return ("none");
  289         case IST_PULSE:
  290                 return ("pulsed");
  291         case IST_EDGE:
  292                 return ("edge-triggered");
  293         case IST_LEVEL:
  294                 return ("level-triggered");
  295         default:
  296                 panic("isa_intr_typename: invalid type %d", type);
  297         }
  298 }

/* [<][>][^][v][top][bottom][index][help] */