summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-12-19 18:55:48 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-12-19 18:55:48 +0000
commit3face08f863c93c62aecca9fcdd1cbea8eb50f7d (patch)
tree4a281381e55ad5ede979a99537b934e0f6e84fc3 /sys/dev/acpi
parent34335e08034260b96098433b3174dee4f61280f0 (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.c54
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;