aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2009-09-09 17:09:24 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-09 17:10:24 -0400
commit28760489a3f1e136c5ae8581c0fa8f63511f2f4c (patch)
treea3c890e9c8d9e98385691d56f5c007d280514fe5 /drivers
parent0ba379ec0fb182a87b8891c5754abbcd9c035b4f (diff)
PCI: pcie: Ensure hotplug ports have a minimum number of resources
In general a BIOS may goof or we may hotplug in a hotplug controller. In either case the kernel needs to reserve resources for plugging in more devices in the future instead of creating a minimal resource assignment. We already do this for cardbus bridges I am just adding a variant for pcie bridges. v2: Make testing for pcie hotplug bridges based on a flag. So far we only set the flag for pcie but a header_quirk could easily be added for the non-standard pci hotplug bridges. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci.c10
-rw-r--r--drivers/pci/probe.c18
-rw-r--r--drivers/pci/setup-bus.c22
3 files changed, 45 insertions, 5 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bd993351db45..8c663d628d03 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -41,6 +41,12 @@ int pci_domains_supported = 1;
41unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE; 41unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
42unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; 42unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
43 43
44#define DEFAULT_HOTPLUG_IO_SIZE (256)
45#define DEFAULT_HOTPLUG_MEM_SIZE (2*1024*1024)
46/* pci=hpmemsize=nnM,hpiosize=nn can override this */
47unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
48unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
49
44/** 50/**
45 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children 51 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
46 * @bus: pointer to PCI bus structure to search 52 * @bus: pointer to PCI bus structure to search
@@ -2732,6 +2738,10 @@ static int __init pci_setup(char *str)
2732 strlen(str + 19)); 2738 strlen(str + 19));
2733 } else if (!strncmp(str, "ecrc=", 5)) { 2739 } else if (!strncmp(str, "ecrc=", 5)) {
2734 pcie_ecrc_get_policy(str + 5); 2740 pcie_ecrc_get_policy(str + 5);
2741 } else if (!strncmp(str, "hpiosize=", 9)) {
2742 pci_hotplug_io_size = memparse(str + 9, &str);
2743 } else if (!strncmp(str, "hpmemsize=", 10)) {
2744 pci_hotplug_mem_size = memparse(str + 10, &str);
2735 } else { 2745 } else {
2736 printk(KERN_ERR "PCI: Unknown option `%s'\n", 2746 printk(KERN_ERR "PCI: Unknown option `%s'\n",
2737 str); 2747 str);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ab52840f4753..882383b61d30 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -697,6 +697,23 @@ static void set_pcie_port_type(struct pci_dev *pdev)
697 pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; 697 pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
698} 698}
699 699
700static void set_pcie_hotplug_bridge(struct pci_dev *pdev)
701{
702 int pos;
703 u16 reg16;
704 u32 reg32;
705
706 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
707 if (!pos)
708 return;
709 pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
710 if (!(reg16 & PCI_EXP_FLAGS_SLOT))
711 return;
712 pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &reg32);
713 if (reg32 & PCI_EXP_SLTCAP_HPC)
714 pdev->is_hotplug_bridge = 1;
715}
716
700#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) 717#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
701 718
702/** 719/**
@@ -804,6 +821,7 @@ int pci_setup_device(struct pci_dev *dev)
804 pci_read_irq(dev); 821 pci_read_irq(dev);
805 dev->transparent = ((dev->class & 0xff) == 1); 822 dev->transparent = ((dev->class & 0xff) == 1);
806 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); 823 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
824 set_pcie_hotplug_bridge(dev);
807 break; 825 break;
808 826
809 case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ 827 case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 7c443b4583ab..cb1a027eb552 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -309,7 +309,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
309 since these windows have 4K granularity and the IO ranges 309 since these windows have 4K granularity and the IO ranges
310 of non-bridge PCI devices are limited to 256 bytes. 310 of non-bridge PCI devices are limited to 256 bytes.
311 We must be careful with the ISA aliasing though. */ 311 We must be careful with the ISA aliasing though. */
312static void pbus_size_io(struct pci_bus *bus) 312static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
313{ 313{
314 struct pci_dev *dev; 314 struct pci_dev *dev;
315 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 315 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -336,6 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
336 size1 += r_size; 336 size1 += r_size;
337 } 337 }
338 } 338 }
339 if (size < min_size)
340 size = min_size;
339/* To be fixed in 2.5: we should have sort of HAVE_ISA 341/* To be fixed in 2.5: we should have sort of HAVE_ISA
340 flag in the struct pci_bus. */ 342 flag in the struct pci_bus. */
341#if defined(CONFIG_ISA) || defined(CONFIG_EISA) 343#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
@@ -354,7 +356,8 @@ static void pbus_size_io(struct pci_bus *bus)
354 356
355/* Calculate the size of the bus and minimal alignment which 357/* Calculate the size of the bus and minimal alignment which
356 guarantees that all child resources fit in this size. */ 358 guarantees that all child resources fit in this size. */
357static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) 359static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
360 unsigned long type, resource_size_t min_size)
358{ 361{
359 struct pci_dev *dev; 362 struct pci_dev *dev;
360 resource_size_t min_align, align, size; 363 resource_size_t min_align, align, size;
@@ -404,6 +407,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
404 mem64_mask &= r->flags & IORESOURCE_MEM_64; 407 mem64_mask &= r->flags & IORESOURCE_MEM_64;
405 } 408 }
406 } 409 }
410 if (size < min_size)
411 size = min_size;
407 412
408 align = 0; 413 align = 0;
409 min_align = 0; 414 min_align = 0;
@@ -483,6 +488,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
483{ 488{
484 struct pci_dev *dev; 489 struct pci_dev *dev;
485 unsigned long mask, prefmask; 490 unsigned long mask, prefmask;
491 resource_size_t min_mem_size = 0, min_io_size = 0;
486 492
487 list_for_each_entry(dev, &bus->devices, bus_list) { 493 list_for_each_entry(dev, &bus->devices, bus_list) {
488 struct pci_bus *b = dev->subordinate; 494 struct pci_bus *b = dev->subordinate;
@@ -512,8 +518,12 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
512 518
513 case PCI_CLASS_BRIDGE_PCI: 519 case PCI_CLASS_BRIDGE_PCI:
514 pci_bridge_check_ranges(bus); 520 pci_bridge_check_ranges(bus);
521 if (bus->self->is_hotplug_bridge) {
522 min_io_size = pci_hotplug_io_size;
523 min_mem_size = pci_hotplug_mem_size;
524 }
515 default: 525 default:
516 pbus_size_io(bus); 526 pbus_size_io(bus, min_io_size);
517 /* If the bridge supports prefetchable range, size it 527 /* If the bridge supports prefetchable range, size it
518 separately. If it doesn't, or its prefetchable window 528 separately. If it doesn't, or its prefetchable window
519 has already been allocated by arch code, try 529 has already been allocated by arch code, try
@@ -521,9 +531,11 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
521 resources. */ 531 resources. */
522 mask = IORESOURCE_MEM; 532 mask = IORESOURCE_MEM;
523 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; 533 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
524 if (pbus_size_mem(bus, prefmask, prefmask)) 534 if (pbus_size_mem(bus, prefmask, prefmask, min_mem_size))
525 mask = prefmask; /* Success, size non-prefetch only. */ 535 mask = prefmask; /* Success, size non-prefetch only. */
526 pbus_size_mem(bus, mask, IORESOURCE_MEM); 536 else
537 min_mem_size += min_mem_size;
538 pbus_size_mem(bus, mask, IORESOURCE_MEM, min_mem_size);
527 break; 539 break;
528 } 540 }
529} 541}