.. | .. |
---|
1878 | 1878 | add_size = size - new_size; |
---|
1879 | 1879 | pci_dbg(bridge, "bridge window %pR shrunken by %pa\n", res, |
---|
1880 | 1880 | &add_size); |
---|
| 1881 | + } else { |
---|
| 1882 | + return; |
---|
1881 | 1883 | } |
---|
1882 | 1884 | |
---|
1883 | 1885 | res->end = res->start + new_size - 1; |
---|
1884 | 1886 | remove_from_list(add_list, res); |
---|
1885 | 1887 | } |
---|
1886 | 1888 | |
---|
| 1889 | +static void remove_dev_resource(struct resource *avail, struct pci_dev *dev, |
---|
| 1890 | + struct resource *res) |
---|
| 1891 | +{ |
---|
| 1892 | + resource_size_t size, align, tmp; |
---|
| 1893 | + |
---|
| 1894 | + size = resource_size(res); |
---|
| 1895 | + if (!size) |
---|
| 1896 | + return; |
---|
| 1897 | + |
---|
| 1898 | + align = pci_resource_alignment(dev, res); |
---|
| 1899 | + align = align ? ALIGN(avail->start, align) - avail->start : 0; |
---|
| 1900 | + tmp = align + size; |
---|
| 1901 | + avail->start = min(avail->start + tmp, avail->end + 1); |
---|
| 1902 | +} |
---|
| 1903 | + |
---|
| 1904 | +static void remove_dev_resources(struct pci_dev *dev, struct resource *io, |
---|
| 1905 | + struct resource *mmio, |
---|
| 1906 | + struct resource *mmio_pref) |
---|
| 1907 | +{ |
---|
| 1908 | + int i; |
---|
| 1909 | + |
---|
| 1910 | + for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
---|
| 1911 | + struct resource *res = &dev->resource[i]; |
---|
| 1912 | + |
---|
| 1913 | + if (resource_type(res) == IORESOURCE_IO) { |
---|
| 1914 | + remove_dev_resource(io, dev, res); |
---|
| 1915 | + } else if (resource_type(res) == IORESOURCE_MEM) { |
---|
| 1916 | + |
---|
| 1917 | + /* |
---|
| 1918 | + * Make sure prefetchable memory is reduced from |
---|
| 1919 | + * the correct resource. Specifically we put 32-bit |
---|
| 1920 | + * prefetchable memory in non-prefetchable window |
---|
| 1921 | + * if there is an 64-bit pretchable window. |
---|
| 1922 | + * |
---|
| 1923 | + * See comments in __pci_bus_size_bridges() for |
---|
| 1924 | + * more information. |
---|
| 1925 | + */ |
---|
| 1926 | + if ((res->flags & IORESOURCE_PREFETCH) && |
---|
| 1927 | + ((res->flags & IORESOURCE_MEM_64) == |
---|
| 1928 | + (mmio_pref->flags & IORESOURCE_MEM_64))) |
---|
| 1929 | + remove_dev_resource(mmio_pref, dev, res); |
---|
| 1930 | + else |
---|
| 1931 | + remove_dev_resource(mmio, dev, res); |
---|
| 1932 | + } |
---|
| 1933 | + } |
---|
| 1934 | +} |
---|
| 1935 | + |
---|
| 1936 | +/* |
---|
| 1937 | + * io, mmio and mmio_pref contain the total amount of bridge window space |
---|
| 1938 | + * available. This includes the minimal space needed to cover all the |
---|
| 1939 | + * existing devices on the bus and the possible extra space that can be |
---|
| 1940 | + * shared with the bridges. |
---|
| 1941 | + */ |
---|
1887 | 1942 | static void pci_bus_distribute_available_resources(struct pci_bus *bus, |
---|
1888 | 1943 | struct list_head *add_list, |
---|
1889 | 1944 | struct resource io, |
---|
.. | .. |
---|
1893 | 1948 | unsigned int normal_bridges = 0, hotplug_bridges = 0; |
---|
1894 | 1949 | struct resource *io_res, *mmio_res, *mmio_pref_res; |
---|
1895 | 1950 | struct pci_dev *dev, *bridge = bus->self; |
---|
1896 | | - resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align; |
---|
| 1951 | + resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align; |
---|
1897 | 1952 | |
---|
1898 | 1953 | io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW]; |
---|
1899 | 1954 | mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW]; |
---|
.. | .. |
---|
1937 | 1992 | normal_bridges++; |
---|
1938 | 1993 | } |
---|
1939 | 1994 | |
---|
1940 | | - /* |
---|
1941 | | - * There is only one bridge on the bus so it gets all available |
---|
1942 | | - * resources which it can then distribute to the possible hotplug |
---|
1943 | | - * bridges below. |
---|
1944 | | - */ |
---|
1945 | | - if (hotplug_bridges + normal_bridges == 1) { |
---|
1946 | | - dev = list_first_entry(&bus->devices, struct pci_dev, bus_list); |
---|
1947 | | - if (dev->subordinate) |
---|
1948 | | - pci_bus_distribute_available_resources(dev->subordinate, |
---|
1949 | | - add_list, io, mmio, mmio_pref); |
---|
| 1995 | + if (!(hotplug_bridges + normal_bridges)) |
---|
1950 | 1996 | return; |
---|
| 1997 | + |
---|
| 1998 | + /* |
---|
| 1999 | + * Calculate the amount of space we can forward from "bus" to any |
---|
| 2000 | + * downstream buses, i.e., the space left over after assigning the |
---|
| 2001 | + * BARs and windows on "bus". |
---|
| 2002 | + */ |
---|
| 2003 | + list_for_each_entry(dev, &bus->devices, bus_list) { |
---|
| 2004 | + if (!dev->is_virtfn) |
---|
| 2005 | + remove_dev_resources(dev, &io, &mmio, &mmio_pref); |
---|
1951 | 2006 | } |
---|
1952 | 2007 | |
---|
1953 | | - if (hotplug_bridges == 0) |
---|
1954 | | - return; |
---|
1955 | | - |
---|
1956 | 2008 | /* |
---|
1957 | | - * Calculate the total amount of extra resource space we can |
---|
1958 | | - * pass to bridges below this one. This is basically the |
---|
1959 | | - * extra space reduced by the minimal required space for the |
---|
1960 | | - * non-hotplug bridges. |
---|
| 2009 | + * If there is at least one hotplug bridge on this bus it gets all |
---|
| 2010 | + * the extra resource space that was left after the reductions |
---|
| 2011 | + * above. |
---|
| 2012 | + * |
---|
| 2013 | + * If there are no hotplug bridges the extra resource space is |
---|
| 2014 | + * split between non-hotplug bridges. This is to allow possible |
---|
| 2015 | + * hotplug bridges below them to get the extra space as well. |
---|
1961 | 2016 | */ |
---|
| 2017 | + if (hotplug_bridges) { |
---|
| 2018 | + io_per_b = div64_ul(resource_size(&io), hotplug_bridges); |
---|
| 2019 | + mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges); |
---|
| 2020 | + mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), |
---|
| 2021 | + hotplug_bridges); |
---|
| 2022 | + } else { |
---|
| 2023 | + io_per_b = div64_ul(resource_size(&io), normal_bridges); |
---|
| 2024 | + mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges); |
---|
| 2025 | + mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), |
---|
| 2026 | + normal_bridges); |
---|
| 2027 | + } |
---|
| 2028 | + |
---|
1962 | 2029 | for_each_pci_bridge(dev, bus) { |
---|
1963 | | - resource_size_t used_size; |
---|
1964 | 2030 | struct resource *res; |
---|
1965 | | - |
---|
1966 | | - if (dev->is_hotplug_bridge) |
---|
1967 | | - continue; |
---|
1968 | | - |
---|
1969 | | - /* |
---|
1970 | | - * Reduce the available resource space by what the |
---|
1971 | | - * bridge and devices below it occupy. |
---|
1972 | | - */ |
---|
1973 | | - res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; |
---|
1974 | | - align = pci_resource_alignment(dev, res); |
---|
1975 | | - align = align ? ALIGN(io.start, align) - io.start : 0; |
---|
1976 | | - used_size = align + resource_size(res); |
---|
1977 | | - if (!res->parent) |
---|
1978 | | - io.start = min(io.start + used_size, io.end + 1); |
---|
1979 | | - |
---|
1980 | | - res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; |
---|
1981 | | - align = pci_resource_alignment(dev, res); |
---|
1982 | | - align = align ? ALIGN(mmio.start, align) - mmio.start : 0; |
---|
1983 | | - used_size = align + resource_size(res); |
---|
1984 | | - if (!res->parent) |
---|
1985 | | - mmio.start = min(mmio.start + used_size, mmio.end + 1); |
---|
1986 | | - |
---|
1987 | | - res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; |
---|
1988 | | - align = pci_resource_alignment(dev, res); |
---|
1989 | | - align = align ? ALIGN(mmio_pref.start, align) - |
---|
1990 | | - mmio_pref.start : 0; |
---|
1991 | | - used_size = align + resource_size(res); |
---|
1992 | | - if (!res->parent) |
---|
1993 | | - mmio_pref.start = min(mmio_pref.start + used_size, |
---|
1994 | | - mmio_pref.end + 1); |
---|
1995 | | - } |
---|
1996 | | - |
---|
1997 | | - io_per_hp = div64_ul(resource_size(&io), hotplug_bridges); |
---|
1998 | | - mmio_per_hp = div64_ul(resource_size(&mmio), hotplug_bridges); |
---|
1999 | | - mmio_pref_per_hp = div64_ul(resource_size(&mmio_pref), |
---|
2000 | | - hotplug_bridges); |
---|
2001 | | - |
---|
2002 | | - /* |
---|
2003 | | - * Go over devices on this bus and distribute the remaining |
---|
2004 | | - * resource space between hotplug bridges. |
---|
2005 | | - */ |
---|
2006 | | - for_each_pci_bridge(dev, bus) { |
---|
2007 | 2031 | struct pci_bus *b; |
---|
2008 | 2032 | |
---|
2009 | 2033 | b = dev->subordinate; |
---|
2010 | | - if (!b || !dev->is_hotplug_bridge) |
---|
| 2034 | + if (!b) |
---|
| 2035 | + continue; |
---|
| 2036 | + if (hotplug_bridges && !dev->is_hotplug_bridge) |
---|
2011 | 2037 | continue; |
---|
2012 | 2038 | |
---|
| 2039 | + res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; |
---|
| 2040 | + |
---|
2013 | 2041 | /* |
---|
2014 | | - * Distribute available extra resources equally between |
---|
2015 | | - * hotplug-capable downstream ports taking alignment into |
---|
2016 | | - * account. |
---|
| 2042 | + * Make sure the split resource space is properly aligned |
---|
| 2043 | + * for bridge windows (align it down to avoid going above |
---|
| 2044 | + * what is available). |
---|
2017 | 2045 | */ |
---|
2018 | | - io.end = io.start + io_per_hp - 1; |
---|
2019 | | - mmio.end = mmio.start + mmio_per_hp - 1; |
---|
2020 | | - mmio_pref.end = mmio_pref.start + mmio_pref_per_hp - 1; |
---|
| 2046 | + align = pci_resource_alignment(dev, res); |
---|
| 2047 | + io.end = align ? io.start + ALIGN_DOWN(io_per_b, align) - 1 |
---|
| 2048 | + : io.start + io_per_b - 1; |
---|
| 2049 | + |
---|
| 2050 | + /* |
---|
| 2051 | + * The x_per_b holds the extra resource space that can be |
---|
| 2052 | + * added for each bridge but there is the minimal already |
---|
| 2053 | + * reserved as well so adjust x.start down accordingly to |
---|
| 2054 | + * cover the whole space. |
---|
| 2055 | + */ |
---|
| 2056 | + io.start -= resource_size(res); |
---|
| 2057 | + |
---|
| 2058 | + res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; |
---|
| 2059 | + align = pci_resource_alignment(dev, res); |
---|
| 2060 | + mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_b, align) - 1 |
---|
| 2061 | + : mmio.start + mmio_per_b - 1; |
---|
| 2062 | + mmio.start -= resource_size(res); |
---|
| 2063 | + |
---|
| 2064 | + res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; |
---|
| 2065 | + align = pci_resource_alignment(dev, res); |
---|
| 2066 | + mmio_pref.end = align ? mmio_pref.start + |
---|
| 2067 | + ALIGN_DOWN(mmio_pref_per_b, align) - 1 |
---|
| 2068 | + : mmio_pref.start + mmio_pref_per_b - 1; |
---|
| 2069 | + mmio_pref.start -= resource_size(res); |
---|
2021 | 2070 | |
---|
2022 | 2071 | pci_bus_distribute_available_resources(b, add_list, io, mmio, |
---|
2023 | 2072 | mmio_pref); |
---|
2024 | 2073 | |
---|
2025 | | - io.start += io_per_hp; |
---|
2026 | | - mmio.start += mmio_per_hp; |
---|
2027 | | - mmio_pref.start += mmio_pref_per_hp; |
---|
| 2074 | + io.start += io.end + 1; |
---|
| 2075 | + mmio.start += mmio.end + 1; |
---|
| 2076 | + mmio_pref.start += mmio_pref.end + 1; |
---|
2028 | 2077 | } |
---|
2029 | 2078 | } |
---|
2030 | 2079 | |
---|