lkml.org 
[lkml]   [2012]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v1 10/22] PCI: enhance PCI bus specific logic to support PCI bus lock mechanism
    Date
    This patch enhances PCI bus specific logic to support PCI bus lock mechanism.

    Signed-off-by: Jiang Liu <liuj97@gmail.com>
    ---
    drivers/pci/bus.c | 54 ++++++++++++++++++++++++++++++-----------------------
    1 file changed, 31 insertions(+), 23 deletions(-)

    diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
    index b6aacaa..371f20a 100644
    --- a/drivers/pci/bus.c
    +++ b/drivers/pci/bus.c
    @@ -185,19 +185,20 @@ int pci_bus_add_device(struct pci_dev *dev)
    */
    int pci_bus_add_child(struct pci_bus *bus)
    {
    - int retval;
    -
    - if (bus->bridge)
    - bus->dev.parent = bus->bridge;
    -
    - retval = device_add(&bus->dev);
    - if (retval)
    - return retval;
    -
    - bus->is_added = 1;
    -
    - /* Create legacy_io and legacy_mem files for this bus */
    - pci_create_legacy_files(bus);
    + int retval = -EBUSY;
    +
    + if (pci_bus_get_state(bus) == PCI_BUS_STATE_INITIALIZED) {
    + if (bus->bridge)
    + bus->dev.parent = bus->bridge;
    + retval = device_add(&bus->dev);
    + if (retval == 0) {
    + /* Create legacy_io and legacy_mem files for this bus */
    + pci_create_legacy_files(bus);
    + pci_bus_change_state(bus, PCI_BUS_STATE_INITIALIZED,
    + PCI_BUS_STATE_WORKING, false);
    + bus->is_added = 1;
    + }
    + }

    return retval;
    }
    @@ -232,13 +233,14 @@ void pci_bus_add_devices(const struct pci_bus *bus)
    list_for_each_entry(dev, &bus->devices, bus_list) {
    BUG_ON(!dev->is_added);

    - child = dev->subordinate;
    + child = pci_lock_subordinate(dev, PCI_BUS_STATE_STOPPING - 1);
    + if (!child)
    + continue;
    +
    /*
    * If there is an unattached subordinate bus, attach
    * it and then scan for unattached PCI devices.
    */
    - if (!child)
    - continue;
    if (list_empty(&child->node)) {
    down_write(&pci_bus_sem);
    list_add_tail(&child->node, &dev->bus->children);
    @@ -250,28 +252,34 @@ void pci_bus_add_devices(const struct pci_bus *bus)
    * register the bus with sysfs as the parent is now
    * properly registered.
    */
    - if (child->is_added)
    - continue;
    - retval = pci_bus_add_child(child);
    - if (retval)
    - dev_err(&dev->dev, "Error adding bus, continuing\n");
    + if (pci_bus_get_state(child) == PCI_BUS_STATE_INITIALIZED) {
    + retval = pci_bus_add_child(child);
    + if (retval)
    + dev_err(&dev->dev,
    + "Error adding bus, continuing\n");
    + }
    +
    + pci_bus_unlock(child);
    }
    }

    void pci_enable_bridges(struct pci_bus *bus)
    {
    struct pci_dev *dev;
    + struct pci_bus *child;
    int retval;

    list_for_each_entry(dev, &bus->devices, bus_list) {
    - if (dev->subordinate) {
    + child = pci_lock_subordinate(dev, PCI_BUS_STATE_STOPPING - 1);
    + if (child) {
    if (!pci_is_enabled(dev)) {
    retval = pci_enable_device(dev);
    if (retval)
    dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", retval);
    pci_set_master(dev);
    }
    - pci_enable_bridges(dev->subordinate);
    + pci_enable_bridges(child);
    + pci_bus_unlock(child);
    }
    }
    }
    --
    1.7.9.5


    \
     
     \ /
      Last update: 2012-08-07 19:02    [W:3.750 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site