[BACK]Return to sili_pci.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/sili_pci.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb