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