|
@@ -57,6 +57,35 @@ struct irq_router_handler {
|
|
|
|
|
|
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
|
|
|
|
|
|
+/*
|
|
|
+ * Check passed address for the PCI IRQ Routing Table signature
|
|
|
+ * and perform checksum verification.
|
|
|
+ */
|
|
|
+
|
|
|
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
|
|
|
+{
|
|
|
+ struct irq_routing_table *rt;
|
|
|
+ int i;
|
|
|
+ u8 sum;
|
|
|
+
|
|
|
+ rt = (struct irq_routing_table *) addr;
|
|
|
+ if (rt->signature != PIRQ_SIGNATURE ||
|
|
|
+ rt->version != PIRQ_VERSION ||
|
|
|
+ rt->size % 16 ||
|
|
|
+ rt->size < sizeof(struct irq_routing_table))
|
|
|
+ return NULL;
|
|
|
+ sum = 0;
|
|
|
+ for (i=0; i < rt->size; i++)
|
|
|
+ sum += addr[i];
|
|
|
+ if (!sum) {
|
|
|
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
|
|
|
+ return rt;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/*
|
|
|
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
|
|
|
*/
|
|
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void)
|
|
|
{
|
|
|
u8 *addr;
|
|
|
struct irq_routing_table *rt;
|
|
|
- int i;
|
|
|
- u8 sum;
|
|
|
|
|
|
+ if (pirq_table_addr) {
|
|
|
+ rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
|
|
|
+ if (rt)
|
|
|
+ return rt;
|
|
|
+ printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
|
|
|
+ }
|
|
|
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
|
|
|
- rt = (struct irq_routing_table *) addr;
|
|
|
- if (rt->signature != PIRQ_SIGNATURE ||
|
|
|
- rt->version != PIRQ_VERSION ||
|
|
|
- rt->size % 16 ||
|
|
|
- rt->size < sizeof(struct irq_routing_table))
|
|
|
- continue;
|
|
|
- sum = 0;
|
|
|
- for(i=0; i<rt->size; i++)
|
|
|
- sum += addr[i];
|
|
|
- if (!sum) {
|
|
|
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
|
|
|
+ rt = pirq_check_routing_table(addr);
|
|
|
+ if (rt)
|
|
|
return rt;
|
|
|
- }
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|