diff options
author | Eric W. Biederman <ebiederm@aristanetworks.com> | 2009-09-09 17:09:24 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-09 17:10:24 -0400 |
commit | 28760489a3f1e136c5ae8581c0fa8f63511f2f4c (patch) | |
tree | a3c890e9c8d9e98385691d56f5c007d280514fe5 /drivers/pci/probe.c | |
parent | 0ba379ec0fb182a87b8891c5754abbcd9c035b4f (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/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 18 |
1 files changed, 18 insertions, 0 deletions
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 | ||
700 | static 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, ®16); | ||
710 | if (!(reg16 & PCI_EXP_FLAGS_SLOT)) | ||
711 | return; | ||
712 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, ®32); | ||
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 */ |