diff options
author | tegge <tegge@FreeBSD.org> | 1998-04-01 21:07:37 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 1998-04-01 21:07:37 +0000 |
commit | 028480bfb1299a0a34ad19f20e2cc3f24b402235 (patch) | |
tree | 77436497a16e77fa303820d1d60caeb109f2acad /sys/pci/pci.c | |
parent | 574d6dcedfc1e96deb88ef6e7f5540eab053fe2d (diff) | |
download | FreeBSD-src-028480bfb1299a0a34ad19f20e2cc3f24b402235.zip FreeBSD-src-028480bfb1299a0a34ad19f20e2cc3f24b402235.tar.gz |
Add two workarounds for broken MP tables:
- Attempt to handle PCI devices where the interrupt is
an ISA/EISA interrupt according to the mp table.
- Attempt to handle multiple IO APIC pins connected to
the same PCI or ISA/EISA interrupt source. Print a
warning if this happens, since performance is suboptimal.
This workaround is only used for PCI devices.
With these two workarounds, the -SMP kernel is capable of running on
my Asus P/I-P65UP5 motherboard when version 1.4 of the MP table is disabled.
Diffstat (limited to 'sys/pci/pci.c')
-rw-r--r-- | sys/pci/pci.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/pci/pci.c b/sys/pci/pci.c index 6ecd4b7..530408b 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci.c,v 1.80 1997/11/07 08:53:28 phk Exp $ + * $Id: pci.c,v 1.81 1998/01/24 02:54:47 eivind Exp $ * */ @@ -340,9 +340,25 @@ pci_readcfg(pcicfgregs *probe) int airq; airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin); - if ((airq >= 0) && (airq != cfg->intline)) { - undirect_pci_irq(cfg->intline); - cfg->intline = airq; + if (airq >= 0) { + /* PCI specific entry found in MP table */ + if (airq != cfg->intline) { + undirect_pci_irq(cfg->intline); + cfg->intline = airq; + } + } else { + /* + * PCI interrupts might be redirected to the + * ISA bus according to some MP tables. Use the + * same methods as used by the ISA devices + * devices to find the proper IOAPIC int pin. + */ + airq = isa_apic_pin(cfg->intline); + if ((airq >= 0) && (airq != cfg->intline)) { + /* XXX: undirect_pci_irq() ? */ + undirect_isa_irq(cfg->intline); + cfg->intline = airq; + } } } #endif /* APIC_IO */ |