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

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

1.1     ! nbrk        1: /*     $OpenBSD: musycc_obsd.c,v 1.9 2006/01/25 11:02:54 claudio Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2004,2005  Internet Business Solutions AG, Zurich, Switzerland
        !             5:  * Written by: Claudio Jeker <jeker@accoom.net>
        !             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/types.h>
        !            22:
        !            23: #include <sys/device.h>
        !            24: #include <sys/malloc.h>
        !            25: #include <sys/systm.h>
        !            26: #include <sys/socket.h>
        !            27:
        !            28: #include <machine/cpu.h>
        !            29: #include <machine/bus.h>
        !            30: #include <machine/intr.h>
        !            31:
        !            32: #include <net/if.h>
        !            33: #include <net/if_media.h>
        !            34: #include <net/if_sppp.h>
        !            35:
        !            36: #include <dev/pci/musyccvar.h>
        !            37: #include <dev/pci/musyccreg.h>
        !            38:
        !            39: #include <dev/pci/pcivar.h>
        !            40: #include <dev/pci/pcireg.h>
        !            41: #include <dev/pci/pcidevs.h>
        !            42:
        !            43: int    musycc_match(struct device *, void *, void *);
        !            44: void   musycc_softc_attach(struct device *, struct device *, void *);
        !            45: void   musycc_ebus_attach(struct device *, struct musycc_softc *,
        !            46:            struct pci_attach_args *);
        !            47: int    musycc_ebus_print(void *, const char *);
        !            48:
        !            49: struct cfattach musycc_ca = {
        !            50:        sizeof(struct musycc_softc), musycc_match, musycc_softc_attach
        !            51: };
        !            52:
        !            53: struct cfdriver musycc_cd = {
        !            54:        NULL, "musycc", DV_DULL
        !            55: };
        !            56:
        !            57: SLIST_HEAD(, musycc_softc) msc_list = SLIST_HEAD_INITIALIZER(msc_list);
        !            58:
        !            59: const struct pci_matchid musycc_pci_devices[] = {
        !            60:        { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_MUSYCC8478 },
        !            61:        { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_MUSYCC8474 },
        !            62:        { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_MUSYCC8472 },
        !            63:        { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_MUSYCC8471 }
        !            64: };
        !            65:
        !            66: int
        !            67: musycc_match(struct device *parent, void *match, void *aux)
        !            68: {
        !            69:        return (pci_matchbyid((struct pci_attach_args *)aux, musycc_pci_devices,
        !            70:            sizeof(musycc_pci_devices)/sizeof(musycc_pci_devices[0])));
        !            71: }
        !            72:
        !            73: void
        !            74: musycc_softc_attach(struct device *parent, struct device *self, void *aux)
        !            75: {
        !            76:        struct musycc_softc     *sc = (struct musycc_softc *)self;
        !            77:        struct pci_attach_args  *pa = aux;
        !            78:        pci_chipset_tag_t        pc = pa->pa_pc;
        !            79:        pci_intr_handle_t        ih;
        !            80:        const char              *intrstr = NULL;
        !            81:
        !            82:        if (pci_mapreg_map(pa, MUSYCC_PCI_BAR,
        !            83:            PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
        !            84:            &sc->mc_st, &sc->mc_sh, NULL, &sc->mc_iosize, 0)) {
        !            85:                printf(": can't map mem space\n");
        !            86:                return;
        !            87:        }
        !            88:        sc->mc_dmat = pa->pa_dmat;
        !            89:
        !            90:        switch (PCI_PRODUCT(pa->pa_id)) {
        !            91:        case PCI_PRODUCT_CONEXANT_MUSYCC8478:
        !            92:                sc->mc_ngroups = 8;
        !            93:                sc->mc_nports = 8;
        !            94:                break;
        !            95:        case PCI_PRODUCT_CONEXANT_MUSYCC8474:
        !            96:                sc->mc_ngroups = 4;
        !            97:                sc->mc_nports = 4;
        !            98:                break;
        !            99:        case PCI_PRODUCT_CONEXANT_MUSYCC8472:
        !           100:                sc->mc_ngroups = 2;
        !           101:                sc->mc_nports = 2;
        !           102:                break;
        !           103:        case PCI_PRODUCT_CONEXANT_MUSYCC8471:
        !           104:                sc->mc_ngroups = 1;
        !           105:                sc->mc_nports = 1;
        !           106:                break;
        !           107:        }
        !           108:
        !           109:        if (pa->pa_function == 1)
        !           110:                return (musycc_ebus_attach(parent, sc, pa));
        !           111:
        !           112:        sc->bus = parent->dv_unit;
        !           113:        sc->device = pa->pa_device;
        !           114:        SLIST_INSERT_HEAD(&msc_list, sc, list);
        !           115:
        !           116:        /*
        !           117:         * Allocate our interrupt.
        !           118:         */
        !           119:        if (pci_intr_map(pa, &ih)) {
        !           120:                printf(": couldn't map interrupt\n");
        !           121:                bus_space_unmap(sc->mc_st, sc->mc_sh, sc->mc_iosize);
        !           122:                return;
        !           123:        }
        !           124:
        !           125:        intrstr = pci_intr_string(pc, ih);
        !           126:        sc->mc_ih = pci_intr_establish(pc, ih, IPL_NET, musycc_intr, sc,
        !           127:            self->dv_xname);
        !           128:        if (sc->mc_ih == NULL) {
        !           129:                printf(": couldn't establish interrupt");
        !           130:                if (intrstr != NULL)
        !           131:                        printf(" at %s", intrstr);
        !           132:                printf("\n");
        !           133:                bus_space_unmap(sc->mc_st, sc->mc_sh, sc->mc_iosize);
        !           134:                return;
        !           135:        }
        !           136:
        !           137:        printf(": %s\n", intrstr);
        !           138:
        !           139:        /* soft reset device */
        !           140:        bus_space_write_4(sc->mc_st, sc->mc_sh, MUSYCC_SERREQ(0),
        !           141:            MUSYCC_SREQ_SET(1));
        !           142:        bus_space_barrier(sc->mc_st, sc->mc_sh, MUSYCC_SERREQ(0),
        !           143:            sizeof(u_int32_t), BUS_SPACE_BARRIER_WRITE);
        !           144:
        !           145:        /*
        !           146:         * preload global configuration: set EBUS to sane defaults
        !           147:         * so that the ROM access will work.
        !           148:         * intel mode, elapse = 3, blapse = 3, alapse = 3, disable INTB
        !           149:         */
        !           150:        sc->mc_global_conf = MUSYCC_CONF_MPUSEL | MUSYCC_CONF_ECKEN |
        !           151:            MUSYCC_CONF_ELAPSE_SET(3) | MUSYCC_CONF_ALAPSE_SET(3) |
        !           152:            MUSYCC_CONF_BLAPSE_SET(3) | MUSYCC_CONF_INTB;
        !           153:
        !           154:        /* Dual Address Cycle Base Pointer */
        !           155:        bus_space_write_4(sc->mc_st, sc->mc_sh, MUSYCC_DACB_PTR, 0);
        !           156:        /* Global Configuration Descriptor */
        !           157:        bus_space_write_4(sc->mc_st, sc->mc_sh, MUSYCC_GLOBALCONF,
        !           158:            sc->mc_global_conf);
        !           159:
        !           160:        return;
        !           161: }
        !           162:
        !           163: void
        !           164: musycc_ebus_attach(struct device *parent, struct musycc_softc *esc,
        !           165:     struct pci_attach_args *pa)
        !           166: {
        !           167:        struct ebus_dev                  rom;
        !           168:        struct musycc_attach_args        ma;
        !           169:        struct musycc_softc             *sc;
        !           170:        pci_chipset_tag_t                pc = pa->pa_pc;
        !           171: #if 0
        !           172:        pci_intr_handle_t                ih;
        !           173:        const char                      *intrstr = NULL;
        !           174: #endif
        !           175:        struct musycc_rom                baseconf;
        !           176:        struct musycc_rom_framer         framerconf;
        !           177:        bus_size_t                       offset;
        !           178:        int                              i;
        !           179:
        !           180:        /* find HDLC controller softc ... */
        !           181:        SLIST_FOREACH(sc, &msc_list, list)
        !           182:                if (sc->bus == parent->dv_unit && sc->device == pa->pa_device)
        !           183:                        break;
        !           184:        if (sc == NULL) {
        !           185:                printf(": corresponding hdlc controller not found\n");
        !           186:                return;
        !           187:        }
        !           188:
        !           189:        /* ... and link them together */
        !           190:        esc->mc_other = sc;
        !           191:        sc->mc_other = esc;
        !           192:
        !           193: #if 0
        !           194:        /*
        !           195:         * Allocate our interrupt.
        !           196:         */
        !           197:        if (pci_intr_map(pa, &ih)) {
        !           198:                printf(": couldn't map interrupt\n");
        !           199:                goto failed;
        !           200:        }
        !           201:
        !           202:        intrstr = pci_intr_string(pc, ih);
        !           203:        esc->mc_ih = pci_intr_establish(pc, ih, IPL_NET, ebus_intr, esc,
        !           204:            esc->mc_dev.dv_xname);
        !           205:        if (esc->mc_ih == NULL) {
        !           206:                printf(": couldn't establish interrupt");
        !           207:                if (intrstr != NULL)
        !           208:                        printf(" at %s", intrstr);
        !           209:                printf("\n");
        !           210:                goto failed;
        !           211:        }
        !           212:
        !           213:        /* XXX this printf should actually move to the end of the function */
        !           214:        printf(": %s\n", intrstr);
        !           215: #endif
        !           216:
        !           217:        if (ebus_attach_device(&rom, sc, 0, 0x400) != 0) {
        !           218:                printf(": failed to map rom @ %05p\n", 0);
        !           219:                goto failed;
        !           220:        }
        !           221:
        !           222:        offset = 0;
        !           223:        ebus_read_buf(&rom, offset, &baseconf, sizeof(baseconf));
        !           224:        offset += sizeof(baseconf);
        !           225:
        !           226:        if (baseconf.magic != MUSYCC_ROM_MAGIC) {
        !           227:                printf(": bad rom\n");
        !           228:                goto failed;
        !           229:        }
        !           230:
        !           231:        /* Do generic parts of attach. */
        !           232:        if (musycc_attach_common(sc, baseconf.portmap, baseconf.portmode))
        !           233:                goto failed;
        !           234:
        !           235:        /* map and reset leds */
        !           236:        /* (15 * 0x4000) << 2 */
        !           237:        esc->mc_ledbase = ntohl(baseconf.ledbase) << 2;
        !           238:        esc->mc_ledmask = baseconf.ledmask;
        !           239:        esc->mc_ledstate = 0;
        !           240:        bus_space_write_1(esc->mc_st, esc->mc_sh, esc->mc_ledbase, 0);
        !           241:
        !           242:        printf("\n");
        !           243:
        !           244:        for (i = 0; i < baseconf.numframer; i++) {
        !           245:                if (offset >= 0x400) {
        !           246:                        printf("%s: bad rom\n", sc->mc_dev.dv_xname);
        !           247:                        goto failed;
        !           248:                }
        !           249:                ebus_read_buf(&rom, offset, &framerconf, sizeof(framerconf));
        !           250:                offset += sizeof(framerconf);
        !           251:
        !           252:                strlcpy(ma.ma_product, baseconf.product, sizeof(ma.ma_product));
        !           253:                ma.ma_base = ntohl(framerconf.base);
        !           254:                ma.ma_size = ntohl(framerconf.size);
        !           255:                ma.ma_type = ntohl(framerconf.type);
        !           256:                ma.ma_gnum = framerconf.gnum;
        !           257:                ma.ma_port = framerconf.port;
        !           258:                ma.ma_flags = framerconf.flags;
        !           259:                ma.ma_slot = framerconf.slot;
        !           260:
        !           261:                (void)config_found(&sc->mc_dev, &ma, musycc_ebus_print);
        !           262:        }
        !           263:
        !           264:        return;
        !           265: failed:
        !           266:        /* Failed! */
        !           267:        pci_intr_disestablish(pc, sc->mc_ih);
        !           268:        if (esc->mc_ih != NULL)
        !           269:                pci_intr_disestablish(pc, esc->mc_ih);
        !           270:        bus_space_unmap(sc->mc_st, sc->mc_sh, sc->mc_iosize);
        !           271:        bus_space_unmap(esc->mc_st, esc->mc_sh, esc->mc_iosize);
        !           272:        return;
        !           273: }
        !           274:
        !           275: int
        !           276: musycc_ebus_print(void *aux, const char *pnp)
        !           277: {
        !           278:        struct musycc_attach_args *ma = aux;
        !           279:
        !           280:        if (pnp)
        !           281:                printf("framer at %s port %d slot %c",
        !           282:                    pnp, ma->ma_port, ma->ma_slot);
        !           283:        else
        !           284:                printf(" port %d slot %c", ma->ma_port, ma->ma_slot);
        !           285:        return (UNCONF);
        !           286: }
        !           287:

CVSweb