From a8c18609ec602c5ecae7aa3fb9b1693540d4d98f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 20 Jan 2002 03:28:29 +0000 Subject: [PATCH] The Libretto L series has no $PIR table, but does have a _PIR table. This typo keeps us from properly routing an interrupt for CardBus bridges on this machine. So, now we look for $PIR and then _PIR to cope. With these changes, the Libretto L1 now works properly. Evidentally, the idea comes from patch that the Japanese version of RedHat (or against a Japanese version of Red Hat), but my Japanese isn't good enough to to know for sure. Reported by: Hiroyuki Aizu-san # This may be an MFC candidate, but I'm not yet sure. --- sys/amd64/pci/pci_cfgreg.c | 35 ++++++++++++++++++++++------------- sys/i386/pci/pci_cfgreg.c | 35 ++++++++++++++++++++++------------- sys/i386/pci/pci_pir.c | 35 ++++++++++++++++++++++------------- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c index da1d2081d9b2..8ac47ee40340 100644 --- a/sys/amd64/pci/pci_cfgreg.c +++ b/sys/amd64/pci/pci_cfgreg.c @@ -135,21 +135,31 @@ pci_cfgregopen(void) /* * Look for the interrupt routing table. + * + * We use PCI BIOS's PIR table if it's available $PIR is the + * standard way to do this. Sadly, some machines are not + * standards conforming and have _PIR instead. We shrug and cope + * by looking for both. */ - /* We use PCI BIOS's PIR table if it's available */ - if (pcibios_get_version() >= 0x0210 && pt == NULL && - (sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0)) != 0) { - pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); - for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < (pt->pt_header.ph_length); i++) { - ck += cv[i]; - } - if (ck == 0) { - pci_route_table = pt; - pci_route_count = (pt->pt_header.ph_length - sizeof(struct PIR_header)) / sizeof(struct PIR_entry); - printf("Using $PIR table, %d entries at %p\n", pci_route_count, pci_route_table); + if (pcibios_get_version() >= 0x0210 && pt == NULL) { + sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0); + if (sigaddr == 0) + sigaddr = bios_sigsearch(0, "_PIR", 4, 16, 0); + if (sigaddr != 0) { + pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); + for (cv = (u_int8_t *)pt, ck = 0, i = 0; + i < (pt->pt_header.ph_length); i++) { + ck += cv[i]; + } + if (ck == 0) { + pci_route_table = pt; + pci_route_count = (pt->pt_header.ph_length - + sizeof(struct PIR_header)) / sizeof(struct PIR_entry); + printf("Using $PIR table, %d entries at %p\n", + pci_route_count, pci_route_table); + } } } - opened = 1; return(1); } @@ -263,7 +273,6 @@ pci_cfgintr(int bus, int device, int pin) irq = pci_cfgintr_unique(pe, pin); if (irq == 255) irq = pci_cfgintr_virgin(pe, pin); - if (irq == 255) break; diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index da1d2081d9b2..8ac47ee40340 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -135,21 +135,31 @@ pci_cfgregopen(void) /* * Look for the interrupt routing table. + * + * We use PCI BIOS's PIR table if it's available $PIR is the + * standard way to do this. Sadly, some machines are not + * standards conforming and have _PIR instead. We shrug and cope + * by looking for both. */ - /* We use PCI BIOS's PIR table if it's available */ - if (pcibios_get_version() >= 0x0210 && pt == NULL && - (sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0)) != 0) { - pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); - for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < (pt->pt_header.ph_length); i++) { - ck += cv[i]; - } - if (ck == 0) { - pci_route_table = pt; - pci_route_count = (pt->pt_header.ph_length - sizeof(struct PIR_header)) / sizeof(struct PIR_entry); - printf("Using $PIR table, %d entries at %p\n", pci_route_count, pci_route_table); + if (pcibios_get_version() >= 0x0210 && pt == NULL) { + sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0); + if (sigaddr == 0) + sigaddr = bios_sigsearch(0, "_PIR", 4, 16, 0); + if (sigaddr != 0) { + pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); + for (cv = (u_int8_t *)pt, ck = 0, i = 0; + i < (pt->pt_header.ph_length); i++) { + ck += cv[i]; + } + if (ck == 0) { + pci_route_table = pt; + pci_route_count = (pt->pt_header.ph_length - + sizeof(struct PIR_header)) / sizeof(struct PIR_entry); + printf("Using $PIR table, %d entries at %p\n", + pci_route_count, pci_route_table); + } } } - opened = 1; return(1); } @@ -263,7 +273,6 @@ pci_cfgintr(int bus, int device, int pin) irq = pci_cfgintr_unique(pe, pin); if (irq == 255) irq = pci_cfgintr_virgin(pe, pin); - if (irq == 255) break; diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c index da1d2081d9b2..8ac47ee40340 100644 --- a/sys/i386/pci/pci_pir.c +++ b/sys/i386/pci/pci_pir.c @@ -135,21 +135,31 @@ pci_cfgregopen(void) /* * Look for the interrupt routing table. + * + * We use PCI BIOS's PIR table if it's available $PIR is the + * standard way to do this. Sadly, some machines are not + * standards conforming and have _PIR instead. We shrug and cope + * by looking for both. */ - /* We use PCI BIOS's PIR table if it's available */ - if (pcibios_get_version() >= 0x0210 && pt == NULL && - (sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0)) != 0) { - pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); - for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < (pt->pt_header.ph_length); i++) { - ck += cv[i]; - } - if (ck == 0) { - pci_route_table = pt; - pci_route_count = (pt->pt_header.ph_length - sizeof(struct PIR_header)) / sizeof(struct PIR_entry); - printf("Using $PIR table, %d entries at %p\n", pci_route_count, pci_route_table); + if (pcibios_get_version() >= 0x0210 && pt == NULL) { + sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0); + if (sigaddr == 0) + sigaddr = bios_sigsearch(0, "_PIR", 4, 16, 0); + if (sigaddr != 0) { + pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); + for (cv = (u_int8_t *)pt, ck = 0, i = 0; + i < (pt->pt_header.ph_length); i++) { + ck += cv[i]; + } + if (ck == 0) { + pci_route_table = pt; + pci_route_count = (pt->pt_header.ph_length - + sizeof(struct PIR_header)) / sizeof(struct PIR_entry); + printf("Using $PIR table, %d entries at %p\n", + pci_route_count, pci_route_table); + } } } - opened = 1; return(1); } @@ -263,7 +273,6 @@ pci_cfgintr(int bus, int device, int pin) irq = pci_cfgintr_unique(pe, pin); if (irq == 255) irq = pci_cfgintr_virgin(pe, pin); - if (irq == 255) break;