aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/pci/irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-28 17:59:07 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-28 17:59:07 -0400
commitadb2705a89e8b41abcf29c0ed86f4ce93ab36734 (patch)
tree01d772570d58cce24b61874e711fd9f51e2729e7 /arch/i386/pci/irq.c
parentf340c0d1a3f40fdcba69cd291530a4debc58748f (diff)
parent8644d2a42bdba2d513f71c07eaf1b6f9b718b8eb (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
Diffstat (limited to 'arch/i386/pci/irq.c')
-rw-r--r--arch/i386/pci/irq.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 83458f81e661..78ca1ecbb907 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -58,6 +58,35 @@ struct irq_router_handler {
58int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; 58int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
59 59
60/* 60/*
61 * Check passed address for the PCI IRQ Routing Table signature
62 * and perform checksum verification.
63 */
64
65static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
66{
67 struct irq_routing_table *rt;
68 int i;
69 u8 sum;
70
71 rt = (struct irq_routing_table *) addr;
72 if (rt->signature != PIRQ_SIGNATURE ||
73 rt->version != PIRQ_VERSION ||
74 rt->size % 16 ||
75 rt->size < sizeof(struct irq_routing_table))
76 return NULL;
77 sum = 0;
78 for (i=0; i < rt->size; i++)
79 sum += addr[i];
80 if (!sum) {
81 DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
82 return rt;
83 }
84 return NULL;
85}
86
87
88
89/*
61 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. 90 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
62 */ 91 */
63 92
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void)
65{ 94{
66 u8 *addr; 95 u8 *addr;
67 struct irq_routing_table *rt; 96 struct irq_routing_table *rt;
68 int i;
69 u8 sum;
70 97
98 if (pirq_table_addr) {
99 rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
100 if (rt)
101 return rt;
102 printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
103 }
71 for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { 104 for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
72 rt = (struct irq_routing_table *) addr; 105 rt = pirq_check_routing_table(addr);
73 if (rt->signature != PIRQ_SIGNATURE || 106 if (rt)
74 rt->version != PIRQ_VERSION ||
75 rt->size % 16 ||
76 rt->size < sizeof(struct irq_routing_table))
77 continue;
78 sum = 0;
79 for(i=0; i<rt->size; i++)
80 sum += addr[i];
81 if (!sum) {
82 DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
83 return rt; 107 return rt;
84 }
85 } 108 }
86 return NULL; 109 return NULL;
87} 110}