diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-05-18 13:35:50 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-06-13 17:42:22 -0400 |
commit | 98a3583107ed587ed3cfe2a1d8e5347421de5a80 (patch) | |
tree | 402af5b2aee4af6f6ffaefb0f856b33f70e4a9b5 /drivers/pci/probe.c | |
parent | 82ec90eac304e81b1389175b4dded7abecc678ef (diff) |
PCI: add busn_res operation functions
Will use them insert/update busn res in pci_bus struct.
[bhelgaas: print conflicting entry if insertion fails]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 674a477a6486..7662ab7b2640 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1714,6 +1714,74 @@ err_out: | |||
1714 | return NULL; | 1714 | return NULL; |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) | ||
1718 | { | ||
1719 | struct resource *res = &b->busn_res; | ||
1720 | struct resource *parent_res, *conflict; | ||
1721 | |||
1722 | res->start = bus; | ||
1723 | res->end = bus_max; | ||
1724 | res->flags = IORESOURCE_BUS; | ||
1725 | |||
1726 | if (!pci_is_root_bus(b)) | ||
1727 | parent_res = &b->parent->busn_res; | ||
1728 | else { | ||
1729 | parent_res = get_pci_domain_busn_res(pci_domain_nr(b)); | ||
1730 | res->flags |= IORESOURCE_PCI_FIXED; | ||
1731 | } | ||
1732 | |||
1733 | conflict = insert_resource_conflict(parent_res, res); | ||
1734 | |||
1735 | if (conflict) | ||
1736 | dev_printk(KERN_DEBUG, &b->dev, | ||
1737 | "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n", | ||
1738 | res, pci_is_root_bus(b) ? "domain " : "", | ||
1739 | parent_res, conflict->name, conflict); | ||
1740 | else | ||
1741 | dev_printk(KERN_DEBUG, &b->dev, | ||
1742 | "busn_res: %pR is inserted under %s%pR\n", | ||
1743 | res, pci_is_root_bus(b) ? "domain " : "", | ||
1744 | parent_res); | ||
1745 | |||
1746 | return conflict == NULL; | ||
1747 | } | ||
1748 | |||
1749 | int pci_bus_update_busn_res_end(struct pci_bus *b, int bus_max) | ||
1750 | { | ||
1751 | struct resource *res = &b->busn_res; | ||
1752 | struct resource old_res = *res; | ||
1753 | resource_size_t size; | ||
1754 | int ret; | ||
1755 | |||
1756 | if (res->start > bus_max) | ||
1757 | return -EINVAL; | ||
1758 | |||
1759 | size = bus_max - res->start + 1; | ||
1760 | ret = adjust_resource(res, res->start, size); | ||
1761 | dev_printk(KERN_DEBUG, &b->dev, | ||
1762 | "busn_res: %pR end %s updated to %02x\n", | ||
1763 | &old_res, ret ? "can not be" : "is", bus_max); | ||
1764 | |||
1765 | if (!ret && !res->parent) | ||
1766 | pci_bus_insert_busn_res(b, res->start, res->end); | ||
1767 | |||
1768 | return ret; | ||
1769 | } | ||
1770 | |||
1771 | void pci_bus_release_busn_res(struct pci_bus *b) | ||
1772 | { | ||
1773 | struct resource *res = &b->busn_res; | ||
1774 | int ret; | ||
1775 | |||
1776 | if (!res->flags || !res->parent) | ||
1777 | return; | ||
1778 | |||
1779 | ret = release_resource(res); | ||
1780 | dev_printk(KERN_DEBUG, &b->dev, | ||
1781 | "busn_res: %pR %s released\n", | ||
1782 | res, ret ? "can not be" : "is"); | ||
1783 | } | ||
1784 | |||
1717 | struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, | 1785 | struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus, |
1718 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1786 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1719 | { | 1787 | { |