lkml.org 
[lkml]   [2009]   [Jan]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 4/8] PCI hotplug: fix wrong assumption in acpi_get_hp_hw_control_from_firmware
    Current acpi_get_hp_hw_control_from_firmware() has a assumption that
    pci_bus->self is NULL on a PCI root bus. But it might not be true on
    some platforms. Because of this wrong assumption, current
    acpi_get_hp_hw_control_from_firmware() might cause endless loop. We
    must check pci_bus->parent instead.

    Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

    ---
    drivers/pci/hotplug/acpi_pcihp.c | 34 ++++++++++++----------------------
    1 file changed, 12 insertions(+), 22 deletions(-)

    Index: linux-2.6.29-rc2/drivers/pci/hotplug/acpi_pcihp.c
    ===================================================================
    --- linux-2.6.29-rc2.orig/drivers/pci/hotplug/acpi_pcihp.c
    +++ linux-2.6.29-rc2/drivers/pci/hotplug/acpi_pcihp.c
    @@ -373,12 +373,10 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_fro
    *
    * Attempt to take hotplug control from firmware.
    */
    -int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
    +int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
    {
    acpi_status status;
    acpi_handle chandle, handle;
    - struct pci_dev *pdev = dev;
    - struct pci_bus *parent;
    struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };

    flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
    @@ -410,26 +408,18 @@ int acpi_get_hp_hw_control_from_firmware
    string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
    }

    - pdev = dev;
    - handle = DEVICE_ACPI_HANDLE(&dev->dev);
    - while (!handle) {
    + handle = DEVICE_ACPI_HANDLE(&pdev->dev);
    + if (!handle) {
    /*
    * This hotplug controller was not listed in the ACPI name
    * space at all. Try to get acpi handle of parent pci bus.
    */
    - if (!pdev || !pdev->bus->parent)
    - break;
    - parent = pdev->bus->parent;
    - dbg("Could not find %s in acpi namespace, trying parent\n",
    - pci_name(pdev));
    - if (!parent->self)
    - /* Parent must be a host bridge */
    - handle = acpi_get_pci_rootbridge_handle(
    - pci_domain_nr(parent),
    - parent->number);
    - else
    - handle = DEVICE_ACPI_HANDLE(&(parent->self->dev));
    - pdev = parent->self;
    + struct pci_bus *pbus;
    + for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
    + handle = acpi_pci_get_bridge_handle(pbus);
    + if (handle)
    + break;
    + }
    }

    while (handle) {
    @@ -448,13 +438,13 @@ int acpi_get_hp_hw_control_from_firmware
    }

    dbg("Cannot get control of hotplug hardware for pci %s\n",
    - pci_name(dev));
    + pci_name(pdev));

    kfree(string.pointer);
    return -ENODEV;
    got_one:
    - dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
    - (char *)string.pointer);
    + dbg("Gained control for hotplug HW for pci %s (%s)\n",
    + pci_name(pdev), (char *)string.pointer);
    kfree(string.pointer);
    return 0;
    }



    \
     
     \ /
      Last update: 2009-01-28 12:59    [W:0.026 / U:118.804 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site