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

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

1.1       nbrk        1: /*     $OpenBSD: mpi_pci.c,v 1.14 2007/03/17 10:25:39 dlg Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
                      5:  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include <sys/param.h>
                     21: #include <sys/systm.h>
                     22: #include <sys/kernel.h>
                     23: #include <sys/malloc.h>
                     24: #include <sys/device.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 <scsi/scsi_all.h>
                     33: #include <scsi/scsiconf.h>
                     34:
                     35: #include <dev/ic/mpireg.h>
                     36: #include <dev/ic/mpivar.h>
                     37:
                     38: int    mpi_pci_match(struct device *, void *, void *);
                     39: void   mpi_pci_attach(struct device *, struct device *, void *);
                     40: int    mpi_pci_detach(struct device *, int);
                     41:
                     42: struct mpi_pci_softc {
                     43:        struct mpi_softc        psc_mpi;
                     44:
                     45:        pci_chipset_tag_t       psc_pc;
                     46:        pcitag_t                psc_tag;
                     47:
                     48:        void                    *psc_ih;
                     49: };
                     50:
                     51: struct cfattach mpi_pci_ca = {
                     52:        sizeof(struct mpi_pci_softc), mpi_pci_match, mpi_pci_attach,
                     53:        mpi_pci_detach
                     54: };
                     55:
                     56: #define PREAD(s, r)    pci_conf_read((s)->psc_pc, (s)->psc_tag, (r))
                     57: #define PWRITE(s, r, v)        pci_conf_write((s)->psc_pc, (s)->psc_tag, (r), (v))
                     58:
                     59: static const struct pci_matchid mpi_devices[] = {
                     60:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_1030 },
                     61:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC909 },
                     62:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC909A },
                     63:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC919 },
                     64:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC919_1 },
                     65:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC919X },
                     66:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC929 },
                     67:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC929_1 },
                     68:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC929X },
                     69:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC939X },
                     70:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC949E },
                     71:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC949X },
                     72:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1064 },
                     73:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1064A },
                     74:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1064E },
                     75:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1066 },
                     76:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1066E },
                     77:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1068 },
                     78:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1078 },
                     79:        { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_SAS1068E }
                     80: };
                     81:
                     82: int
                     83: mpi_pci_match(struct device *parent, void *match, void *aux)
                     84: {
                     85:        return (pci_matchbyid((struct pci_attach_args *)aux, mpi_devices,
                     86:            sizeof(mpi_devices) / sizeof(mpi_devices[0])));
                     87: }
                     88:
                     89: void
                     90: mpi_pci_attach(struct device *parent, struct device *self, void *aux)
                     91: {
                     92:        struct mpi_pci_softc            *psc = (void *)self;
                     93:        struct mpi_softc                *sc = &psc->psc_mpi;
                     94:        struct pci_attach_args          *pa = aux;
                     95:        pcireg_t                        memtype;
                     96:        int                             r;
                     97:        pci_intr_handle_t               ih;
                     98:        const char                      *intrstr;
                     99:
                    100:        psc->psc_pc = pa->pa_pc;
                    101:        psc->psc_tag = pa->pa_tag;
                    102:        psc->psc_ih = NULL;
                    103:        sc->sc_dmat = pa->pa_dmat;
                    104:        sc->sc_ios = 0;
                    105:
                    106:        /* find the appropriate memory base */
                    107:        for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
                    108:                memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, r);
                    109:                if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM)
                    110:                        break;
                    111:        }
                    112:        if (r >= PCI_MAPREG_END) {
                    113:                printf(": unable to locate system interface registers\n");
                    114:                return;
                    115:        }
                    116:
                    117:        if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh,
                    118:            NULL, &sc->sc_ios, 0) != 0) {
                    119:                printf(": unable to map system interface registers\n");
                    120:                return;
                    121:        }
                    122:
                    123:        /* disable the expansion rom */
                    124:        PWRITE(psc, PCI_ROM_REG, PREAD(psc, PCI_ROM_REG) & ~PCI_ROM_ENABLE);
                    125:
                    126:        /* hook up the interrupt */
                    127:        if (pci_intr_map(pa, &ih)) {
                    128:                printf(": unable to map interrupt\n");
                    129:                goto unmap;
                    130:        }
                    131:        intrstr = pci_intr_string(psc->psc_pc, ih);
                    132:        psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
                    133:            mpi_intr, sc, sc->sc_dev.dv_xname);
                    134:        if (psc->psc_ih == NULL) {
                    135:                printf(": unable to map interrupt%s%s\n",
                    136:                    intrstr == NULL ? "" : " at ",
                    137:                    intrstr == NULL ? "" : intrstr);
                    138:                goto unmap;
                    139:        }
                    140:        printf(": %s", intrstr);
                    141:
                    142:        if (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG) ==
                    143:            PCI_ID_CODE(PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_1030))
                    144:                sc->sc_flags |= MPI_F_SPI;
                    145:
                    146:        if (mpi_attach(sc) != 0) {
                    147:                /* error printed by mpi_attach */
                    148:                goto deintr;
                    149:        }
                    150:
                    151:        return;
                    152:
                    153: deintr:
                    154:        pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
                    155:        psc->psc_ih = NULL;
                    156: unmap:
                    157:        bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
                    158:        sc->sc_ios = 0;
                    159: }
                    160:
                    161: int
                    162: mpi_pci_detach(struct device *self, int flags)
                    163: {
                    164:        struct mpi_pci_softc            *psc = (struct mpi_pci_softc *)self;
                    165:        struct mpi_softc                *sc = &psc->psc_mpi;
                    166:
                    167:        mpi_detach(sc);
                    168:
                    169:        if (psc->psc_ih != NULL) {
                    170:                pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
                    171:                psc->psc_ih = NULL;
                    172:        }
                    173:        if (sc->sc_ios != 0) {
                    174:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
                    175:                sc->sc_ios = 0;
                    176:        }
                    177:
                    178:        return (0);
                    179: }

CVSweb