diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-12-19 18:55:48 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-12-19 18:55:48 +0000 |
commit | 3face08f863c93c62aecca9fcdd1cbea8eb50f7d (patch) | |
tree | 4a281381e55ad5ede979a99537b934e0f6e84fc3 /sys/dev/acpi | |
parent | 34335e08034260b96098433b3174dee4f61280f0 (diff) |
On many systems the information returned by _PRT is an absolute lie, especially
in the PIC case. So if _CRS returns a plausible value, go with that, and only
chose an interrupt from the list returned by _PRT if the value returned by
_CRS makes no sense.
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r-- | sys/dev/acpi/acpiprt.c | 54 |
1 files changed, 6 insertions, 48 deletions
diff --git a/sys/dev/acpi/acpiprt.c b/sys/dev/acpi/acpiprt.c index fe3ae073d2c..4a5adf41808 100644 --- a/sys/dev/acpi/acpiprt.c +++ b/sys/dev/acpi/acpiprt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpiprt.c,v 1.29 2008/12/17 19:35:39 kettenis Exp $ */ +/* $OpenBSD: acpiprt.c,v 1.30 2008/12/19 18:55:47 kettenis Exp $ */ /* * Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org> * @@ -57,7 +57,6 @@ int acpiprt_match(struct device *, void *, void *); void acpiprt_attach(struct device *, struct device *, void *); int acpiprt_getirq(union acpi_resource *crs, void *arg); int acpiprt_getminbus(union acpi_resource *, void *); -int acpiprt_checkprs(union acpi_resource *, void *); int acpiprt_chooseirq(union acpi_resource *, void *); struct acpiprt_softc { @@ -133,36 +132,6 @@ acpiprt_attach(struct device *parent, struct device *self, void *aux) } int -acpiprt_checkprs(union acpi_resource *crs, void *arg) -{ - int *irq = (int *)arg; - int typ, i; - - typ = AML_CRSTYPE(crs); - switch (typ) { - case SR_IRQ: - for (i = 0; i < sizeof(crs->sr_irq.irq_mask) * 8; i++) { - if (crs->sr_irq.irq_mask & (1L << i)) { - if (i == *irq) - return (0); - } - } - break; - case LR_EXTIRQ: - for (i = 0; i < crs->lr_extirq.irq_count; i++) { - if (crs->lr_extirq.irq[i] == *irq) - return (0); - } - break; - default: - printf("unknown interrupt: %x\n", typ); - } - - *irq = -1; - return (0); -} - -int acpiprt_getirq(union acpi_resource *crs, void *arg) { int *irq = (int *)arg; @@ -247,7 +216,7 @@ 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, newirq, sta; + int pin, irq, sta; #if NIOAPIC > 0 struct mp_intr_map *map; struct ioapic_softc *apic; @@ -315,28 +284,17 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) acpiprt_getirq, &irq); aml_freevalue(&res); - /* Check Possible IRQs */ - if (!aml_evalname(sc->sc_acpi, node, "_PRS", 0, NULL, &res)){ + /* Pick a new IRQ if necessary. */ + if ((irq == 0 || irq == 2 || irq == 13) && + !aml_evalname(sc->sc_acpi, node, "_PRS", 0, NULL, &res)){ if (res.type == AML_OBJTYPE_BUFFER && res.length >= 6) { aml_parse_resource(res.length, res.v_buffer, - acpiprt_checkprs, &irq); - aml_parse_resource(res.length, res.v_buffer, - acpiprt_chooseirq, &newirq); + acpiprt_chooseirq, &irq); } aml_freevalue(&res); } - if (irq == -1) { - /* - * Current IRQ is "impossible". Use the first - * available Possible IRQ instead. We - * postpone re-routeing the interrupt until we - * establish a handler for it. - */ - irq = newirq; - } - if ((p = malloc(sizeof(*p), M_ACPI, M_NOWAIT)) == NULL) return; p->bus = sc->sc_bus; |