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_pccard.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  * $FreeBSD: releng/5.1/sys/dev/aic/aic_pccard.c 113315 2003-04-10 04:36:02Z imp $
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/kernel.h>
   31 #include <sys/module.h>
   32 #include <sys/bus.h>
   33 
   34 #include <machine/bus_pio.h>
   35 #include <machine/bus.h>
   36 #include <machine/resource.h>
   37 #include <sys/rman.h>
   38  
   39 #include <dev/aic/aicvar.h>
   40 #include <dev/pccard/pccardvar.h>
   41 #include <dev/pccard/pccarddevs.h>
   42 
   43 #include "card_if.h"
   44 
   45 struct aic_pccard_softc {
   46         struct  aic_softc sc_aic;
   47         struct  resource *sc_port;
   48         struct  resource *sc_irq;
   49         void    *sc_ih;
   50 };
   51 
   52 static int aic_pccard_alloc_resources(device_t);
   53 static void aic_pccard_release_resources(device_t);
   54 static int aic_pccard_match(device_t);
   55 static int aic_pccard_probe(device_t);
   56 static int aic_pccard_attach(device_t);
   57 
   58 const struct pccard_product aic_pccard_products[] = {
   59         PCMCIA_CARD(ADAPTEC, APA1460, 0),
   60         PCMCIA_CARD(ADAPTEC, APA1460A, 0),
   61         PCMCIA_CARD(NEWMEDIA, BUSTOASTER, 0),
   62         PCMCIA_CARD(NEWMEDIA, BUSTOASTER2, 0),
   63         PCMCIA_CARD(NEWMEDIA, BUSTOASTER3, 0),
   64         { NULL }
   65 };
   66 
   67 #define AIC_PCCARD_PORTSIZE 0x20
   68 
   69 static int
   70 aic_pccard_alloc_resources(device_t dev)
   71 {
   72         struct aic_pccard_softc *sc = device_get_softc(dev);
   73         int rid;
   74 
   75         sc->sc_port = sc->sc_irq = 0;
   76 
   77         rid = 0;
   78         sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
   79             0ul, ~0ul, AIC_PCCARD_PORTSIZE, RF_ACTIVE);
   80         if (!sc->sc_port)
   81                 return (ENOMEM);
   82 
   83         rid = 0;
   84         sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
   85             0ul, ~0ul, 1, RF_ACTIVE);
   86         if (!sc->sc_irq) {
   87                 aic_pccard_release_resources(dev);
   88                 return (ENOMEM);
   89         }
   90 
   91         sc->sc_aic.unit = device_get_unit(dev);
   92         sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
   93         sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
   94         return (0);
   95 }
   96 
   97 static void
   98 aic_pccard_release_resources(device_t dev)
   99 {
  100         struct aic_pccard_softc *sc = device_get_softc(dev);
  101 
  102         if (sc->sc_port)
  103                 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port);
  104         if (sc->sc_irq)
  105                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
  106         sc->sc_port = sc->sc_irq = 0;
  107 }
  108 
  109 static int
  110 aic_pccard_match(device_t dev)
  111 {
  112         const struct pccard_product *pp;
  113 
  114         if ((pp = pccard_product_lookup(dev, aic_pccard_products,
  115             sizeof(aic_pccard_products[0]), NULL)) != NULL) {
  116                 if (pp->pp_name != NULL)
  117                         device_set_desc(dev, pp->pp_name);
  118                 return 0;
  119         }
  120         return EIO;
  121 }
  122 
  123 static int
  124 aic_pccard_probe(device_t dev)
  125 {
  126         struct aic_pccard_softc *sc = device_get_softc(dev);
  127         struct aic_softc *aic = &sc->sc_aic;
  128 
  129         if (aic_pccard_alloc_resources(dev))
  130                 return (ENXIO);
  131         if (aic_probe(aic)) {
  132                 aic_pccard_release_resources(dev);
  133                 return (ENXIO);
  134         }
  135         aic_pccard_release_resources(dev);
  136 
  137         device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
  138         return (0);
  139 }
  140 
  141 static int
  142 aic_pccard_attach(device_t dev)
  143 {
  144         struct aic_pccard_softc *sc = device_get_softc(dev);
  145         struct aic_softc *aic = &sc->sc_aic;
  146         int error;
  147 
  148         error = aic_pccard_alloc_resources(dev);
  149         if (error) {
  150                 device_printf(dev, "resource allocation failed\n");
  151                 return (error);
  152         }
  153 
  154         error = aic_attach(aic);
  155         if (error) {
  156                 device_printf(dev, "attach failed\n");
  157                 aic_pccard_release_resources(dev);
  158                 return (error);
  159         }
  160 
  161         error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
  162                                 aic_intr, aic, &sc->sc_ih);
  163         if (error) {
  164                 device_printf(dev, "failed to register interrupt handler\n");
  165                 aic_pccard_release_resources(dev);
  166                 return (error);
  167         }
  168         return (0);
  169 }
  170 
  171 static int
  172 aic_pccard_detach(device_t dev)
  173 {
  174         struct aic_pccard_softc *sc = device_get_softc(dev);
  175         struct aic_softc *aic = &sc->sc_aic;
  176         int error;
  177 
  178         error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
  179         if (error) {
  180                 device_printf(dev, "failed to unregister interrupt handler\n");
  181         }
  182 
  183         error = aic_detach(aic);
  184         if (error) {
  185                 device_printf(dev, "detach failed\n");
  186                 return (error);
  187         }
  188 
  189         aic_pccard_release_resources(dev);
  190         return (0);
  191 }
  192 
  193 static device_method_t aic_pccard_methods[] = {
  194         /* Device interface */
  195         DEVMETHOD(device_probe,         pccard_compat_probe),
  196         DEVMETHOD(device_attach,        pccard_compat_attach),
  197         DEVMETHOD(device_detach,        aic_pccard_detach),
  198 
  199         /* Card interface */
  200         DEVMETHOD(card_compat_match,    aic_pccard_match),
  201         DEVMETHOD(card_compat_probe,    aic_pccard_probe),
  202         DEVMETHOD(card_compat_attach,   aic_pccard_attach),
  203 
  204         { 0, 0 }
  205 };
  206 
  207 static driver_t aic_pccard_driver = {
  208         "aic",
  209         aic_pccard_methods, sizeof(struct aic_pccard_softc),
  210 };
  211 
  212 extern devclass_t aic_devclass;
  213 
  214 MODULE_DEPEND(aic, cam, 1,1,1);
  215 DRIVER_MODULE(aic, pccard, aic_pccard_driver, aic_devclass, 0, 0);

Cache object: 2622a50c4e9cc5a1749bfe42fc397770


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