summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-06-23 18:11:33 +0000
committerjhb <jhb@FreeBSD.org>2004-06-23 18:11:33 +0000
commitb597657d93c100a9e52c4ec3f2cb9eb99ec92fe1 (patch)
tree2ac8c3a7808455765a02fbf39b3c9ddd205c4eb7 /sys/i386
parent8371bbfa53f254227d77ff45cbbbff7fc59eed1b (diff)
downloadFreeBSD-src-b597657d93c100a9e52c4ec3f2cb9eb99ec92fe1.zip
FreeBSD-src-b597657d93c100a9e52c4ec3f2cb9eb99ec92fe1.tar.gz
Finally implement bus_config_intr() support for I/O APIC interrupt sources.
This should fix problems with older SMP systems that only have ISA/EISA IRQs when routing virgin PCI interrupts as well as on other boxes whose MADT does not have any interrupt override entries for ISA IRQs that are used to route PCI interrupts even in APIC mode.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/io_apic.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/sys/i386/i386/io_apic.c b/sys/i386/i386/io_apic.c
index c00bebf..99cf908 100644
--- a/sys/i386/i386/io_apic.c
+++ b/sys/i386/i386/io_apic.c
@@ -403,32 +403,39 @@ ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
struct ioapic *io = (struct ioapic *)isrc->is_pic;
+ int changed;
KASSERT(!(trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM),
("%s: Conforming trigger or polarity\n", __func__));
/*
- * For now we ignore any requests but do output any changes that
- * would be made to the console it bootverbose is enabled. The only
- * known causes of these messages so far is a bug in acpi(4) that
- * causes the ISA IRQs used for PCI interrupts in PIC mode to be
- * set to level/low when they aren't being used. There are possibly
- * legitimate requests, so at some point when the acpi(4) driver is
- * fixed this code can be changed to actually change the intpin as
- * requested.
+ * EISA interrupts always use active high polarity, so don't allow
+ * them to be set to active low.
+ *
+ * XXX: Should we write to the ELCR if the trigger mode changes for
+ * an EISA IRQ?
*/
- if (!bootverbose)
- return (0);
- if (intpin->io_edgetrigger != (trig == INTR_TRIGGER_EDGE))
- printf(
- "ioapic%u: Request to change trigger for pin %u to %s ignored\n",
- io->io_id, intpin->io_intpin, trig == INTR_TRIGGER_EDGE ?
- "edge" : "level");
- if (intpin->io_activehi != (pol == INTR_POLARITY_HIGH))
- printf(
- "ioapic%u: Request to change polarity for pin %u to %s ignored\n",
- io->io_id, intpin->io_intpin, pol == INTR_POLARITY_HIGH ?
- "high" : "low");
+ if (intpin->io_bus == APIC_BUS_EISA)
+ pol = INTR_POLARITY_HIGH;
+ changed = 0;
+ if (intpin->io_edgetrigger != (trig == INTR_TRIGGER_EDGE)) {
+ if (bootverbose)
+ printf("ioapic%u: Changing trigger for pin %u to %s\n",
+ io->io_id, intpin->io_intpin,
+ trig == INTR_TRIGGER_EDGE ? "edge" : "level");
+ intpin->io_edgetrigger = (trig == INTR_TRIGGER_EDGE);
+ changed++;
+ }
+ if (intpin->io_activehi != (pol == INTR_POLARITY_HIGH)) {
+ if (bootverbose)
+ printf("ioapic%u: Changing polarity for pin %u to %s\n",
+ io->io_id, intpin->io_intpin,
+ pol == INTR_POLARITY_HIGH ? "high" : "low");
+ intpin->io_activehi = (pol == INTR_POLARITY_HIGH);
+ changed++;
+ }
+ if (changed)
+ ioapic_program_intpin(intpin);
return (0);
}
OpenPOWER on IntegriCloud