finally fix intr routing on alphas such as the as500 after months of
breakage: - call PCIB_ROUTE_INTERRUPT() regardless of how valid the intline looks. Some alphas leave garbage in the intline and leave the intr mapping to OS platform support routines that map slots/buses to intlines - Down in the alpha pci code, first try platform.pci_intr_route() and if it doesn't exist or returns garbage, just read the intline out of config space. tested on AS500 (garbage in intline) and UP1000 (PC-like, intline is valid) Note that a nice little hack like the APIC_IO section of pci_cfgregread() is not workable. This is because the calling interface for alpha_pci_route_interrupt() requires us to figure out the bus/slot/etc from a device_t. At pci_read_device() time, we don't have a device_t for the bus/slot/func in question.
This commit is contained in:
parent
88bc7f853c
commit
d6a516cf80
@ -40,6 +40,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcivar.h>
|
||||
#include <machine/chipset.h>
|
||||
#include <machine/cpuconf.h>
|
||||
@ -80,6 +81,8 @@ SYSCTL_LONG(_hw_chipset, OID_AUTO, hae_mask, CTLFLAG_RD, &chipset_hae_mask, 0,
|
||||
int
|
||||
alpha_pci_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
{
|
||||
int intline = 255;
|
||||
|
||||
/*
|
||||
* Validate requested pin number.
|
||||
*/
|
||||
@ -87,8 +90,10 @@ alpha_pci_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
return(255);
|
||||
|
||||
if (platform.pci_intr_route)
|
||||
return(platform.pci_intr_route(bus, dev, pin));
|
||||
return(255);
|
||||
intline = platform.pci_intr_route(bus, dev, pin);
|
||||
if (intline == 255)
|
||||
intline = pci_read_config(dev, PCIR_INTLINE, 1);
|
||||
return intline;
|
||||
}
|
||||
|
||||
#ifdef DEV_ISA
|
||||
|
@ -1207,7 +1207,11 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
* If device doesn't have an interrupt routed, and is deserving of
|
||||
* an interrupt, try to assign it one.
|
||||
*/
|
||||
if ((type == SYS_RES_IRQ) && (cfg->intline == 255) && (cfg->intpin != 0)) {
|
||||
if ((type == SYS_RES_IRQ)
|
||||
#ifndef __alpha__
|
||||
&& (cfg->intline == 255) && (cfg->intpin != 0)
|
||||
#endif
|
||||
) {
|
||||
cfg->intline = PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
|
||||
cfg->intpin);
|
||||
if (cfg->intline != 255) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user