X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fprobe.c;h=a10ed9dab2c2d5a04327760de02e140c20ef6f2c;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=3a25b3c189df8f58f6c4b18721786ba4b054341b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3a25b3c18..a10ed9dab 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2,19 +2,14 @@ * probe.c - PCI detection and setup code */ +#include +#include #include #include #include #include #include - -#undef DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif +#include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 @@ -27,12 +22,76 @@ EXPORT_SYMBOL(pci_root_buses); LIST_HEAD(pci_devices); +#ifdef HAVE_PCI_LEGACY +/** + * pci_create_legacy_files - create legacy I/O port and memory files + * @b: bus to create files under + * + * Some platforms allow access to legacy I/O port and ISA memory space on + * a per-bus basis. This routine creates the files and ties them into + * their associated read, write and mmap files from pci-sysfs.c + */ +static void pci_create_legacy_files(struct pci_bus *b) +{ + b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, + GFP_ATOMIC); + if (b->legacy_io) { + b->legacy_io->attr.name = "legacy_io"; + b->legacy_io->size = 0xffff; + b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_io->attr.owner = THIS_MODULE; + b->legacy_io->read = pci_read_legacy_io; + b->legacy_io->write = pci_write_legacy_io; + class_device_create_bin_file(&b->class_dev, b->legacy_io); + + /* Allocated above after the legacy_io struct */ + b->legacy_mem = b->legacy_io + 1; + b->legacy_mem->attr.name = "legacy_mem"; + b->legacy_mem->size = 1024*1024; + b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_mem->attr.owner = THIS_MODULE; + b->legacy_mem->mmap = pci_mmap_legacy_mem; + class_device_create_bin_file(&b->class_dev, b->legacy_mem); + } +} + +void pci_remove_legacy_files(struct pci_bus *b) +{ + if (b->legacy_io) { + class_device_remove_bin_file(&b->class_dev, b->legacy_io); + class_device_remove_bin_file(&b->class_dev, b->legacy_mem); + kfree(b->legacy_io); /* both are allocated here */ + } +} +#else /* !HAVE_PCI_LEGACY */ +static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } +void pci_remove_legacy_files(struct pci_bus *bus) { return; } +#endif /* HAVE_PCI_LEGACY */ + +/* + * PCI Bus Class Devices + */ +static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, + char *buf) +{ + int ret; + cpumask_t cpumask; + + cpumask = pcibus_to_cpumask(to_pci_bus(class_dev)); + ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); + if (ret < PAGE_SIZE) + buf[ret++] = '\n'; + return ret; +} +CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); + /* * PCI Bus Class */ static void release_pcibus_dev(struct class_device *class_dev) { struct pci_bus *pci_bus = to_pci_bus(class_dev); + if (pci_bus->bridge) put_device(pci_bus->bridge); kfree(pci_bus); @@ -49,21 +108,6 @@ static int __init pcibus_class_init(void) } postcore_initcall(pcibus_class_init); -/* - * PCI Bus Class Devices - */ -static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf) -{ - cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number); - int ret; - - ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); - if (ret < PAGE_SIZE) - buf[ret++] = '\n'; - return ret; -} -static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); - /* * Translate the low bits of the PCI base * to the resource type @@ -82,7 +126,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags) /* * Find the extent of a PCI decode.. */ -static u32 pci_size(u32 base, u32 maxbase, unsigned long mask) +static u32 pci_size(u32 base, u32 maxbase, u32 mask) { u32 size = mask & maxbase; /* Find the significant bits */ if (!size) @@ -120,7 +164,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) if (l == 0xffffffff) l = 0; if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { - sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK); + sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK); if (!sz) continue; res->start = l & PCI_BASE_ADDRESS_MEM_MASK; @@ -144,9 +188,11 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) pci_write_config_dword(dev, reg+4, ~0); pci_read_config_dword(dev, reg+4, &sz); pci_write_config_dword(dev, reg+4, l); - if (~sz) - res->end = res->start + 0xffffffff + - (((unsigned long) ~sz) << 32); + sz = pci_size(l, sz, 0xffffffff); + if (sz) { + /* This BAR needs > 4GB? Wow. */ + res->end |= (unsigned long)sz<<32; + } #else if (l) { printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); @@ -168,9 +214,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) if (l == 0xffffffff) l = 0; if (sz && sz != 0xffffffff) { - sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK); + sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK); if (sz) { - res->flags = (l & PCI_ROM_ADDRESS_ENABLE) | + res->flags = (l & IORESOURCE_ROM_ENABLE) | IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE; res->start = l & PCI_ROM_ADDRESS_MASK; @@ -193,10 +239,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) return; if (dev->transparent) { - printk("Transparent bridge - %s\n", pci_name(dev)); - for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) - child->resource[i] = child->parent->resource[i]; - return; + printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev)); + for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) + child->resource[i] = child->parent->resource[i - 3]; } for(i=0; i<3; i++) @@ -218,8 +263,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (base <= limit) { res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; - res->start = base; - res->end = limit + 0xfff; + if (!res->start) + res->start = base; + if (!res->end) + res->end = limit + 0xfff; } res = child->resource[1]; @@ -243,15 +290,23 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) u32 mem_base_hi, mem_limit_hi; pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); + + /* + * Some bridges set the base > limit by default, and some + * (broken) BIOSes do not initialize them. If we find + * this, just assume they are not being used. + */ + if (mem_base_hi <= mem_limit_hi) { #if BITS_PER_LONG == 64 - base |= ((long) mem_base_hi) << 32; - limit |= ((long) mem_limit_hi) << 32; + base |= ((long) mem_base_hi) << 32; + limit |= ((long) mem_limit_hi) << 32; #else - if (mem_base_hi || mem_limit_hi) { - printk(KERN_ERR "PCI: Unable to handle 64-bit address space for %s\n", child->name); - return; - } + if (mem_base_hi || mem_limit_hi) { + printk(KERN_ERR "PCI: Unable to handle 64-bit address space for bridge %s\n", pci_name(dev)); + return; + } #endif + } } if (base <= limit) { res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; @@ -264,9 +319,8 @@ static struct pci_bus * __devinit pci_alloc_bus(void) { struct pci_bus *b; - b = kmalloc(sizeof(*b), GFP_KERNEL); + b = kzalloc(sizeof(*b), GFP_KERNEL); if (b) { - memset(b, 0, sizeof(*b)); INIT_LIST_HEAD(&b->node); INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->devices); @@ -291,6 +345,7 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) child->parent = parent; child->ops = parent->ops; child->sysdata = parent->sysdata; + child->bus_flags = parent->bus_flags; child->bridge = get_device(&bridge->dev); child->class_dev.class = &pcibus_class; @@ -321,12 +376,47 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de struct pci_bus *child; child = pci_alloc_child_bus(parent, dev, busnr); - if (child) + if (child) { + spin_lock(&pci_bus_lock); list_add_tail(&child->node, &parent->children); + spin_unlock(&pci_bus_lock); + } return child; } -static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); +static void pci_enable_crs(struct pci_dev *dev) +{ + u16 cap, rpctl; + int rpcap = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!rpcap) + return; + + pci_read_config_word(dev, rpcap + PCI_CAP_FLAGS, &cap); + if (((cap & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_ROOT_PORT) + return; + + pci_read_config_word(dev, rpcap + PCI_EXP_RTCTL, &rpctl); + rpctl |= PCI_EXP_RTCTL_CRSSVE; + pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); +} + +static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +{ + struct pci_bus *parent = child->parent; + + /* Attempts to fix that up are really dangerous unless + we're going to re-assign all bus numbers. */ + if (!pcibios_assign_all_busses()) + return; + + while (parent->parent && parent->subordinate < max) { + parent->subordinate = max; + pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); + parent = parent->parent; + } +} + +unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); /* * If it's a bridge, configure it and scan the bus behind it. @@ -342,13 +432,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); - u32 buses; + u32 buses, i, j = 0; u16 bctl; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); - DBG("Scanning behind PCI bridge %s, config %06x, pass %d\n", - pci_name(dev), buses & 0xffffff, pass); + pr_debug("PCI: Scanning behind PCI bridge %s, config %06x, pass %d\n", + pci_name(dev), buses & 0xffffff, pass); /* Disable MasterAbortMode during probing to avoid reporting of bus errors (in some architectures) */ @@ -356,6 +446,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); + pci_enable_crs(dev); + if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { unsigned int cmax, busnr; /* @@ -363,27 +455,57 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * pass and just note the configuration. */ if (pass) - return max; + goto out; busnr = (buses >> 8) & 0xFF; - child = pci_alloc_child_bus(bus, dev, busnr); + + /* + * If we already got to this bus through a different bridge, + * ignore it. This can happen with the i450NX chipset. + */ + if (pci_find_bus(pci_domain_nr(bus), busnr)) { + printk(KERN_INFO "PCI: Bus %04x:%02x already known\n", + pci_domain_nr(bus), busnr); + goto out; + } + + child = pci_add_new_bus(bus, dev, busnr); + if (!child) + goto out; child->primary = buses & 0xFF; child->subordinate = (buses >> 16) & 0xFF; child->bridge_ctl = bctl; cmax = pci_scan_child_bus(child); - if (cmax > max) max = cmax; + if (cmax > max) + max = cmax; + if (child->subordinate > max) + max = child->subordinate; } else { /* * We need to assign a number to this bus which we always * do in the second pass. */ - if (!pass) - return max; + if (!pass) { + if (pcibios_assign_all_busses()) + /* Temporarily disable forwarding of the + configuration cycles on all bridges in + this bus segment to avoid possible + conflicts in the second pass between two + bridges programmed with overlapping + bus ranges. */ + pci_write_config_dword(dev, PCI_PRIMARY_BUS, + buses & ~0xffffff); + goto out; + } /* Clear errors */ pci_write_config_word(dev, PCI_STATUS, 0xffff); - child = pci_alloc_child_bus(bus, dev, ++max); + /* Prevent assigning a bus number that already exists. + * This can happen when a bridge is hot-plugged */ + if (pci_find_bus(pci_domain_nr(bus), max+1)) + goto out; + child = pci_add_new_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) | ((unsigned int)(child->secondary) << 8) @@ -404,17 +526,52 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); if (!is_cardbus) { - child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; - + child->bridge_ctl = bctl | PCI_BRIDGE_CTL_NO_ISA; + /* + * Adjust subordinate busnr in parent buses. + * We do this before scanning for children because + * some devices may not be detected if the bios + * was lazy. + */ + pci_fixup_parent_subordinate_busnr(child, max); /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); + /* + * now fix it up again since we have found + * the real value of max. + */ + pci_fixup_parent_subordinate_busnr(child, max); } else { /* * For CardBus bridges, we leave 4 bus numbers * as cards with a PCI-to-PCI bridge can be * inserted later. */ - max += CARDBUS_RESERVE_BUSNR; + for (i=0; iparent) { + if ((!pcibios_assign_all_busses()) && + (parent->subordinate > max) && + (parent->subordinate <= max+i)) { + j = 1; + } + parent = parent->parent; + } + if (j) { + /* + * Often, there are two cardbus bridges + * -- try to leave one valid bus number + * for each one. + */ + i /= 2; + break; + } + } + max += i; + pci_fixup_parent_subordinate_busnr(child, max); } /* * Set the subordinate bus number to its real value. @@ -423,10 +580,29 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); } - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); - sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + while (bus->parent) { + if ((child->subordinate > bus->subordinate) || + (child->number > bus->subordinate) || + (child->number < bus->number) || + (child->subordinate < bus->number)) { + printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " + "hidden behind%s bridge #%02x (-#%02x)%s\n", + child->number, child->subordinate, + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate, + pcibios_assign_all_busses() ? " " : + " (try 'pci=assign-busses')"); + printk(KERN_WARNING "Please report the result to " + "linux-kernel to fix this permanently\n"); + } + bus = bus->parent; + } + +out: + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); + return max; } @@ -439,6 +615,7 @@ static void pci_read_irq(struct pci_dev *dev) unsigned char irq; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); + dev->pin = irq; if (irq) pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); dev->irq = irq; @@ -458,7 +635,6 @@ static int pci_setup_device(struct pci_dev * dev) { u32 class; - dev->slot_name = dev->dev.bus_id; sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); @@ -467,11 +643,15 @@ static int pci_setup_device(struct pci_dev * dev) dev->class = class; class >>= 8; - DBG("Found %02x:%02x [%04x/%04x] %06x %02x\n", dev->bus->number, - dev->devfn, dev->vendor, dev->device, class, dev->hdr_type); + pr_debug("PCI: Found %s [%04x/%04x] %06x %02x\n", pci_name(dev), + dev->vendor, dev->device, class, dev->hdr_type); /* "Unknown power state" */ - dev->current_state = 4; + dev->current_state = PCI_UNKNOWN; + + /* Early fixups, before probing the BARs */ + pci_fixup_device(pci_fixup_early, dev); + class = dev->class >> 8; switch (dev->hdr_type) { /* header type */ case PCI_HEADER_TYPE_NORMAL: /* standard header */ @@ -489,6 +669,7 @@ static int pci_setup_device(struct pci_dev * dev) /* The PCI-to-PCI bridge spec requires that subtractive decoding (i.e. transparent) bridge must have programming interface code of 0x01. */ + pci_read_irq(dev); dev->transparent = ((dev->class & 0xff) == 1); pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); break; @@ -534,6 +715,7 @@ static void pci_release_dev(struct device *dev) /** * pci_cfg_space_size - get the configuration space size of the PCI device. + * @dev: PCI device * * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices * have 4096 bytes. Even if the device is capable, that doesn't mean we can @@ -542,7 +724,7 @@ static void pci_release_dev(struct device *dev) * reading the dword at 0x100 which must either be 0 or a valid extended * capability header. */ -static int pci_cfg_space_size(struct pci_dev *dev) +int pci_cfg_space_size(struct pci_dev *dev) { int pos; u32 status; @@ -569,6 +751,11 @@ static int pci_cfg_space_size(struct pci_dev *dev) return PCI_CFG_SPACE_SIZE; } +static void pci_release_bus_bridge_dev(struct device *dev) +{ + kfree(dev); +} + /* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... @@ -579,9 +766,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) struct pci_dev *dev; u32 l; u8 hdr_type; - - if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) - return NULL; + int delay = 1; if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) return NULL; @@ -591,11 +776,29 @@ pci_scan_device(struct pci_bus *bus, int devfn) l == 0x0000ffff || l == 0xffff0000) return NULL; - dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + /* Configuration request Retry Status */ + while (l == 0xffff0001) { + msleep(delay); + delay *= 2; + if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) + return NULL; + /* Card hasn't responded in 60 seconds? Must be stuck. */ + if (delay > 60 * 1000) { + printk(KERN_WARNING "Device %04x:%02x:%02x.%d not " + "responding\n", pci_domain_nr(bus), + bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn)); + return NULL; + } + } + + if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) + return NULL; + + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = bus->sysdata; dev->dev.parent = bus->bridge; @@ -614,16 +817,30 @@ pci_scan_device(struct pci_bus *bus, int devfn) kfree(dev); return NULL; } + + return dev; +} + +void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) +{ device_initialize(&dev->dev); dev->dev.release = pci_release_dev; pci_dev_get(dev); - pci_name_device(dev); - dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = 0xffffffffull; - return dev; + /* Fix up broken headers */ + pci_fixup_device(pci_fixup_header, dev); + + /* + * Add the device to our list of discovered devices + * and the bus list for fixup functions, etc. + */ + INIT_LIST_HEAD(&dev->global_list); + spin_lock(&pci_bus_lock); + list_add_tail(&dev->bus_list, &bus->devices); + spin_unlock(&pci_bus_lock); } struct pci_dev * __devinit @@ -632,20 +849,11 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) struct pci_dev *dev; dev = pci_scan_device(bus, devfn); - pci_scan_msi_device(dev); - if (!dev) return NULL; - - /* Fix up broken headers */ - pci_fixup_device(PCI_FIXUP_HEADER, dev); - /* - * Add the device to our list of discovered devices - * and the bus list for fixup functions, etc. - */ - INIT_LIST_HEAD(&dev->global_list); - list_add_tail(&dev->bus_list, &bus->devices); + pci_device_add(dev, bus); + pci_scan_msi_device(dev); return dev; } @@ -692,12 +900,12 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) return nr; } -static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) +unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) { unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; - DBG("Scanning bus %02x\n", bus->number); + pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number); /* Go find them, Rover! */ for (devfn = 0; devfn < 0x100; devfn += 8) @@ -707,7 +915,7 @@ static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) * After performing arch-dependent fixup of the bus, look behind * all PCI-to-PCI bridges on this bus. */ - DBG("Fixups for bus %02x\n", bus->number); + pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number); pcibios_fixup_bus(bus); for (pass=0; pass < 2; pass++) list_for_each_entry(dev, &bus->devices, bus_list) { @@ -723,7 +931,8 @@ static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) * * Return how far we've got finding sub-buses. */ - DBG("Bus scan for %02x returning with max=%02x\n", bus->number, max); + pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n", + pci_domain_nr(bus), bus->number, max); return max; } @@ -741,8 +950,10 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) return max; } -struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) +struct pci_bus * __devinit pci_create_bus(struct device *parent, + int bus, struct pci_ops *ops, void *sysdata) { + int error; struct pci_bus *b; struct device *dev; @@ -761,34 +972,69 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, if (pci_find_bus(pci_domain_nr(b), bus)) { /* If we already got to this bus through a different bridge, ignore it */ - DBG("PCI: Bus %02x already known\n", bus); - kfree(dev); - kfree(b); - return NULL; + pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); + goto err_out; } + spin_lock(&pci_bus_lock); list_add_tail(&b->node, &pci_root_buses); + spin_unlock(&pci_bus_lock); memset(dev, 0, sizeof(*dev)); dev->parent = parent; + dev->release = pci_release_bus_bridge_dev; sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus); - device_register(dev); + error = device_register(dev); + if (error) + goto dev_reg_err; b->bridge = get_device(dev); b->class_dev.class = &pcibus_class; sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); - class_device_register(&b->class_dev); - class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); + error = class_device_register(&b->class_dev); + if (error) + goto class_dev_reg_err; + error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); + if (error) + goto class_dev_create_file_err; - sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); + /* Create legacy_io and legacy_mem files for this bus */ + pci_create_legacy_files(b); + + error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); + if (error) + goto sys_create_link_err; b->number = b->secondary = bus; b->resource[0] = &ioport_resource; b->resource[1] = &iomem_resource; - b->subordinate = pci_scan_child_bus(b); + return b; + +sys_create_link_err: + class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity); +class_dev_create_file_err: + class_device_unregister(&b->class_dev); +class_dev_reg_err: + device_unregister(dev); +dev_reg_err: + spin_lock(&pci_bus_lock); + list_del(&b->node); + spin_unlock(&pci_bus_lock); +err_out: + kfree(dev); + kfree(b); + return NULL; +} +EXPORT_SYMBOL_GPL(pci_create_bus); - pci_bus_add_devices(b); +struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, + int bus, struct pci_ops *ops, void *sysdata) +{ + struct pci_bus *b; + b = pci_create_bus(parent, bus, ops, sysdata); + if (b) + b->subordinate = pci_scan_child_bus(b); return b; } EXPORT_SYMBOL(pci_scan_bus_parented); @@ -799,4 +1045,5 @@ EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_bridge); EXPORT_SYMBOL(pci_scan_single_device); +EXPORT_SYMBOL_GPL(pci_scan_child_bus); #endif