void sdhc_acpi_attach(struct device *parent, struct device *self, void *aux) { struct acpi_attach_args *aaa = aux; struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)self; struct aml_value res; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_node = aaa->aaa_node; printf(": %s", sc->sc_node->name); if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { printf(", can't find registers\n"); return; } aml_parse_resource(&res, sdhc_acpi_parse_resources, sc); printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size); if (sc->sc_addr == 0 || sc->sc_size == 0) { printf("\n"); return; } printf(" irq %d", sc->sc_irq); sc->sc_memt = aaa->aaa_memt; if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0, &sc->sc_memh)) { printf(", can't map registers\n"); return; } sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO, sdhc_intr, sc, sc->sc.sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(", can't establish interrupt\n"); return; } printf("\n"); sc->sc.sc_host = &sc->sc_host; sdhc_host_found(&sc->sc, sc->sc_memt, sc->sc_memh, sc->sc_size, 0, 0); }
void acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) { struct aml_node *node; struct aml_value res, *pp; u_int64_t addr; int pin, irq, sta; #if NIOAPIC > 0 struct mp_intr_map *map; struct ioapic_softc *apic; #endif pci_chipset_tag_t pc = NULL; pcitag_t tag; pcireg_t reg; int bus, dev, func, nfuncs; if (v->type != AML_OBJTYPE_PACKAGE || v->length != 4) { printf("invalid mapping object\n"); return; } addr = aml_val2int(v->v_package[0]); pin = aml_val2int(v->v_package[1]); if (pin > 3) { return; } pp = v->v_package[2]; if (pp->type == AML_OBJTYPE_NAMEREF) { node = aml_searchname(sc->sc_devnode, pp->v_nameref); if (node == NULL) { printf("Invalid device!\n"); return; } pp = node->value; } if (pp->type == AML_OBJTYPE_OBJREF) { pp = pp->v_objref.ref; } if (pp->type == AML_OBJTYPE_DEVICE) { node = pp->node; if (aml_evalname(sc->sc_acpi, node, "_STA", 0, NULL, &res)) printf("no _STA method\n"); sta = aml_val2int(&res) & STA_ENABLED; aml_freevalue(&res); if (sta == 0) return; if (aml_evalname(sc->sc_acpi, node, "_CRS", 0, NULL, &res)) printf("no _CRS method\n"); if (res.type != AML_OBJTYPE_BUFFER || res.length < 6) { printf("invalid _CRS object\n"); aml_freevalue(&res); return; } aml_parse_resource(res.length, res.v_buffer, acpiprt_getirq, &irq); aml_freevalue(&res); } else { irq = aml_val2int(v->v_package[3]); } #ifdef ACPI_DEBUG printf("%s: %s addr 0x%llx pin %d irq %d\n", DEVNAME(sc), aml_nodename(pp->node), addr, pin, irq); #endif #if NIOAPIC > 0 if (nioapics > 0) { apic = ioapic_find_bybase(irq); if (apic == NULL) { printf("%s: no apic found for irq %d\n", DEVNAME(sc), irq); return; } map = malloc(sizeof (struct mp_intr_map), M_DEVBUF, M_NOWAIT); if (map == NULL) return; memset(map, 0, sizeof *map); map->ioapic = apic; map->ioapic_pin = irq - apic->sc_apic_vecbase; map->bus_pin = ((addr >> 14) & 0x7c) | (pin & 0x3); map->redir = IOAPIC_REDLO_ACTLO | IOAPIC_REDLO_LEVEL; map->redir |= (IOAPIC_REDLO_DEL_LOPRI << IOAPIC_REDLO_DEL_SHIFT); map->ioapic_ih = APIC_INT_VIA_APIC | ((apic->sc_apicid << APIC_INT_APIC_SHIFT) | (map->ioapic_pin << APIC_INT_PIN_SHIFT)); apic->sc_pins[map->ioapic_pin].ip_map = map; map->next = mp_busses[sc->sc_bus].mb_intrs; mp_busses[sc->sc_bus].mb_intrs = map; return; }