Annotation of sys/dev/cardbus/puc_cardbus.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: puc_cardbus.c,v 1.2 2006/10/12 16:35:52 grange Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2006 Michael Shalayeff
! 5: * All rights reserved.
! 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 MIND, USE, DATA OR PROFITS, WHETHER IN
! 16: * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 17: * OF 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/device.h>
! 23: #include <sys/tty.h>
! 24:
! 25: #include <machine/bus.h>
! 26: #include <dev/ic/comvar.h>
! 27:
! 28: #include <dev/pci/pcireg.h>
! 29: #include <dev/pci/pcivar.h>
! 30: #include <dev/pci/pcidevs.h>
! 31: #include <dev/cardbus/cardbusvar.h>
! 32:
! 33: #include <dev/pci/pucvar.h>
! 34:
! 35: struct puc_cardbus_softc {
! 36: struct puc_softc sc_psc;
! 37:
! 38: struct cardbus_devfunc *ct;
! 39: int intrline;
! 40: };
! 41:
! 42: int puc_cardbus_match(struct device *, void *, void *);
! 43: void puc_cardbus_attach(struct device *, struct device *, void *);
! 44: int puc_cardbus_detach(struct device *, int);
! 45:
! 46: const char *puc_cardbus_intr_string(struct puc_attach_args *);
! 47: void *puc_cardbus_intr_establish(struct puc_attach_args *, int,
! 48: int (*)(void *), void *, char *);
! 49:
! 50: struct cfattach puc_cardbus_ca = {
! 51: sizeof(struct puc_cardbus_softc), puc_cardbus_match,
! 52: puc_cardbus_attach, puc_cardbus_detach
! 53: };
! 54:
! 55: int
! 56: puc_cardbus_match(struct device *parent, void *match, void *aux)
! 57: {
! 58: struct cardbus_attach_args *ca = aux;
! 59: struct cardbus_devfunc *ct = ca->ca_ct;
! 60: cardbus_chipset_tag_t cc = ct->ct_cc;
! 61: cardbus_function_tag_t cf = ct->ct_cf;
! 62: cardbusreg_t bhlc, reg;
! 63:
! 64: bhlc = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG);
! 65: if (PCI_HDRTYPE_TYPE(bhlc) != 0)
! 66: return(0);
! 67:
! 68: /* this one is some sort of a bridge and not a puc */
! 69: if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_OXFORD2 &&
! 70: PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_OXFORD2_EXSYS_EX41098)
! 71: return (0);
! 72:
! 73: reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_SUBSYS_ID_REG);
! 74: if (puc_find_description(PCI_VENDOR(ca->ca_id),
! 75: PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg)))
! 76: return (10);
! 77:
! 78: return (0);
! 79: }
! 80:
! 81: void
! 82: puc_cardbus_attach(struct device *parent, struct device *self, void *aux)
! 83: {
! 84: struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
! 85: struct puc_softc *sc = &csc->sc_psc;
! 86: struct cardbus_attach_args *ca = aux;
! 87: struct cardbus_devfunc *ct = ca->ca_ct;
! 88: cardbus_chipset_tag_t cc = ct->ct_cc;
! 89: cardbus_function_tag_t cf = ct->ct_cf;
! 90: struct puc_attach_args paa;
! 91: cardbusreg_t reg;
! 92: int i;
! 93:
! 94: Cardbus_function_enable(ct);
! 95:
! 96: csc->ct = ct;
! 97:
! 98: reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_SUBSYS_ID_REG);
! 99: sc->sc_desc = puc_find_description(PCI_VENDOR(ca->ca_id),
! 100: PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg));
! 101:
! 102: puc_print_ports(sc->sc_desc);
! 103:
! 104: /* the fifth one is some memory we dunno */
! 105: for (i = 0; i < PUC_NBARS; i++) {
! 106: cardbusreg_t type;
! 107: int bar;
! 108:
! 109: sc->sc_bar_mappings[i].mapped = 0;
! 110: bar = PCI_MAPREG_START + 4 * i;
! 111: if (!cardbus_mapreg_probe(cc, cf, ca->ca_tag, bar, &type))
! 112: continue;
! 113:
! 114: if (!(sc->sc_bar_mappings[i].mapped = !Cardbus_mapreg_map(ct,
! 115: bar, type, 0,
! 116: &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
! 117: &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)))
! 118: printf("%s: couldn't map BAR at offset 0x%lx\n",
! 119: sc->sc_dev.dv_xname, (long)bar);
! 120: sc->sc_bar_mappings[i].type = type;
! 121: }
! 122:
! 123: csc->intrline = ca->ca_intrline;
! 124:
! 125: if (cardbus_get_capability(cc, cf, ca->ca_tag, PCI_CAP_PWRMGMT, ®,
! 126: 0)) {
! 127: reg = cardbus_conf_read(cc, cf, ca->ca_tag, reg + 4) & 3;
! 128: if (reg) {
! 129: printf("%s: awakening from state D%d\n",
! 130: sc->sc_dev.dv_xname, reg);
! 131: cardbus_conf_write(cc, cf, ca->ca_tag, reg + 4, 0);
! 132: }
! 133: }
! 134:
! 135: (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
! 136: (*cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
! 137: (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
! 138:
! 139: paa.puc = sc;
! 140: paa.hwtype = COM_UART_OX16C950; /* XXX */
! 141: paa.intr_string = &puc_cardbus_intr_string;
! 142: paa.intr_establish = &puc_cardbus_intr_establish;
! 143: puc_common_attach(sc, &paa);
! 144: }
! 145:
! 146: const char *
! 147: puc_cardbus_intr_string(struct puc_attach_args *paa)
! 148: {
! 149: struct puc_cardbus_softc *sc = paa->puc;
! 150: static char str[16];
! 151:
! 152: snprintf(str, sizeof str, "irq %d", sc->intrline);
! 153: return (str);
! 154: }
! 155:
! 156: void *
! 157: puc_cardbus_intr_establish(struct puc_attach_args *paa, int type,
! 158: int (*func)(void *), void *arg, char *name)
! 159: {
! 160: struct puc_cardbus_softc *sc = paa->puc;
! 161: struct cardbus_devfunc *ct = sc->ct;
! 162:
! 163: return (cardbus_intr_establish(ct->ct_cc, ct->ct_cf, sc->intrline,
! 164: type, func, arg, name));
! 165: }
! 166:
! 167: int
! 168: puc_cardbus_detach(struct device *self, int flags)
! 169: {
! 170: struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
! 171: struct puc_softc *sc = &csc->sc_psc;
! 172: struct cardbus_devfunc *ct = csc->ct;
! 173: int i, rv;
! 174:
! 175: for (i = PUC_MAX_PORTS; i--; )
! 176: if (sc->sc_ports[i].dev)
! 177: if ((rv = config_detach(sc->sc_ports[i].dev, flags)))
! 178: return (rv);
! 179:
! 180: for (i = PUC_NBARS; i--; )
! 181: if (sc->sc_bar_mappings[i].mapped)
! 182: Cardbus_mapreg_unmap(ct, sc->sc_bar_mappings[i].type,
! 183: sc->sc_bar_mappings[i].t, sc->sc_bar_mappings[i].h,
! 184: sc->sc_bar_mappings[i].s);
! 185:
! 186: return (0);
! 187: }
CVSweb