lkml.org 
[lkml]   [2009]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2/4] pci: try to assign res for device under transparent bridges -v2

    we could run out of space under under 4g, but device under transparent bridge
    still use 64bit resource, so try on parent bus again and again.

    [ Impact: better support for assigne unassigned resources ]

    Signed-off-by: Yinghai Lu <yinghai@kernel.org>

    ---
    drivers/pci/setup-bus.c | 1
    drivers/pci/setup-res.c | 49 +++++++++++++++++++++++++++++++++++-------------
    2 files changed, 36 insertions(+), 14 deletions(-)

    Index: linux-2.6/drivers/pci/setup-bus.c
    ===================================================================
    --- linux-2.6.orig/drivers/pci/setup-bus.c
    +++ linux-2.6/drivers/pci/setup-bus.c
    @@ -58,7 +58,6 @@ static void pbus_assign_resources_sorted
    res = list->res;
    idx = res - &list->dev->resource[0];
    if (pci_assign_resource(list->dev, idx)) {
    - /* FIXME: get rid of this */
    res->start = 0;
    res->end = 0;
    res->flags = 0;
    Index: linux-2.6/drivers/pci/setup-res.c
    ===================================================================
    --- linux-2.6.orig/drivers/pci/setup-res.c
    +++ linux-2.6/drivers/pci/setup-res.c
    @@ -135,23 +135,16 @@ void pci_disable_bridge_window(struct pc
    }
    #endif /* CONFIG_PCI_QUIRKS */

    -int pci_assign_resource(struct pci_dev *dev, int resno)
    +static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
    + int resno)
    {
    - struct pci_bus *bus = dev->bus;
    struct resource *res = dev->resource + resno;
    resource_size_t size, min, align;
    int ret;

    size = resource_size(res);
    min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
    -
    align = resource_alignment(res);
    - if (!align) {
    - dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
    - "alignment) %pR flags %#lx\n",
    - resno, res, res->flags);
    - return -EINVAL;
    - }

    /* First, try exact prefetching match.. */
    ret = pci_bus_alloc_resource(bus, res, size, align, min,
    @@ -169,10 +162,7 @@ int pci_assign_resource(struct pci_dev *
    pcibios_align_resource, dev);
    }

    - if (ret) {
    - dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
    - resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
    - } else {
    + if (!ret) {
    res->flags &= ~IORESOURCE_STARTALIGN;
    if (resno < PCI_BRIDGE_RESOURCES)
    pci_update_resource(dev, resno);
    @@ -180,6 +170,39 @@ int pci_assign_resource(struct pci_dev *

    return ret;
    }
    +
    +int pci_assign_resource(struct pci_dev *dev, int resno)
    +{
    + struct resource *res = dev->resource + resno;
    + resource_size_t align;
    + struct pci_bus *bus;
    + int ret;
    +
    + align = resource_alignment(res);
    + if (!align) {
    + dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
    + "alignment) %pR flags %#lx\n",
    + resno, res, res->flags);
    + return -EINVAL;
    + }
    +
    + bus = dev->bus;
    + while ((ret = __pci_assign_resource(bus, dev, resno))) {
    + if (bus->parent && bus->self->transparent)
    + bus = bus->parent;
    + else
    + bus = NULL;
    + if (bus)
    + continue;
    + break;
    + }
    +
    + if (ret)
    + dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
    + resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
    +
    + return ret;
    +}

    #if 0
    int pci_assign_resource_fixed(struct pci_dev *dev, int resno)

    \
     
     \ /
      Last update: 2009-04-24 05:55    [W:4.091 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site