Merge tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Host bridge hotplug: - Add MMCONFIG support for hot-added host bridges (Jiang Liu) Device hotplug: - Move fixups from __init to __devinit (Sebastian Andrzej Siewior) - Call FINAL fixups for hot-added devices, too (Myron Stowe) - Factor out generic code for P2P bridge hot-add (Yinghai Lu) - Remove all functions in a slot, not just those with _EJx (Amos Kong) Dynamic resource management: - Track bus number allocation (struct resource tree per domain) (Yinghai Lu) - Make P2P bridge 1K I/O windows work with resource reassignment (Bjorn Helgaas, Yinghai Lu) - Disable decoding while updating 64-bit BARs (Bjorn Helgaas) Power management: - Add PCIe runtime D3cold support (Huang Ying) Virtualization: - Add VFIO infrastructure (ACS, DMA source ID quirks) (Alex Williamson) - Add quirks for devices with broken INTx masking (Jan Kiszka) Miscellaneous: - Fix some PCI Express capability version issues (Myron Stowe) - Factor out some arch code with a weak, generic, pcibios_setup() (Myron Stowe)" * tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (122 commits) PCI: hotplug: ensure a consistent return value in error case PCI: fix undefined reference to 'pci_fixup_final_inited' PCI: build resource code for M68K architecture PCI: pciehp: remove unused pciehp_get_max_lnk_width(), pciehp_get_cur_lnk_width() PCI: reorder __pci_assign_resource() (no change) PCI: fix truncation of resource size to 32 bits PCI: acpiphp: merge acpiphp_debug and debug PCI: acpiphp: remove unused res_lock sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases() PCI: call final fixups hot-added devices PCI: move final fixups from __init to __devinit x86/PCI: move final fixups from __init to __devinit MIPS/PCI: move final fixups from __init to __devinit PCI: support sizing P2P bridge I/O windows with 1K granularity PCI: reimplement P2P bridge 1K I/O windows (Intel P64H2) PCI: disable MEM decoding while updating 64-bit MEM BARs PCI: leave MEM and IO decoding disabled during 64-bit BAR sizing, too PCI: never discard enable/suspend/resume_early/resume fixups PCI: release temporary reference in __nv_msi_ht_cap_quirk() PCI: restructure 'pci_do_fixups()' ...
This commit is contained in:
@@ -265,7 +265,7 @@ out:
|
||||
* assign_requested_resources_sorted() - satisfy resource requests
|
||||
*
|
||||
* @head : head of the list tracking requests for resources
|
||||
* @failed_list : head of the list tracking requests that could
|
||||
* @fail_head : head of the list tracking requests that could
|
||||
* not be allocated
|
||||
*
|
||||
* Satisfy resource requests of each element in the list. Add
|
||||
@@ -404,8 +404,8 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||
struct resource *res;
|
||||
struct pci_bus_region region;
|
||||
|
||||
dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
dev_info(&bridge->dev, "CardBus bridge to %pR\n",
|
||||
&bus->busn_res);
|
||||
|
||||
res = bus->resource[0];
|
||||
pcibios_resource_to_bus(bridge, ®ion, res);
|
||||
@@ -469,16 +469,23 @@ static void pci_setup_bridge_io(struct pci_bus *bus)
|
||||
struct pci_dev *bridge = bus->self;
|
||||
struct resource *res;
|
||||
struct pci_bus_region region;
|
||||
unsigned long io_mask;
|
||||
u8 io_base_lo, io_limit_lo;
|
||||
u32 l, io_upper16;
|
||||
|
||||
io_mask = PCI_IO_RANGE_MASK;
|
||||
if (bridge->io_window_1k)
|
||||
io_mask = PCI_IO_1K_RANGE_MASK;
|
||||
|
||||
/* Set up the top and bottom of the PCI I/O segment for this bus. */
|
||||
res = bus->resource[0];
|
||||
pcibios_resource_to_bus(bridge, ®ion, res);
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
pci_read_config_dword(bridge, PCI_IO_BASE, &l);
|
||||
l &= 0xffff0000;
|
||||
l |= (region.start >> 8) & 0x00f0;
|
||||
l |= region.end & 0xf000;
|
||||
io_base_lo = (region.start >> 8) & io_mask;
|
||||
io_limit_lo = (region.end >> 8) & io_mask;
|
||||
l |= ((u32) io_limit_lo << 8) | io_base_lo;
|
||||
/* Set up upper 16 bits of I/O base/limit. */
|
||||
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
|
||||
dev_info(&bridge->dev, " bridge window %pR\n", res);
|
||||
@@ -553,8 +560,8 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
|
||||
{
|
||||
struct pci_dev *bridge = bus->self;
|
||||
|
||||
dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
dev_info(&bridge->dev, "PCI bridge to %pR\n",
|
||||
&bus->busn_res);
|
||||
|
||||
if (type & IORESOURCE_IO)
|
||||
pci_setup_bridge_io(bus);
|
||||
@@ -699,7 +706,7 @@ static resource_size_t calculate_memsize(resource_size_t size,
|
||||
* @realloc_head : track the additional io window on this list
|
||||
*
|
||||
* Sizing the IO windows of the PCI-PCI bridge is trivial,
|
||||
* since these windows have 4K granularity and the IO ranges
|
||||
* since these windows have 1K or 4K granularity and the IO ranges
|
||||
* of non-bridge PCI devices are limited to 256 bytes.
|
||||
* We must be careful with the ISA aliasing though.
|
||||
*/
|
||||
@@ -710,10 +717,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
|
||||
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
|
||||
unsigned long size = 0, size0 = 0, size1 = 0;
|
||||
resource_size_t children_add_size = 0;
|
||||
resource_size_t min_align = 4096, align;
|
||||
|
||||
if (!b_res)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Per spec, I/O windows are 4K-aligned, but some bridges have an
|
||||
* extension to support 1K alignment.
|
||||
*/
|
||||
if (bus->self->io_window_1k)
|
||||
min_align = 1024;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
int i;
|
||||
|
||||
@@ -731,34 +745,43 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
|
||||
else
|
||||
size1 += r_size;
|
||||
|
||||
align = pci_resource_alignment(dev, r);
|
||||
if (align > min_align)
|
||||
min_align = align;
|
||||
|
||||
if (realloc_head)
|
||||
children_add_size += get_res_add_size(realloc_head, r);
|
||||
}
|
||||
}
|
||||
|
||||
if (min_align > 4096)
|
||||
min_align = 4096;
|
||||
|
||||
size0 = calculate_iosize(size, min_size, size1,
|
||||
resource_size(b_res), 4096);
|
||||
resource_size(b_res), min_align);
|
||||
if (children_add_size > add_size)
|
||||
add_size = children_add_size;
|
||||
size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
|
||||
calculate_iosize(size, min_size, add_size + size1,
|
||||
resource_size(b_res), 4096);
|
||||
resource_size(b_res), min_align);
|
||||
if (!size0 && !size1) {
|
||||
if (b_res->start || b_res->end)
|
||||
dev_info(&bus->self->dev, "disabling bridge window "
|
||||
"%pR to [bus %02x-%02x] (unused)\n", b_res,
|
||||
bus->secondary, bus->subordinate);
|
||||
"%pR to %pR (unused)\n", b_res,
|
||||
&bus->busn_res);
|
||||
b_res->flags = 0;
|
||||
return;
|
||||
}
|
||||
/* Alignment of the IO window is always 4K */
|
||||
b_res->start = 4096;
|
||||
|
||||
b_res->start = min_align;
|
||||
b_res->end = b_res->start + size0 - 1;
|
||||
b_res->flags |= IORESOURCE_STARTALIGN;
|
||||
if (size1 > size0 && realloc_head) {
|
||||
add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
|
||||
add_to_list(realloc_head, bus->self, b_res, size1-size0,
|
||||
min_align);
|
||||
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
|
||||
"%pR to [bus %02x-%02x] add_size %lx\n", b_res,
|
||||
bus->secondary, bus->subordinate, size1-size0);
|
||||
"%pR to %pR add_size %lx\n", b_res,
|
||||
&bus->busn_res, size1-size0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,8 +886,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
||||
if (!size0 && !size1) {
|
||||
if (b_res->start || b_res->end)
|
||||
dev_info(&bus->self->dev, "disabling bridge window "
|
||||
"%pR to [bus %02x-%02x] (unused)\n", b_res,
|
||||
bus->secondary, bus->subordinate);
|
||||
"%pR to %pR (unused)\n", b_res,
|
||||
&bus->busn_res);
|
||||
b_res->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -874,8 +897,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
||||
if (size1 > size0 && realloc_head) {
|
||||
add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
|
||||
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
|
||||
"%pR to [bus %02x-%02x] add_size %llx\n", b_res,
|
||||
bus->secondary, bus->subordinate, (unsigned long long)size1-size0);
|
||||
"%pR to %pR add_size %llx\n", b_res,
|
||||
&bus->busn_res, (unsigned long long)size1-size0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user