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/aic/aic_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 /*-
    2  * Copyright (c) 1999 Luoqi Chen.
    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 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/callout.h>
   32 #include <sys/kernel.h>
   33 #include <sys/lock.h>
   34 #include <sys/module.h>
   35 #include <sys/mutex.h>
   36 #include <sys/bus.h>
   37 
   38 #include <machine/bus.h>
   39 #include <machine/resource.h>
   40 #include <sys/rman.h>
   41  
   42 #include <isa/isavar.h>
   43 #include <dev/aic/aic6360reg.h>
   44 #include <dev/aic/aicvar.h>
   45   
   46 struct aic_isa_softc {
   47         struct  aic_softc sc_aic;
   48         struct  resource *sc_port;
   49         struct  resource *sc_irq;
   50         struct  resource *sc_drq;
   51         void    *sc_ih;
   52 };
   53 
   54 static int aic_isa_alloc_resources(device_t);
   55 static void aic_isa_release_resources(device_t);
   56 static int aic_isa_probe(device_t);
   57 static int aic_isa_attach(device_t);
   58 
   59 static u_int aic_isa_ports[] = { 0x340, 0x140 };
   60 #define AIC_ISA_NUMPORTS (sizeof(aic_isa_ports) / sizeof(aic_isa_ports[0]))
   61 #define AIC_ISA_PORTSIZE 0x20
   62 
   63 static struct isa_pnp_id aic_ids[] = {
   64         { 0x15309004, "Adaptec AHA-1530P" },
   65         { 0x15209004, "Adaptec AHA-1520P" },
   66         { 0 }
   67 };
   68 
   69 static int
   70 aic_isa_alloc_resources(device_t dev)
   71 {
   72         struct aic_isa_softc *sc = device_get_softc(dev);
   73         int rid;
   74 
   75         sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
   76 
   77         rid = 0;
   78         sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
   79                                         0ul, ~0ul, AIC_ISA_PORTSIZE, RF_ACTIVE);
   80         if (!sc->sc_port) {
   81                 device_printf(dev, "I/O port allocation failed\n");
   82                 return (ENOMEM);
   83         }
   84 
   85         if (isa_get_irq(dev) != -1) {
   86                 rid = 0;
   87                 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
   88                                                     RF_ACTIVE);
   89                 if (!sc->sc_irq) {
   90                         device_printf(dev, "IRQ allocation failed\n");
   91                         aic_isa_release_resources(dev);
   92                         return (ENOMEM);
   93                 }
   94         }
   95 
   96         if (isa_get_drq(dev) != -1) {
   97                 rid = 0;
   98                 sc->sc_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid,
   99                                                     RF_ACTIVE);
  100                 if (!sc->sc_drq) {
  101                         device_printf(dev, "DRQ allocation failed\n");
  102                         aic_isa_release_resources(dev);
  103                         return (ENOMEM);
  104                 }
  105         }
  106 
  107         sc->sc_aic.dev = dev;
  108         sc->sc_aic.res = sc->sc_port;
  109         mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
  110         return (0);
  111 }
  112 
  113 static void
  114 aic_isa_release_resources(device_t dev)
  115 {
  116         struct aic_isa_softc *sc = device_get_softc(dev);
  117 
  118         if (sc->sc_port)
  119                 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port);
  120         if (sc->sc_irq)
  121                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
  122         if (sc->sc_drq)
  123                 bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq);
  124         sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
  125         mtx_destroy(&sc->sc_aic.lock);
  126 }
  127 
  128 static int
  129 aic_isa_probe(device_t dev)
  130 {
  131         struct aic_isa_softc *sc = device_get_softc(dev);
  132         struct aic_softc *aic = &sc->sc_aic;
  133         int numports, i;
  134         u_int port, *ports;
  135         u_int8_t porta;
  136 
  137         if (ISA_PNP_PROBE(device_get_parent(dev), dev, aic_ids) == ENXIO)
  138                 return (ENXIO);
  139 
  140         port = isa_get_port(dev);
  141         if (port != -1) {
  142                 ports = &port;
  143                 numports = 1;
  144         } else {
  145                 ports = aic_isa_ports;
  146                 numports = AIC_ISA_NUMPORTS;
  147         }
  148 
  149         for (i = 0; i < numports; i++) {
  150                 if (bus_set_resource(dev, SYS_RES_IOPORT, 0, ports[i],
  151                                      AIC_ISA_PORTSIZE))
  152                         continue;
  153                 if (aic_isa_alloc_resources(dev))
  154                         continue;
  155                 if (aic_probe(aic) == 0)
  156                         break;
  157                 aic_isa_release_resources(dev);
  158         }
  159 
  160         if (i == numports)
  161                 return (ENXIO);
  162 
  163         porta = aic_inb(aic, PORTA);
  164         aic_isa_release_resources(dev);
  165         if (isa_get_irq(dev) == -1)
  166                 bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
  167         if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
  168                 bus_set_resource(dev, SYS_RES_DRQ, 0, PORTA_DRQ(porta), 1);
  169         device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
  170         return (0);
  171 }
  172 
  173 static int
  174 aic_isa_attach(device_t dev)
  175 {
  176         struct aic_isa_softc *sc = device_get_softc(dev);
  177         struct aic_softc *aic = &sc->sc_aic;
  178         int error;
  179 
  180         error = aic_isa_alloc_resources(dev);
  181         if (error) {
  182                 device_printf(dev, "resource allocation failed\n");
  183                 return (error);
  184         }
  185 
  186         error = aic_attach(aic);
  187         if (error) {
  188                 device_printf(dev, "attach failed\n");
  189                 aic_isa_release_resources(dev);
  190                 return (error);
  191         }
  192 
  193         error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
  194             INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
  195         if (error) {
  196                 device_printf(dev, "failed to register interrupt handler\n");
  197                 aic_isa_release_resources(dev);
  198                 return (error);
  199         }
  200         return (0);
  201 }
  202 
  203 static int
  204 aic_isa_detach(device_t dev)
  205 {
  206         struct aic_isa_softc *sc = device_get_softc(dev);
  207         struct aic_softc *aic = &sc->sc_aic;
  208         int error;
  209 
  210         error = aic_detach(aic);
  211         if (error) {
  212                 device_printf(dev, "detach failed\n");
  213                 return (error);
  214         }
  215 
  216         error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
  217         if (error) {
  218                 device_printf(dev, "failed to unregister interrupt handler\n");
  219         }
  220 
  221         aic_isa_release_resources(dev);
  222         return (0);
  223 }
  224 
  225 static device_method_t aic_isa_methods[] = {
  226         /* Device interface */
  227         DEVMETHOD(device_probe,         aic_isa_probe),
  228         DEVMETHOD(device_attach,        aic_isa_attach),
  229         DEVMETHOD(device_detach,        aic_isa_detach),
  230         { 0, 0 }
  231 };
  232 
  233 static driver_t aic_isa_driver = {
  234         "aic",
  235         aic_isa_methods, sizeof(struct aic_isa_softc),
  236 };
  237 
  238 extern devclass_t aic_devclass;
  239 
  240 MODULE_DEPEND(aic, cam, 1,1,1);
  241 DRIVER_MODULE(aic, isa, aic_isa_driver, aic_devclass, 0, 0);

Cache object: e32c8d237cd28a9ce4cadc19398dbf2f


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