lkml.org 
[lkml]   [2012]   [Sep]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 16/40] PCI: pci_bus_size_bridges() should not size own bridge
    Date
    During checking acpiphp code, found following sequence:
    pci_bus_size_bridges(bus);
    pci_bus_assign_resources(bus);
    pci_enable_bridges(bus);

    The problem is that when bus is not root bus, pci_bus_size_bridges would also size
    own pci bridge bus->self if that bridge resource is not inserted before.
    but later pci_bus_assign_resources will not allocate those size bridge res.

    So try make it less confusing, let it does not include self sizing.
    and add with_self parameter info __pci_bus_size_bridge()

    Fixes caller in pci hotplug componets.

    Signed-off-by: Yinghai Lu <yinghai@kernel.org>
    ---
    drivers/pci/hotplug/acpiphp_glue.c | 3 ++-
    drivers/pci/setup-bus.c | 24 +++++++++++++++---------
    include/linux/pci.h | 1 +
    3 files changed, 18 insertions(+), 10 deletions(-)

    diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
    index 085eec7..6cb1923 100644
    --- a/drivers/pci/hotplug/acpiphp_glue.c
    +++ b/drivers/pci/hotplug/acpiphp_glue.c
    @@ -842,7 +842,8 @@ static int __ref enable_device(struct acpiphp_slot *slot)
    max = pci_scan_bridge(bus, dev, max, pass);
    if (pass && dev->subordinate) {
    check_hotplug_bridge(slot, dev);
    - pci_bus_size_bridges(dev->subordinate);
    + pci_bus_size_bridges_with_self(
    + dev->subordinate);
    }
    }
    }
    diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
    index 31821d4..85f7ec73 100644
    --- a/drivers/pci/setup-bus.c
    +++ b/drivers/pci/setup-bus.c
    @@ -1044,8 +1044,8 @@ handle_done:
    ;
    }

    -void __ref __pci_bus_size_bridges(struct pci_bus *bus,
    - struct list_head *realloc_head)
    +static void __ref __pci_bus_size_bridges(struct pci_bus *bus,
    + struct list_head *realloc_head, bool with_self)
    {
    struct pci_dev *dev;
    unsigned long mask, prefmask;
    @@ -1063,13 +1063,13 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,

    case PCI_CLASS_BRIDGE_PCI:
    default:
    - __pci_bus_size_bridges(b, realloc_head);
    + __pci_bus_size_bridges(b, realloc_head, true);
    break;
    }
    }

    - /* The root bus? */
    - if (!bus->self)
    + /* Is root bus or not wanted? */
    + if (!bus->self || !with_self)
    return;

    switch (bus->self->class >> 8) {
    @@ -1109,9 +1109,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
    }
    }

    +void __ref pci_bus_size_bridges_with_self(struct pci_bus *bus)
    +{
    + __pci_bus_size_bridges(bus, NULL, true);
    +}
    +EXPORT_SYMBOL(pci_bus_size_bridges_with_self);
    +
    void __ref pci_bus_size_bridges(struct pci_bus *bus)
    {
    - __pci_bus_size_bridges(bus, NULL);
    + __pci_bus_size_bridges(bus, NULL, false);
    }
    EXPORT_SYMBOL(pci_bus_size_bridges);

    @@ -1424,7 +1430,7 @@ again:
    /* Depth first, calculate sizes and alignments of all
    subordinate buses. */
    list_for_each_entry(bus, &pci_root_buses, node)
    - __pci_bus_size_bridges(bus, add_list);
    + __pci_bus_size_bridges(bus, add_list, false);

    /* Depth last, allocate resources and update the hardware. */
    list_for_each_entry(bus, &pci_root_buses, node)
    @@ -1501,7 +1507,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
    IORESOURCE_PREFETCH;

    again:
    - __pci_bus_size_bridges(parent, &add_list);
    + __pci_bus_size_bridges(parent, &add_list, true);
    __pci_bridge_assign_resources(bridge, &add_list, &fail_head);
    BUG_ON(!list_empty(&add_list));
    tried_times++;
    @@ -1562,7 +1568,7 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
    if (dev->subordinate)
    __pci_bus_size_bridges(dev->subordinate,
    - &add_list);
    + &add_list, true);
    up_read(&pci_bus_sem);
    __pci_bus_assign_resources(bus, &add_list, NULL);
    BUG_ON(!list_empty(&add_list));
    diff --git a/include/linux/pci.h b/include/linux/pci.h
    index 02b8e10..7404077 100644
    --- a/include/linux/pci.h
    +++ b/include/linux/pci.h
    @@ -978,6 +978,7 @@ int pci_vpd_truncate(struct pci_dev *dev, size_t size);
    resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
    void pci_bus_assign_resources(const struct pci_bus *bus);
    void pci_bus_size_bridges(struct pci_bus *bus);
    +void pci_bus_size_bridges_with_self(struct pci_bus *bus);
    int pci_claim_resource(struct pci_dev *, int);
    void pci_assign_unassigned_resources(void);
    void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
    --
    1.7.7


    \
     
     \ /
      Last update: 2012-09-19 22:01    [W:4.310 / U:0.236 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site