root/dev/pci/sili_pci.c

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

DEFINITIONS

This source file includes following definitions.
  1. sili_lookup
  2. sili_pci_match
  3. sili_pci_attach
  4. sili_pci_detach

    1 /*      $OpenBSD: sili_pci.c,v 1.7 2007/04/07 05:59:49 dlg Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/kernel.h>
   22 #include <sys/malloc.h>
   23 #include <sys/device.h>
   24 #include <sys/timeout.h>
   25 
   26 #include <machine/bus.h>
   27 
   28 #include <dev/pci/pcireg.h>
   29 #include <dev/pci/pcivar.h>
   30 #include <dev/pci/pcidevs.h>
   31 
   32 #include <dev/ata/atascsi.h>
   33 
   34 #include <dev/ic/silireg.h>
   35 #include <dev/ic/silivar.h>
   36 
   37 int     sili_pci_match(struct device *, void *, void *);
   38 void    sili_pci_attach(struct device *, struct device *, void *);
   39 int     sili_pci_detach(struct device *, int);
   40 
   41 struct sili_pci_softc {
   42         struct sili_softc       psc_sili;
   43 
   44         pci_chipset_tag_t       psc_pc;
   45         pcitag_t                psc_tag;
   46 
   47         void                    *psc_ih;
   48 };
   49 
   50 struct cfattach sili_pci_ca = {
   51         sizeof(struct sili_pci_softc), sili_pci_match, sili_pci_attach,
   52         sili_pci_detach
   53 };
   54 
   55 struct sili_device {
   56         pci_vendor_id_t         sd_vendor;
   57         pci_product_id_t        sd_product;
   58         u_int                   sd_nports;
   59 };
   60 
   61 const struct sili_device *sili_lookup(struct pci_attach_args *);
   62 
   63 static const struct sili_device sili_devices[] = {
   64         { PCI_VENDOR_CMDTECH,   PCI_PRODUCT_CMDTECH_3124, 4 },
   65         { PCI_VENDOR_CMDTECH,   PCI_PRODUCT_CMDTECH_3131, 1 },
   66         { PCI_VENDOR_CMDTECH,   PCI_PRODUCT_CMDTECH_3132, 2 },
   67         { PCI_VENDOR_CMDTECH,   PCI_PRODUCT_CMDTECH_3531, 1 },
   68         { PCI_VENDOR_CMDTECH,   PCI_PRODUCT_CMDTECH_AAR_1220SA, 2 },
   69         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_3124, 4 }
   70 };
   71 
   72 const struct sili_device *
   73 sili_lookup(struct pci_attach_args *pa)
   74 {
   75         int                             i;
   76         const struct sili_device        *sd;
   77 
   78         for (i = 0; i < sizeofa(sili_devices); i++) {
   79                 sd = &sili_devices[i];
   80                 if (sd->sd_vendor == PCI_VENDOR(pa->pa_id) &&
   81                     sd->sd_product == PCI_PRODUCT(pa->pa_id))
   82                         return (sd);
   83         }
   84 
   85         return (NULL);
   86 }
   87 
   88 int
   89 sili_pci_match(struct device *parent, void *match, void *aux)
   90 {
   91         return (sili_lookup((struct pci_attach_args *)aux) != NULL);
   92 }
   93 
   94 void
   95 sili_pci_attach(struct device *parent, struct device *self, void *aux)
   96 {
   97         struct sili_pci_softc           *psc = (void *)self;
   98         struct sili_softc               *sc = &psc->psc_sili;
   99         struct pci_attach_args          *pa = aux;
  100         const struct sili_device        *sd;
  101         pcireg_t                        memtype;
  102         pci_intr_handle_t               ih;
  103         const char                      *intrstr;
  104 
  105         sd = sili_lookup(pa);
  106 
  107         psc->psc_pc = pa->pa_pc;
  108         psc->psc_tag = pa->pa_tag;
  109         psc->psc_ih = NULL;
  110         sc->sc_dmat = pa->pa_dmat;
  111         sc->sc_ios_global = 0;
  112         sc->sc_ios_port = 0;
  113         sc->sc_nports = sd->sd_nports;
  114 
  115         memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag,
  116             SILI_PCI_BAR_GLOBAL);
  117         if (pci_mapreg_map(pa, SILI_PCI_BAR_GLOBAL, memtype, 0,
  118             &sc->sc_iot_global, &sc->sc_ioh_global,
  119             NULL, &sc->sc_ios_global, 0) != 0) {
  120                 printf(": unable to map global registers\n");
  121                 return;
  122         }
  123 
  124         memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag,
  125             SILI_PCI_BAR_PORT);
  126         if (pci_mapreg_map(pa, SILI_PCI_BAR_PORT, memtype, 0,
  127             &sc->sc_iot_port, &sc->sc_ioh_port,
  128             NULL, &sc->sc_ios_port, 0) != 0) {
  129                 printf(": unable to map port registers\n");
  130                 goto unmap_global;
  131         }
  132 
  133         /* hook up the interrupt */
  134         if (pci_intr_map(pa, &ih)) {
  135                 printf(": unable to map interrupt\n");
  136                 goto unmap_port;
  137         }
  138         intrstr = pci_intr_string(psc->psc_pc, ih);
  139         psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
  140             sili_intr, sc, sc->sc_dev.dv_xname);
  141         if (psc->psc_ih == NULL) {
  142                 printf(": unable to map interrupt%s%s\n",
  143                     intrstr == NULL ? "" : " at ",
  144                     intrstr == NULL ? "" : intrstr);
  145                 goto unmap_port;
  146         }
  147         printf(": %s", intrstr);
  148 
  149         if (sili_attach(sc) != 0) {
  150                 /* error printed by sili_attach */
  151                 goto deintr;
  152         }
  153 
  154         return;
  155 
  156 deintr:
  157         pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
  158         psc->psc_ih = NULL;
  159 unmap_port:
  160         bus_space_unmap(sc->sc_iot_port, sc->sc_ioh_port, sc->sc_ios_port);
  161         sc->sc_ios_port = 0;
  162 unmap_global:
  163         bus_space_unmap(sc->sc_iot_global, sc->sc_ioh_global,
  164             sc->sc_ios_global);
  165         sc->sc_ios_global = 0;
  166 }
  167 
  168 int
  169 sili_pci_detach(struct device *self, int flags)
  170 {
  171         struct sili_pci_softc           *psc = (struct sili_pci_softc *)self;
  172         struct sili_softc               *sc = &psc->psc_sili;
  173         int                             rv;
  174 
  175         rv = sili_detach(sc, flags);
  176         if (rv != 0)
  177                 return (rv);
  178 
  179         if (psc->psc_ih != NULL) {
  180                 pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
  181                 psc->psc_ih = NULL;
  182         }
  183         if (sc->sc_ios_port != 0) {
  184                 bus_space_unmap(sc->sc_iot_port, sc->sc_ioh_port,
  185                     sc->sc_ios_port);
  186                 sc->sc_ios_port = 0;
  187         }
  188         if (sc->sc_ios_global != 0) {
  189                 bus_space_unmap(sc->sc_iot_global, sc->sc_ioh_global,
  190                     sc->sc_ios_global);
  191                 sc->sc_ios_global = 0;
  192         }
  193 
  194         return (0);
  195 }

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