Reverse the quirk table entry for swizzling on a missing interrupt map;
this is now done on all machines except for some known problematic ones. Add an additional guard to make sure that the interrupt numbers are in the correct range before swizzling. This should catch any remaining models for which the swizzle is inappropriate. Correct the swizzle calculation to account for the fact that the parent interrupt numbers to be swizzled are 1-based. Approved by: re
This commit is contained in:
parent
d4523ab223
commit
ed2f312db5
@ -55,12 +55,13 @@ u_int8_t pci_bus_cnt;
|
||||
phandle_t *pci_bus_map;
|
||||
int pci_bus_map_sz;
|
||||
|
||||
#define OPQ_NEED_SWIZZLE 1
|
||||
#define OPQ_NO_SWIZZLE 1
|
||||
static struct ofw_pci_quirk {
|
||||
char *opq_model;
|
||||
int opq_quirks;
|
||||
} ofw_pci_quirks[] = {
|
||||
{ "SUNW,UltraSPARC-IIi-cEngine", OPQ_NEED_SWIZZLE }
|
||||
{ "SUNW,Ultra-4", OPQ_NO_SWIZZLE },
|
||||
{ "SUNW,Ultra-1-Engine", OPQ_NO_SWIZZLE },
|
||||
};
|
||||
#define OPQ_NENT (sizeof(ofw_pci_quirks) / sizeof(ofw_pci_quirks[0]))
|
||||
|
||||
@ -77,18 +78,20 @@ ofw_pci_orb_callback(phandle_t node, u_int8_t *pintptr, int pintsz,
|
||||
u_int32_t pintr, intr;
|
||||
char type[32];
|
||||
|
||||
if ((pci_quirks & OPQ_NEED_SWIZZLE) != 0 &&
|
||||
pintsz == sizeof(u_int32_t) && pregsz >= sizeof(preg) &&
|
||||
if (pintsz != sizeof(u_int32_t))
|
||||
return (-1);
|
||||
bcopy(pintptr, &pintr, sizeof(pintr));
|
||||
if ((pci_quirks & OPQ_NO_SWIZZLE) == 0 && pregsz >= sizeof(preg) &&
|
||||
OF_getprop(node, "device_type", type, sizeof(type)) != -1 &&
|
||||
strcmp(type, OFW_PCI_PCIBUS) == 0) {
|
||||
strcmp(type, OFW_PCI_PCIBUS) == 0 && pintr >= 1 && pintr <= 4) {
|
||||
/*
|
||||
* Handle a quirk found on some Netra t1 models: there exist
|
||||
* PCI bridges without interrupt maps, where we apparently must
|
||||
* do the PCI swizzle and continue to map on at the parent.
|
||||
*/
|
||||
bcopy(pintptr, &pintr, sizeof(pintr));
|
||||
bcopy(pregptr, &preg, sizeof(preg));
|
||||
intr = (OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi) + pintr) % 4;
|
||||
intr = (OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi) + pintr + 3) %
|
||||
4 + 1;
|
||||
*rintr = malloc(sizeof(intr), M_OFWPROP, M_WAITOK);
|
||||
bcopy(&intr, *rintr, sizeof(intr));
|
||||
*terminate = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user