struct pci_bus * __devinit pcibios_scan_root(int busnum) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { /* Already scanned */ return bus; } } /* Allocate per-root-bus (not per bus) arch-specific data. * TODO: leak; this memory is never freed. * It's arguable whether it's worth the trouble to care. */ sd = kzalloc(sizeof(*sd), GFP_KERNEL); if (!sd) { printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); return NULL; } sd->node = get_mp_bus_to_node(busnum); printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); if (!bus) kfree(sd); return bus; }
/* * Discover remaining PCI buses in case there are peer host bridges. * We use the number of last PCI bus provided by the PCI BIOS. */ static void __devinit pcibios_fixup_peer_bridges(void) { int n, devfn; long node; if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) return; DBG("PCI: Peer bridge fixup\n"); for (n=0; n <= pcibios_last_bus; n++) { u32 l; if (pci_find_bus(0, n)) continue; node = get_mp_bus_to_node(n); for (devfn = 0; devfn < 256; devfn += 8) { if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) && l != 0x0000 && l != 0xffff) { DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); pci_scan_bus_on_node(n, &pci_root_ops, node); break; } } } }
static void __init pirq_peer_trick(void) { struct irq_routing_table *rt = pirq_table; u8 busmap[256]; int i; struct irq_info *e; memset(busmap, 0, sizeof(busmap)); for (i = 0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { e = &rt->slots[i]; #ifdef DEBUG { int j; DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); for (j = 0; j < 4; j++) DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); DBG("\n"); } #endif busmap[e->bus] = 1; } for (i = 1; i < 256; i++) { int node; if (!busmap[i] || pci_find_bus(0, i)) continue; node = get_mp_bus_to_node(i); if (pci_scan_bus_on_node(i, &pci_root_ops, node)) printk(KERN_INFO "PCI: Discovered primary peer " "bus %02x [IRQ]\n", i); } pcibios_last_bus = -1; }
struct pci_bus * __devinit pcibios_scan_root(int busnum) { struct pci_bus *bus = NULL; while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { /* Already scanned */ return bus; } } return pci_scan_bus_on_node(busnum, &pci_root_ops, get_mp_bus_to_node(busnum)); }
void __devinit pcibios_scan_specific_bus(int busn) { int devfn; long node; u32 l; if (pci_find_bus(0, busn)) return; node = get_mp_bus_to_node(busn); for (devfn = 0; devfn < 256; devfn += 8) { if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && l != 0x0000 && l != 0xffff) { DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn); pci_scan_bus_on_node(busn, &pci_root_ops, node); return; } } }
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) { struct acpi_device *device = root->device; struct pci_root_info *info = NULL; int domain = root->segment; int busnum = root->secondary.start; LIST_HEAD(resources); struct pci_bus *bus = NULL; struct pci_sysdata *sd; int node; #ifdef CONFIG_ACPI_NUMA int pxm; #endif if (pci_ignore_seg) domain = 0; if (domain && !pci_domains_supported) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (multiple domains not supported)\n", domain, busnum); return NULL; } node = -1; #ifdef CONFIG_ACPI_NUMA pxm = acpi_get_pxm(device->handle); if (pxm >= 0) node = pxm_to_node(pxm); if (node != -1) set_mp_bus_to_node(busnum, node); else #endif node = get_mp_bus_to_node(busnum); if (node != -1 && !node_online(node)) node = -1; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (out of memory)\n", domain, busnum); return NULL; } sd = &info->sd; sd->domain = domain; sd->node = node; sd->companion = device; /* * Maybe the desired pci bus has been already scanned. In such case * it is unnecessary to scan the pci bus with the given domain,busnum. */ bus = pci_find_bus(domain, busnum); if (bus) { /* * If the desired bus exits, the content of bus->sysdata will * be replaced by sd. */ memcpy(bus->sysdata, sd, sizeof(*sd)); kfree(info); } else { probe_pci_root_info(info, device, busnum, domain); /* insert busn res at first */ pci_add_resource(&resources, &root->secondary); /* * _CRS with no apertures is normal, so only fall back to * defaults or native bridge info if we're ignoring _CRS. */ if (pci_use_crs) add_resources(info, &resources); else { free_pci_root_info_res(info); x86_pci_root_bus_resources(busnum, &resources); } if (!setup_mcfg_map(info, domain, (u8)root->secondary.start, (u8)root->secondary.end, root->mcfg_addr)) bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); if (bus) { pci_scan_child_bus(bus); pci_set_host_bridge_release( to_pci_host_bridge(bus->bridge), release_pci_root_info, info); } else { pci_free_resource_list(&resources); __release_pci_root_info(info); } } /* After the PCI-E bus has been walked and all devices discovered, * configure any settings of the fabric that might be necessary. */ if (bus) { struct pci_bus *child; list_for_each_entry(child, &bus->children, node) pcie_bus_configure_settings(child); } if (bus && node != -1) { #ifdef CONFIG_ACPI_NUMA if (pxm >= 0) dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d (pxm %d)\n", node, pxm); #else dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); #endif } return bus; }
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { struct acpi_device *device = root->device; int domain = root->segment; int busnum = root->secondary.start; struct pci_bus *bus; struct pci_sysdata *sd; int node; #ifdef CONFIG_ACPI_NUMA int pxm; #endif if (domain && !pci_domains_supported) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (multiple domains not supported)\n", domain, busnum); return NULL; } node = -1; #ifdef CONFIG_ACPI_NUMA pxm = acpi_get_pxm(device->handle); if (pxm >= 0) node = pxm_to_node(pxm); if (node != -1) set_mp_bus_to_node(busnum, node); else #endif node = get_mp_bus_to_node(busnum); if (node != -1 && !node_online(node)) node = -1; /* Allocate per-root-bus (not per bus) arch-specific data. * TODO: leak; this memory is never freed. * It's arguable whether it's worth the trouble to care. */ sd = kzalloc(sizeof(*sd), GFP_KERNEL); if (!sd) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (out of memory)\n", domain, busnum); return NULL; } sd->domain = domain; sd->node = node; /* * Maybe the desired pci bus has been already scanned. In such case * it is unnecessary to scan the pci bus with the given domain,busnum. */ bus = pci_find_bus(domain, busnum); if (bus) { /* * If the desired bus exits, the content of bus->sysdata will * be replaced by sd. */ memcpy(bus->sysdata, sd, sizeof(*sd)); kfree(sd); } else { bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); if (bus) { get_current_resources(device, busnum, domain, bus); bus->subordinate = pci_scan_child_bus(bus); } } if (!bus) kfree(sd); if (bus && node != -1) { #ifdef CONFIG_ACPI_NUMA if (pxm >= 0) dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d (pxm %d)\n", node, pxm); #else dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); #endif } return bus; }
int pcibios_scan_root() { return get_mp_bus_to_node(0); }