[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

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