Loading Documentation/kernel-parameters.txt +4 −0 Original line number Diff line number Diff line Loading @@ -1030,6 +1030,10 @@ running once the system is up. irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned automatically to PCI devices. You can make the kernel exclude IRQs of your ISA cards this way. pirqaddr=0xAAAAA [IA-32] Specify the physical address of the PIRQ table (normally generated by the BIOS) if it is outside the F0000h-100000h range. lastbus=N [IA-32] Scan all buses till bus #N. Can be useful if the kernel is unable to find your secondary buses and you want to tell it explicitly which ones they are. Loading arch/i386/kernel/acpi/boot.c +49 −8 Original line number Diff line number Diff line Loading @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ struct acpi_table_mcfg_config *pci_mmcfg_config; int pci_mmcfg_config_num; int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; unsigned long i; int config_size; if (!phys_addr || !size) return -EINVAL; Loading @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } if (mcfg->base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); /* how many config structures do we have */ pci_mmcfg_config_num = 0; i = size - sizeof(struct acpi_table_mcfg); while (i >= sizeof(struct acpi_table_mcfg_config)) { ++pci_mmcfg_config_num; i -= sizeof(struct acpi_table_mcfg_config); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } pci_mmcfg_base_addr = mcfg->base_address; config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); if (!pci_mmcfg_config) { printk(KERN_WARNING PREFIX "No memory for MCFG config tables\n"); return -ENOMEM; } memcpy(pci_mmcfg_config, &mcfg->config, config_size); for (i = 0; i < pci_mmcfg_config_num; ++i) { if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); return -ENODEV; } } return 0; } #else #define acpi_parse_mcfg NULL #endif /* !CONFIG_PCI_MMCONFIG */ #endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init Loading Loading @@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { /* TBD */ return -EINVAL; } EXPORT_SYMBOL(acpi_register_ioapic); int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) { /* TBD */ return -EINVAL; } EXPORT_SYMBOL(acpi_unregister_ioapic); static unsigned long __init acpi_scan_rsdp ( unsigned long start, Loading Loading @@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } Loading arch/i386/pci/common.c +6 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; struct pci_bus *pci_root_bus = NULL; unsigned long pirq_table_addr; struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) Loading Loading @@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); return pci_scan_bus(busnum, &pci_root_ops, NULL); return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; Loading Loading @@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; } else if (!strncmp(str, "pirqaddr=", 9)) { pirq_table_addr = simple_strtoul(str+9, NULL, 0); return NULL; } #endif #ifdef CONFIG_PCI_DIRECT Loading arch/i386/pci/irq.c +37 −14 Original line number Diff line number Diff line Loading @@ -58,23 +58,22 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. * Check passed address for the PCI IRQ Routing Table signature * and perform checksum verification. */ static struct irq_routing_table * __init pirq_find_routing_table(void) static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) { u8 *addr; struct irq_routing_table *rt; int i; u8 sum; 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; return NULL; sum = 0; for (i=0; i < rt->size; i++) sum += addr[i]; Loading @@ -82,6 +81,30 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); return rt; } return NULL; } /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; 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 = pirq_check_routing_table(addr); if (rt) return rt; } return NULL; } Loading arch/i386/pci/legacy.c +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); if (pci_root_bus) pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); Loading Loading
Documentation/kernel-parameters.txt +4 −0 Original line number Diff line number Diff line Loading @@ -1030,6 +1030,10 @@ running once the system is up. irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned automatically to PCI devices. You can make the kernel exclude IRQs of your ISA cards this way. pirqaddr=0xAAAAA [IA-32] Specify the physical address of the PIRQ table (normally generated by the BIOS) if it is outside the F0000h-100000h range. lastbus=N [IA-32] Scan all buses till bus #N. Can be useful if the kernel is unable to find your secondary buses and you want to tell it explicitly which ones they are. Loading
arch/i386/kernel/acpi/boot.c +49 −8 Original line number Diff line number Diff line Loading @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ struct acpi_table_mcfg_config *pci_mmcfg_config; int pci_mmcfg_config_num; int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; unsigned long i; int config_size; if (!phys_addr || !size) return -EINVAL; Loading @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } if (mcfg->base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); /* how many config structures do we have */ pci_mmcfg_config_num = 0; i = size - sizeof(struct acpi_table_mcfg); while (i >= sizeof(struct acpi_table_mcfg_config)) { ++pci_mmcfg_config_num; i -= sizeof(struct acpi_table_mcfg_config); }; if (pci_mmcfg_config_num == 0) { printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } pci_mmcfg_base_addr = mcfg->base_address; config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); if (!pci_mmcfg_config) { printk(KERN_WARNING PREFIX "No memory for MCFG config tables\n"); return -ENOMEM; } memcpy(pci_mmcfg_config, &mcfg->config, config_size); for (i = 0; i < pci_mmcfg_config_num; ++i) { if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); return -ENODEV; } } return 0; } #else #define acpi_parse_mcfg NULL #endif /* !CONFIG_PCI_MMCONFIG */ #endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init Loading Loading @@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { /* TBD */ return -EINVAL; } EXPORT_SYMBOL(acpi_register_ioapic); int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) { /* TBD */ return -EINVAL; } EXPORT_SYMBOL(acpi_unregister_ioapic); static unsigned long __init acpi_scan_rsdp ( unsigned long start, Loading Loading @@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } Loading
arch/i386/pci/common.c +6 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; struct pci_bus *pci_root_bus = NULL; unsigned long pirq_table_addr; struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) Loading Loading @@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); return pci_scan_bus(busnum, &pci_root_ops, NULL); return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; Loading Loading @@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; } else if (!strncmp(str, "pirqaddr=", 9)) { pirq_table_addr = simple_strtoul(str+9, NULL, 0); return NULL; } #endif #ifdef CONFIG_PCI_DIRECT Loading
arch/i386/pci/irq.c +37 −14 Original line number Diff line number Diff line Loading @@ -58,23 +58,22 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. * Check passed address for the PCI IRQ Routing Table signature * and perform checksum verification. */ static struct irq_routing_table * __init pirq_find_routing_table(void) static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) { u8 *addr; struct irq_routing_table *rt; int i; u8 sum; 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; return NULL; sum = 0; for (i=0; i < rt->size; i++) sum += addr[i]; Loading @@ -82,6 +81,30 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); return rt; } return NULL; } /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; 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 = pirq_check_routing_table(addr); if (rt) return rt; } return NULL; } Loading
arch/i386/pci/legacy.c +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); if (pci_root_bus) pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); Loading