diff options
Diffstat (limited to 'arch/i386/pci/irq.c')
| -rw-r--r-- | arch/i386/pci/irq.c | 51 | 
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 { | |||
| 58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | 58 | int (*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 | |||
| 65 | static 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 | } | 
