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

Annotation of sys/dev/pci/sdhc_pci.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: sdhc_pci.c,v 1.5 2006/07/19 20:58:45 fgsch Exp $      */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2006 Uwe Stuehler <uwe@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/device.h>
        !            21: #include <sys/systm.h>
        !            22: #include <sys/malloc.h>
        !            23:
        !            24: #include <dev/pci/pcivar.h>
        !            25: #include <dev/pci/pcidevs.h>
        !            26: #include <dev/sdmmc/sdhcreg.h>
        !            27: #include <dev/sdmmc/sdhcvar.h>
        !            28: #include <dev/sdmmc/sdmmcvar.h>
        !            29:
        !            30: /*
        !            31:  * 8-bit PCI configuration register that tells us how many slots there
        !            32:  * are and which BAR entry corresponds to the first slot.
        !            33:  */
        !            34: #define SDHC_PCI_CONF_SLOT_INFO                0x40
        !            35: #define SDHC_PCI_NUM_SLOTS(info)       ((((info) >> 4) & 0x7) + 1)
        !            36: #define SDHC_PCI_FIRST_BAR(info)       ((info) & 0x7)
        !            37:
        !            38: /* TI specific register */
        !            39: #define SDHC_PCI_GENERAL_CTL           0x4c
        !            40: #define  MMC_SD_DIS                    0x02
        !            41:
        !            42: struct sdhc_pci_softc {
        !            43:        struct sdhc_softc sc;
        !            44:        void *sc_ih;
        !            45: };
        !            46:
        !            47: int    sdhc_pci_match(struct device *, void *, void *);
        !            48: void   sdhc_pci_attach(struct device *, struct device *, void *);
        !            49: void   sdhc_takecontroller(struct pci_attach_args *);
        !            50:
        !            51: struct cfattach sdhc_pci_ca = {
        !            52:        sizeof(struct sdhc_pci_softc), sdhc_pci_match, sdhc_pci_attach
        !            53: };
        !            54:
        !            55: int
        !            56: sdhc_pci_match(struct device *parent, void *match, void *aux)
        !            57: {
        !            58:        struct pci_attach_args *pa = aux;
        !            59:
        !            60:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SYSTEM &&
        !            61:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SYSTEM_SDHC)
        !            62:                return 1;
        !            63:
        !            64:        return 0;
        !            65: }
        !            66:
        !            67: void
        !            68: sdhc_pci_attach(struct device *parent, struct device *self, void *aux)
        !            69: {
        !            70:        struct sdhc_pci_softc *sc = (struct sdhc_pci_softc *)self;
        !            71:        struct pci_attach_args *pa = aux;
        !            72:        pci_intr_handle_t ih;
        !            73:        char const *intrstr;
        !            74:        int slotinfo;
        !            75:        int nslots;
        !            76:        int usedma;
        !            77:        int reg;
        !            78:        bus_space_tag_t iot;
        !            79:        bus_space_handle_t ioh;
        !            80:        bus_size_t size;
        !            81:
        !            82:        /* Some TI controllers needs special treatment. */
        !            83:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TI &&
        !            84:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TI_PCI7XX1_SD &&
        !            85:             pa->pa_function == 4)
        !            86:                sdhc_takecontroller(pa);
        !            87:
        !            88:        if (pci_intr_map(pa, &ih)) {
        !            89:                printf(": can't map interrupt\n");
        !            90:                return;
        !            91:        }
        !            92:
        !            93:        intrstr = pci_intr_string(pa->pa_pc, ih);
        !            94:        sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_SDMMC,
        !            95:            sdhc_intr, sc, sc->sc.sc_dev.dv_xname);
        !            96:        if (sc->sc_ih == NULL) {
        !            97:                printf(": can't establish interrupt\n");
        !            98:                return;
        !            99:        }
        !           100:        printf(": %s\n", intrstr);
        !           101:
        !           102:        /* Enable use of DMA if supported by the interface. */
        !           103:        usedma = PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA;
        !           104:
        !           105:        /*
        !           106:         * Map and attach all hosts supported by the host controller.
        !           107:         */
        !           108:        slotinfo = pci_conf_read(pa->pa_pc, pa->pa_tag,
        !           109:            SDHC_PCI_CONF_SLOT_INFO);
        !           110:        nslots = SDHC_PCI_NUM_SLOTS(slotinfo);
        !           111:
        !           112:        /* Allocate an array big enough to hold all the possible hosts */
        !           113:        MALLOC(sc->sc.sc_host, struct sdhc_host **,
        !           114:            sizeof(struct sdhc_host *) * nslots, M_DEVBUF, M_WAITOK);
        !           115:
        !           116:        /* XXX: handle 64-bit BARs */
        !           117:        for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) *
        !           118:                 sizeof(u_int32_t);
        !           119:             reg < SDHC_PCI_BAR_END && nslots > 0;
        !           120:             reg += sizeof(u_int32_t), nslots--) {
        !           121:
        !           122:                if (pci_mem_find(pa->pa_pc, pa->pa_tag, reg,
        !           123:                    NULL, NULL, NULL) != 0)
        !           124:                        continue;
        !           125:
        !           126:                if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_MEM, 0,
        !           127:                    &iot, &ioh, NULL, &size, 0)) {
        !           128:                        printf("%s at 0x%x: can't map registers\n",
        !           129:                            sc->sc.sc_dev.dv_xname, reg);
        !           130:                        continue;
        !           131:                }
        !           132:
        !           133:                if (sdhc_host_found(&sc->sc, iot, ioh, size, usedma) != 0)
        !           134:                        /* XXX: sc->sc_host leak */
        !           135:                        printf("%s at 0x%x: can't initialize host\n",
        !           136:                            sc->sc.sc_dev.dv_xname, reg);
        !           137:        }
        !           138:
        !           139:        /*
        !           140:         * Establish power and shutdown hooks.
        !           141:         */
        !           142:        (void)powerhook_establish(sdhc_power, &sc->sc);
        !           143:        (void)shutdownhook_establish(sdhc_shutdown, &sc->sc);
        !           144: }
        !           145:
        !           146: void
        !           147: sdhc_takecontroller(struct pci_attach_args *pa)
        !           148: {
        !           149:        pcitag_t tag;
        !           150:        pcireg_t id, reg;
        !           151:
        !           152:        /* Look at func 3 for the flash device */
        !           153:        tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 3);
        !           154:        id = pci_conf_read(pa->pa_pc, tag, PCI_ID_REG);
        !           155:        if (PCI_PRODUCT(id) != PCI_PRODUCT_TI_PCI7XX1_FLASH)
        !           156:                return;
        !           157:
        !           158:        /*
        !           159:         * Disable MMC/SD on the flash media controller so the
        !           160:         * SD host takes over.
        !           161:         */
        !           162:        reg = pci_conf_read(pa->pa_pc, tag, SDHC_PCI_GENERAL_CTL);
        !           163:        reg |= MMC_SD_DIS;
        !           164:        pci_conf_write(pa->pa_pc, tag, SDHC_PCI_GENERAL_CTL, reg);
        !           165: }

CVSweb