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:
Andrew Gallatin 2001-05-27 22:22:03 +00:00
parent 88bc7f853c
commit d6a516cf80
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=77280
2 changed files with 12 additions and 3 deletions

View file

@ -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

View file

@ -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) {