Commit ddd13dc6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
  PCI: add acpi_find_root_bridge_handle
  PCI: acpi_pcihp: run _OSC on a root bridge
  x86/PCI: irq and pci_ids patch for Intel Ibex Peak PCHs
  x86/PCI: allow scanning of 255 PCI busses
  x86, pci: detect end_bus_number according to acpi/e820 reserved, v2
  pci: debug extra pci bus resources
  pci: debug extra pci resources range
parents f607e3a0 a59f2bba
...@@ -590,6 +590,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route ...@@ -590,6 +590,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH10_1: case PCI_DEVICE_ID_INTEL_ICH10_1:
case PCI_DEVICE_ID_INTEL_ICH10_2: case PCI_DEVICE_ID_INTEL_ICH10_2:
case PCI_DEVICE_ID_INTEL_ICH10_3: case PCI_DEVICE_ID_INTEL_ICH10_3:
case PCI_DEVICE_ID_INTEL_PCH_0:
case PCI_DEVICE_ID_INTEL_PCH_1:
r->name = "PIIX/ICH"; r->name = "PIIX/ICH";
r->get = pirq_piix_get; r->get = pirq_piix_get;
r->set = pirq_piix_set; r->set = pirq_piix_set;
......
...@@ -14,7 +14,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) ...@@ -14,7 +14,7 @@ static void __devinit pcibios_fixup_peer_bridges(void)
int n, devfn; int n, devfn;
long node; long node;
if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
return; return;
DBG("PCI: Peer bridge fixup\n"); DBG("PCI: Peer bridge fixup\n");
......
...@@ -293,7 +293,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, ...@@ -293,7 +293,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
return AE_OK; return AE_OK;
} }
static int __init is_acpi_reserved(unsigned long start, unsigned long end) static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
{ {
struct resource mcfg_res; struct resource mcfg_res;
...@@ -310,6 +310,41 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end) ...@@ -310,6 +310,41 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end)
return mcfg_res.flags; return mcfg_res.flags;
} }
typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
static int __init is_mmconf_reserved(check_reserved_t is_reserved,
u64 addr, u64 size, int i,
typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
{
u64 old_size = size;
int valid = 0;
while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) {
size >>= 1;
if (size < (16UL<<20))
break;
}
if (size >= (16UL<<20) || size == old_size) {
printk(KERN_NOTICE
"PCI: MCFG area at %Lx reserved in %s\n",
addr, with_e820?"E820":"ACPI motherboard resources");
valid = 1;
if (old_size != size) {
/* update end_bus_number */
cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1);
printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx "
"segment %hu buses %u - %u\n",
i, (unsigned long)cfg->address, cfg->pci_segment,
(unsigned int)cfg->start_bus_number,
(unsigned int)cfg->end_bus_number);
}
}
return valid;
}
static void __init pci_mmcfg_reject_broken(int early) static void __init pci_mmcfg_reject_broken(int early)
{ {
typeof(pci_mmcfg_config[0]) *cfg; typeof(pci_mmcfg_config[0]) *cfg;
...@@ -324,21 +359,22 @@ static void __init pci_mmcfg_reject_broken(int early) ...@@ -324,21 +359,22 @@ static void __init pci_mmcfg_reject_broken(int early)
for (i = 0; i < pci_mmcfg_config_num; i++) { for (i = 0; i < pci_mmcfg_config_num; i++) {
int valid = 0; int valid = 0;
u32 size = (cfg->end_bus_number + 1) << 20; u64 addr, size;
cfg = &pci_mmcfg_config[i]; cfg = &pci_mmcfg_config[i];
addr = cfg->start_bus_number;
addr <<= 20;
addr += cfg->address;
size = cfg->end_bus_number + 1 - cfg->start_bus_number;
size <<= 20;
printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
"segment %hu buses %u - %u\n", "segment %hu buses %u - %u\n",
i, (unsigned long)cfg->address, cfg->pci_segment, i, (unsigned long)cfg->address, cfg->pci_segment,
(unsigned int)cfg->start_bus_number, (unsigned int)cfg->start_bus_number,
(unsigned int)cfg->end_bus_number); (unsigned int)cfg->end_bus_number);
if (!early && if (!early)
is_acpi_reserved(cfg->address, cfg->address + size - 1)) { valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0);
printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
"in ACPI motherboard resources\n",
cfg->address);
valid = 1;
}
if (valid) if (valid)
continue; continue;
...@@ -347,16 +383,11 @@ static void __init pci_mmcfg_reject_broken(int early) ...@@ -347,16 +383,11 @@ static void __init pci_mmcfg_reject_broken(int early)
printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
" reserved in ACPI motherboard resources\n", " reserved in ACPI motherboard resources\n",
cfg->address); cfg->address);
/* Don't try to do this check unless configuration /* Don't try to do this check unless configuration
type 1 is available. how about type 2 ?*/ type 1 is available. how about type 2 ?*/
if (raw_pci_ops && e820_all_mapped(cfg->address, if (raw_pci_ops)
cfg->address + size - 1, valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1);
E820_RESERVED)) {
printk(KERN_NOTICE
"PCI: MCFG area at %Lx reserved in E820\n",
cfg->address);
valid = 1;
}
if (!valid) if (!valid)
goto reject; goto reject;
......
...@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); ...@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
{ {
acpi_status status; acpi_status status;
acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); acpi_handle chandle, handle;
struct pci_dev *pdev = dev; struct pci_dev *pdev = dev;
struct pci_bus *parent; struct pci_bus *parent;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
...@@ -399,10 +399,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) ...@@ -399,10 +399,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
* Per PCI firmware specification, we should run the ACPI _OSC * Per PCI firmware specification, we should run the ACPI _OSC
* method to get control of hotplug hardware before using it. If * method to get control of hotplug hardware before using it. If
* an _OSC is missing, we look for an OSHP to do the same thing. * an _OSC is missing, we look for an OSHP to do the same thing.
* To handle different BIOS behavior, we look for _OSC and OSHP * To handle different BIOS behavior, we look for _OSC on a root
* within the scope of the hotplug controller and its parents, * bridge preferentially (according to PCI fw spec). Later for
* OSHP within the scope of the hotplug controller and its parents,
* upto the host bridge under which this controller exists. * upto the host bridge under which this controller exists.
*/ */
handle = acpi_find_root_bridge_handle(pdev);
if (handle) {
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s\n",
(char *)string.pointer);
status = pci_osc_control_set(handle, flags);
if (ACPI_SUCCESS(status))
goto got_one;
kfree(string.pointer);
string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
}
pdev = dev;
handle = DEVICE_ACPI_HANDLE(&dev->dev);
while (!handle) { while (!handle) {
/* /*
* This hotplug controller was not listed in the ACPI name * This hotplug controller was not listed in the ACPI name
...@@ -427,15 +442,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) ...@@ -427,15 +442,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s \n", dbg("Trying to get hotplug control for %s \n",
(char *)string.pointer); (char *)string.pointer);
status = pci_osc_control_set(handle, flags);
if (status == AE_NOT_FOUND)
status = acpi_run_oshp(handle); status = acpi_run_oshp(handle);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status))
dbg("Gained control for hotplug HW for pci %s (%s)\n", goto got_one;
pci_name(dev), (char *)string.pointer);
kfree(string.pointer);
return 0;
}
if (acpi_root_bridge(handle)) if (acpi_root_bridge(handle))
break; break;
chandle = handle; chandle = handle;
...@@ -449,6 +458,11 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) ...@@ -449,6 +458,11 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
kfree(string.pointer); kfree(string.pointer);
return -ENODEV; return -ENODEV;
got_one:
dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
(char *)string.pointer);
kfree(string.pointer);
return 0;
} }
EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware);
......
...@@ -36,12 +36,7 @@ int aer_osc_setup(struct pcie_device *pciedev) ...@@ -36,12 +36,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
if (acpi_pci_disabled) if (acpi_pci_disabled)
return -1; return -1;
/* Find root host bridge */ handle = acpi_find_root_bridge_handle(pdev);
while (pdev->bus->self)
pdev = pdev->bus->self;
handle = acpi_get_pci_rootbridge_handle(
pci_domain_nr(pdev->bus), pdev->bus->number);
if (handle) { if (handle) {
pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
status = pci_osc_control_set(handle, status = pci_osc_control_set(handle,
......
...@@ -383,6 +383,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) ...@@ -383,6 +383,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->start = base; res->start = base;
if (!res->end) if (!res->end)
res->end = limit + 0xfff; res->end = limit + 0xfff;
printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
} }
res = child->resource[1]; res = child->resource[1];
...@@ -394,6 +395,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) ...@@ -394,6 +395,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base; res->start = base;
res->end = limit + 0xfffff; res->end = limit + 0xfffff;
printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
} }
res = child->resource[2]; res = child->resource[2];
...@@ -429,6 +431,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) ...@@ -429,6 +431,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base; res->start = base;
res->end = limit + 0xfffff; res->end = limit + 0xfffff;
printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
} }
} }
......
...@@ -530,6 +530,36 @@ void __ref pci_bus_assign_resources(struct pci_bus *bus) ...@@ -530,6 +530,36 @@ void __ref pci_bus_assign_resources(struct pci_bus *bus)
} }
EXPORT_SYMBOL(pci_bus_assign_resources); EXPORT_SYMBOL(pci_bus_assign_resources);
static void pci_bus_dump_res(struct pci_bus *bus)
{
int i;
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
struct resource *res = bus->resource[i];
if (!res)
continue;
printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
}
}
static void pci_bus_dump_resources(struct pci_bus *bus)
{
struct pci_bus *b;
struct pci_dev *dev;
pci_bus_dump_res(bus);
list_for_each_entry(dev, &bus->devices, bus_list) {
b = dev->subordinate;
if (!b)
continue;
pci_bus_dump_resources(b);
}
}
void __init void __init
pci_assign_unassigned_resources(void) pci_assign_unassigned_resources(void)
{ {
...@@ -545,4 +575,9 @@ pci_assign_unassigned_resources(void) ...@@ -545,4 +575,9 @@ pci_assign_unassigned_resources(void)
pci_bus_assign_resources(bus); pci_bus_assign_resources(bus);
pci_enable_bridges(bus); pci_enable_bridges(bus);
} }
/* dump the resource on buses */
list_for_each_entry(bus, &pci_root_buses, node) {
pci_bus_dump_resources(bus);
}
} }
...@@ -57,6 +57,15 @@ static inline acpi_status pcie_osc_support_set(u32 flags) ...@@ -57,6 +57,15 @@ static inline acpi_status pcie_osc_support_set(u32 flags)
{ {
return __pci_osc_support_set(flags, PCI_EXPRESS_ROOT_HID_STRING); return __pci_osc_support_set(flags, PCI_EXPRESS_ROOT_HID_STRING);
} }
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
{
/* Find root host bridge */
while (pdev->bus->self)
pdev = pdev->bus->self;
return acpi_get_pci_rootbridge_handle(pci_domain_nr(pdev->bus),
pdev->bus->number);
}
#else #else
#if !defined(AE_ERROR) #if !defined(AE_ERROR)
typedef u32 acpi_status; typedef u32 acpi_status;
...@@ -66,6 +75,8 @@ static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) ...@@ -66,6 +75,8 @@ static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
{return AE_ERROR;} {return AE_ERROR;}
static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;}
static inline acpi_status pcie_osc_support_set(u32 flags) {return AE_ERROR;} static inline acpi_status pcie_osc_support_set(u32 flags) {return AE_ERROR;}
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
{ return NULL; }
#endif #endif
#endif /* _PCI_ACPI_H_ */ #endif /* _PCI_ACPI_H_ */
...@@ -2428,6 +2428,9 @@ ...@@ -2428,6 +2428,9 @@
#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a #define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a
#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 #define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30
#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60
#define PCI_DEVICE_ID_INTEL_PCH_0 0x3b10
#define PCI_DEVICE_ID_INTEL_PCH_1 0x3b11
#define PCI_DEVICE_ID_INTEL_PCH_2 0x3b30
#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment