lkml.org 
[lkml]   [2009]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 7/9] pci: introduce pci_assign_unassigned_bridge_resources

    for pciehp to use it later

    pci_setup_bridge() will not check enabled for the slot bridge, otherwise
    update res is not updated to bridge BAR. that is bridge is enabled already for
    port service.

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

    ---
    drivers/pci/setup-bus.c | 94 +++++++++++++++++++++++++++++++++++++++++++++---
    include/linux/pci.h | 1
    2 files changed, 91 insertions(+), 4 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
    @@ -68,6 +68,51 @@ static void free_failed_list(struct reso
    head->next = NULL;
    }

    +static void pdev_assign_resources_sorted(struct pci_dev *dev,
    + struct resource_list *fail_head)
    +{
    + struct resource *res;
    + struct resource_list head, *list, *tmp;
    + int idx;
    + u16 class = dev->class >> 8;
    +
    + head.next = NULL;
    +
    + /* Don't touch classless devices or host bridges or ioapics. */
    + if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
    + return;
    +
    + /* Don't touch ioapic devices already enabled by firmware */
    + if (class == PCI_CLASS_SYSTEM_PIC) {
    + u16 command;
    + pci_read_config_word(dev, PCI_COMMAND, &command);
    + if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
    + return;
    + }
    +
    + pdev_sort_resources(dev, &head);
    +
    + for (list = head.next; list;) {
    + res = list->res;
    + idx = res - &list->dev->resource[0];
    + if (pci_assign_resource(list->dev, idx)) {
    + if (fail_head && !pci_is_root_bus(list->dev->bus)) {
    + /*
    + * device need to keep flags and size
    + * for second try
    + */
    + add_to_failed_list(fail_head, list->dev, res);
    + } else {
    + res->start = 0;
    + res->end = 0;
    + res->flags = 0;
    + }
    + }
    + tmp = list;
    + list = list->next;
    + kfree(tmp);
    + }
    +}
    static void pbus_assign_resources_sorted(const struct pci_bus *bus,
    struct resource_list *fail_head)
    {
    @@ -281,9 +326,6 @@ static void __pci_setup_bridge(struct pc
    {
    struct pci_dev *bridge = bus->self;

    - if (pci_is_enabled(bridge))
    - return;
    -
    dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
    bus->secondary, bus->subordinate);

    @@ -646,7 +688,8 @@ static void __ref __pci_bus_assign_resou

    switch (dev->class >> 8) {
    case PCI_CLASS_BRIDGE_PCI:
    - pci_setup_bridge(b);
    + if (!pci_is_enabled(dev))
    + pci_setup_bridge(b);
    break;

    case PCI_CLASS_BRIDGE_CARDBUS:
    @@ -667,6 +710,34 @@ void __ref pci_bus_assign_resources(cons
    }
    EXPORT_SYMBOL(pci_bus_assign_resources);

    +static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
    + struct resource_list *fail_head)
    +{
    + struct pci_bus *b;
    +
    + pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
    +
    + b = bridge->subordinate;
    + if (!b)
    + return;
    +
    + __pci_bus_assign_resources(b, fail_head);
    +
    + switch (bridge->class >> 8) {
    + case PCI_CLASS_BRIDGE_PCI:
    + pci_setup_bridge(b);
    + break;
    +
    + case PCI_CLASS_BRIDGE_CARDBUS:
    + pci_setup_cardbus(b);
    + break;
    +
    + default:
    + dev_info(&bridge->dev, "not setting up bridge for bus "
    + "%04x:%02x\n", pci_domain_nr(b), b->number);
    + break;
    + }
    +}
    static void release_children_resource(struct resource *r)
    {
    struct resource *p;
    @@ -894,3 +965,18 @@ enable_and_dump:
    pci_bus_dump_resources(bus);
    }
    }
    +
    +void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
    +{
    + struct pci_bus *bus;
    + struct pci_bus *parent = bridge->subordinate;
    + int retval;
    +
    + pci_bus_size_bridges(parent);
    + pci_clear_master(bridge);
    + __pci_bridge_assign_resources(bridge, NULL);
    + retval = pci_reenable_device(bridge);
    + pci_set_master(bridge);
    + pci_enable_bridges(parent);
    +}
    +EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
    Index: linux-2.6/include/linux/pci.h
    ===================================================================
    --- linux-2.6.orig/include/linux/pci.h
    +++ linux-2.6/include/linux/pci.h
    @@ -768,6 +768,7 @@ void pci_bus_assign_resources(const stru
    void pci_bus_size_bridges(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);
    void pdev_enable_device(struct pci_dev *);
    void pdev_sort_resources(struct pci_dev *, struct resource_list *);
    int pci_enable_resources(struct pci_dev *, int mask);


    \
     
     \ /
      Last update: 2009-11-25 21:05    [W:0.039 / U:61.840 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site