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/isa/isa.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 /*      $OpenBSD: isa.c,v 1.50 2022/04/06 18:59:28 naddy 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 <dev/isa/isareg.h>
   67 #include <dev/isa/isavar.h>
   68 #include <dev/isa/isadmareg.h>
   69 
   70 int isamatch(struct device *, void *, void *);
   71 void isaattach(struct device *, struct device *, void *);
   72 
   73 extern int autoconf_verbose;
   74 
   75 const struct cfattach isa_ca = {
   76         sizeof(struct isa_softc), isamatch, isaattach
   77 };
   78 
   79 struct cfdriver isa_cd = {
   80         NULL, "isa", DV_DULL, CD_INDIRECT
   81 };
   82 
   83 int
   84 isamatch(struct device *parent, void *match, void *aux)
   85 {
   86         struct cfdata *cf = match;
   87         struct isabus_attach_args *iba = aux;
   88 
   89         if (strcmp(iba->iba_busname, cf->cf_driver->cd_name))
   90                 return (0);
   91 
   92         /* XXX check other indicators */
   93 
   94         return (1);
   95 }
   96 
   97 void
   98 isaattach(struct device *parent, struct device *self, void *aux)
   99 {
  100         struct isa_softc *sc = (struct isa_softc *)self;
  101         struct isabus_attach_args *iba = aux;
  102 
  103         isa_attach_hook(parent, self, iba);
  104         printf("\n");
  105 
  106         sc->sc_iot = iba->iba_iot;
  107         sc->sc_memt = iba->iba_memt;
  108 #if NISADMA > 0
  109         sc->sc_dmat = iba->iba_dmat;
  110 #endif /* NISADMA > 0 */
  111         sc->sc_ic = iba->iba_ic;
  112 
  113 #if NISAPNP > 0
  114         isapnp_isa_attach_hook(sc);
  115 #endif
  116 
  117 #if NISADMA > 0
  118         /*
  119          * Map the registers used by the ISA DMA controller.
  120          * XXX Should be done in the isadmaattach routine.. but the delay
  121          * XXX port makes it troublesome.  Note that these aren't really
  122          * XXX valid on ISA busses without DMA.
  123          */
  124         if (bus_space_map(sc->sc_iot, IO_DMA1, DMA1_IOSIZE, 0, &sc->sc_dma1h))
  125                 panic("isaattach: can't map DMA controller #1");
  126         if (bus_space_map(sc->sc_iot, IO_DMA2, DMA2_IOSIZE, 0, &sc->sc_dma2h))
  127                 panic("isaattach: can't map DMA controller #2");
  128         if (bus_space_map(sc->sc_iot, IO_DMAPG, 0xf, 0, &sc->sc_dmapgh))
  129                 panic("isaattach: can't map DMA page registers");
  130 
  131         /*
  132          * Map port 0x84, which causes a 1.25us delay when read.
  133          * We do this now, since several drivers need it.
  134          * XXX this port doesn't exist on all ISA busses...
  135          */
  136         if (bus_space_subregion(sc->sc_iot, sc->sc_dmapgh, 0x04, 1,
  137             &sc->sc_delaybah))
  138 #else /* NISADMA > 0 */
  139         if (bus_space_map(sc->sc_iot, IO_DMAPG + 0x4, 0x1, 0,
  140             &sc->sc_delaybah))
  141 #endif /* NISADMA > 0 */
  142                 panic("isaattach: can't map `delay port'");     /* XXX */
  143 
  144         TAILQ_INIT(&sc->sc_subdevs);
  145         config_scan(isascan, self);
  146 }
  147 
  148 int
  149 isaprint(void *aux, const char *isa)
  150 {
  151         struct isa_attach_args *ia = aux;
  152         int irq, nirq;
  153         int dma, ndma;
  154 
  155         if (ia->ia_iosize)
  156                 printf(" port 0x%x", ia->ia_iobase);
  157         if (ia->ia_iosize > 1)
  158                 printf("/%d", ia->ia_iosize);
  159 
  160         if (ia->ia_msize)
  161                 printf(" iomem 0x%x", ia->ia_maddr);
  162         if (ia->ia_msize > 1)
  163                 printf("/%d", ia->ia_msize);
  164 
  165         nirq = ia->ipa_nirq;
  166         if (nirq < 0 || nirq > nitems(ia->ipa_irq))
  167                 nirq = 1;
  168         for (irq = 0; irq < nirq; irq++)
  169                 if (ia->ipa_irq[irq].num != IRQUNK)
  170                         printf(" irq %d", ia->ipa_irq[irq].num);
  171 
  172         ndma = ia->ipa_ndrq;
  173         if (ndma < 0 || ndma > nitems(ia->ipa_drq))
  174                 ndma = 2;
  175         for (dma = 0; dma < ndma; dma++)
  176                 if (ia->ipa_drq[dma].num != DRQUNK) {
  177                         if (dma == 0)
  178                                 printf(" drq");
  179                         else
  180                                 printf(" drq%d", dma + 1);
  181                         printf(" %d", ia->ipa_drq[dma].num);
  182                 }
  183 
  184         return (UNCONF);
  185 }
  186 
  187 void
  188 isascan(struct device *parent, void *match)
  189 {
  190         struct isa_softc *sc = (struct isa_softc *)parent;
  191         struct device *dev = match;
  192         struct cfdata *cf = dev->dv_cfdata;
  193         struct isa_attach_args ia;
  194 
  195         ia.ia_iot = sc->sc_iot;
  196         ia.ia_memt = sc->sc_memt;
  197 #if NISADMA > 0
  198         ia.ia_dmat = sc->sc_dmat;
  199 #endif /* NISADMA > 0 */
  200         ia.ia_ic = sc->sc_ic;
  201         ia.ia_iobase = cf->cf_iobase;
  202         ia.ia_iosize = 0x666;
  203         ia.ia_maddr = cf->cf_maddr;
  204         ia.ia_msize = cf->cf_msize;
  205         ia.ia_irq = cf->cf_irq == 2 ? 9 : cf->cf_irq;
  206         ia.ipa_nirq = ia.ia_irq == IRQUNK ? 0 : 1;
  207         ia.ia_drq = cf->cf_drq;
  208         ia.ia_drq2 = cf->cf_drq2;
  209         ia.ipa_ndrq = 2;
  210         ia.ia_delaybah = sc->sc_delaybah;
  211 
  212         if (cf->cf_fstate == FSTATE_STAR) {
  213                 struct isa_attach_args ia2 = ia;
  214 
  215                 if (autoconf_verbose)
  216                         printf(">>> probing for %s*\n",
  217                             cf->cf_driver->cd_name);
  218                 while ((*cf->cf_attach->ca_match)(parent, dev, &ia2) > 0) {
  219 #if !defined(__NO_ISA_INTR_CHECK)
  220                         if ((ia2.ia_irq != IRQUNK) &&
  221                             !isa_intr_check(sc->sc_ic, ia2.ia_irq, IST_EDGE)) {
  222                                 printf("%s%d: irq %d already in use\n",
  223                                     cf->cf_driver->cd_name, cf->cf_unit,
  224                                     ia2.ia_irq);
  225                                 ia2 = ia;
  226                                 break;
  227                         }
  228 #endif
  229 
  230                         if (autoconf_verbose)
  231                                 printf(">>> probe for %s* clone into %s%d\n",
  232                                     cf->cf_driver->cd_name,
  233                                     cf->cf_driver->cd_name, cf->cf_unit);
  234                         if (ia2.ia_iosize == 0x666) {
  235                                 printf("%s: iosize not repaired by driver\n",
  236                                     sc->sc_dev.dv_xname);
  237                                 ia2.ia_iosize = 0;
  238                         }
  239                         config_attach(parent, dev, &ia2, isaprint);
  240                         dev = config_make_softc(parent, cf);
  241 #if NISADMA > 0
  242                         if (ia2.ia_drq != DRQUNK)
  243                                 ISA_DRQ_ALLOC((struct device *)sc, ia2.ia_drq);
  244                         if (ia2.ia_drq2 != DRQUNK)
  245                                 ISA_DRQ_ALLOC((struct device *)sc, ia2.ia_drq2);
  246 #endif /* NISAMDA > 0 */
  247                         ia2 = ia;
  248                 }
  249                 if (autoconf_verbose)
  250                         printf(">>> probing for %s* finished\n",
  251                             cf->cf_driver->cd_name);
  252                 free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
  253                 return;
  254         }
  255 
  256         if (autoconf_verbose)
  257                 printf(">>> probing for %s%d\n", cf->cf_driver->cd_name,
  258                     cf->cf_unit);
  259         if ((*cf->cf_attach->ca_match)(parent, dev, &ia) > 0) {
  260 #if !defined(__NO_ISA_INTR_CHECK)
  261                 if ((ia.ia_irq != IRQUNK) &&
  262                     !isa_intr_check(sc->sc_ic, ia.ia_irq, IST_EDGE)) {
  263                         printf("%s%d: irq %d already in use\n",
  264                             cf->cf_driver->cd_name, cf->cf_unit, ia.ia_irq);
  265                         free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
  266                 } else {
  267 #endif
  268                         if (autoconf_verbose)
  269                                 printf(">>> probing for %s%d succeeded\n",
  270                                     cf->cf_driver->cd_name, cf->cf_unit);
  271                         config_attach(parent, dev, &ia, isaprint);
  272 
  273 #if NISADMA > 0
  274                         if (ia.ia_drq != DRQUNK)
  275                                 ISA_DRQ_ALLOC((struct device *)sc, ia.ia_drq);
  276                         if (ia.ia_drq2 != DRQUNK)
  277                                 ISA_DRQ_ALLOC((struct device *)sc, ia.ia_drq2);
  278 #endif /* NISAMDA > 0 */
  279 #if !defined(__NO_ISA_INTR_CHECK)
  280                 }
  281 #endif
  282         } else {
  283                 if (autoconf_verbose)
  284                         printf(">>> probing for %s%d failed\n",
  285                             cf->cf_driver->cd_name, cf->cf_unit);
  286                 free(dev, M_DEVBUF, cf->cf_attach->ca_devsize);
  287         }
  288 }
  289 
  290 char *
  291 isa_intr_typename(int type)
  292 {
  293 
  294         switch (type) {
  295         case IST_NONE:
  296                 return ("none");
  297         case IST_PULSE:
  298                 return ("pulsed");
  299         case IST_EDGE:
  300                 return ("edge-triggered");
  301         case IST_LEVEL:
  302                 return ("level-triggered");
  303         default:
  304                 panic("isa_intr_typename: invalid type %d", type);
  305         }
  306 }

Cache object: 7a7370ba2797ff82d266343f0e4d1371


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