lkml.org 
[lkml]   [2012]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/9] pci: Fix pci cardbus removal
    Date
    During test busn_res allocation with cardbus, found pci card removal is not
    working anymore, and it turns out it is broken by:

    |commit 79cc9601c3e42b4f0650fe7e69132ebce7ab48f9
    |Date: Tue Nov 22 21:06:53 2011 -0800
    |
    | PCI: Only call pci_stop_bus_device() one time for child devices at remove

    that patch changed pci_remove_behind_bridge behavoir that yenta_carbus depends.

    Restore the old behavoir of pci_remove_behind_bridge by:
    1. rename pci_remove_behind_bridge to __pci_remove_behind_bridge, and let
    __pci_remove_bus_device() call it instead.
    2. add pci-stop_befind_bridge that will stop device under bridge
    3. add back pci_remove_behind_bridge that will stop and remove device
    under bridge.

    This one is for v3.3

    -v2: update commit description a little bit.

    Signed-off-by: Yinghai Lu <yinghai@kernel.org>
    ---
    drivers/pci/remove.c | 28 ++++++++++++++++++++++------
    1 files changed, 22 insertions(+), 6 deletions(-)

    diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
    index bd70f23..82f8ae5 100644
    --- a/drivers/pci/remove.c
    +++ b/drivers/pci/remove.c
    @@ -77,6 +77,7 @@ void pci_remove_bus(struct pci_bus *pci_bus)
    }
    EXPORT_SYMBOL(pci_remove_bus);

    +static void __pci_remove_behind_bridge(struct pci_dev *dev);
    /**
    * pci_remove_bus_device - remove a PCI device and any children
    * @dev: the device to remove
    @@ -94,7 +95,7 @@ static void __pci_remove_bus_device(struct pci_dev *dev)
    if (dev->subordinate) {
    struct pci_bus *b = dev->subordinate;

    - pci_remove_behind_bridge(dev);
    + __pci_remove_behind_bridge(dev);
    pci_remove_bus(b);
    dev->subordinate = NULL;
    }
    @@ -107,6 +108,24 @@ void pci_remove_bus_device(struct pci_dev *dev)
    __pci_remove_bus_device(dev);
    }

    +static void __pci_remove_behind_bridge(struct pci_dev *dev)
    +{
    + struct list_head *l, *n;
    +
    + if (dev->subordinate)
    + list_for_each_safe(l, n, &dev->subordinate->devices)
    + __pci_remove_bus_device(pci_dev_b(l));
    +}
    +
    +static void pci_stop_behind_bridge(struct pci_dev *dev)
    +{
    + struct list_head *l, *n;
    +
    + if (dev->subordinate)
    + list_for_each_safe(l, n, &dev->subordinate->devices)
    + pci_stop_bus_device(pci_dev_b(l));
    +}
    +
    /**
    * pci_remove_behind_bridge - remove all devices behind a PCI bridge
    * @dev: PCI bridge device
    @@ -117,11 +136,8 @@ void pci_remove_bus_device(struct pci_dev *dev)
    */
    void pci_remove_behind_bridge(struct pci_dev *dev)
    {
    - struct list_head *l, *n;
    -
    - if (dev->subordinate)
    - list_for_each_safe(l, n, &dev->subordinate->devices)
    - __pci_remove_bus_device(pci_dev_b(l));
    + pci_stop_behind_bridge(dev);
    + __pci_remove_behind_bridge(dev);
    }

    static void pci_stop_bus_devices(struct pci_bus *bus)
    --
    1.7.7


    \
     
     \ /
      Last update: 2012-02-05 07:59    [W:0.024 / U:65.060 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site