* [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 18:18 ` Alex Chiang
2010-01-21 6:14 ` [PATCH 2/9] pci: add failed_list to record failed one for pci_bus_assign_resources Yinghai Lu
` (7 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
so later we could use it to release small resource before pci assign unassign res
-v2: change name to release_child_resources according to Jesse
-v3: according to Linus, move release_child_resources to resource.c
also need to put the lock around them all to avoid recursive deep.
(my test case only have one level that need to be released)
-v4: seperate release_child_resources to another patch
according to Bjorn, change hard code 3 to PCI_BRIDGE_RESOURCE_END
-v5: remove unused in the name, and also use enum for release type according
to Jesse
-v6: use pci_is_root_bus instead acording to Alex.
-v7: remove the switch case in pci_bus_release_resources accord to Alex
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 52fbd42..5b42255 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -604,6 +604,91 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_assign_resources);
+static void pci_bridge_release_resources(struct pci_bus *bus,
+ unsigned long type)
+{
+ int idx;
+ bool changed = false;
+ struct pci_dev *dev;
+ struct resource *r;
+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+ IORESOURCE_PREFETCH;
+
+ dev = bus->self;
+ for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
+ idx++) {
+ r = &dev->resource[idx];
+ if ((r->flags & type_mask) != type)
+ continue;
+ if (!r->parent)
+ continue;
+ /*
+ * if there are children under that, we should release them
+ * all
+ */
+ release_child_resources(r);
+ if (!release_resource(r)) {
+ dev_printk(KERN_DEBUG, &dev->dev,
+ "resource %d %pR released\n", idx, r);
+ /* keep the old size */
+ r->end = resource_size(r) - 1;
+ r->start = 0;
+ r->flags = 0;
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ if (type & IORESOURCE_PREFETCH) {
+ /* avoiding touch the one without PREF */
+ type = IORESOURCE_PREFETCH;
+ }
+ __pci_setup_bridge(bus, type);
+ }
+}
+
+enum release_type {
+ leaf_only,
+ whole_subtree,
+};
+/*
+ * try to release pci bridge resources that is from leaf bridge,
+ * so we can allocate big new one later
+ */
+static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
+ unsigned long type,
+ enum release_type rel_type)
+{
+ struct pci_dev *dev;
+ bool is_leaf_bridge = true;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ struct pci_bus *b = dev->subordinate;
+ if (!b)
+ continue;
+
+ is_leaf_bridge = false;
+
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ continue;
+
+ if (rel_type == whole_subtree)
+ pci_bus_release_bridge_resources(b, type,
+ whole_subtree);
+ }
+
+ /* The root bus? */
+ if (pci_is_root_bus(bus))
+ return;
+
+ if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ return;
+
+ if (((rel_type == leaf_only) && is_leaf_bridge) ||
+ (rel_type == whole_subtree))
+ pci_bridge_release_resources(bus, type);
+}
+
static void pci_bus_dump_res(struct pci_bus *bus)
{
int i;
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res
2010-01-21 6:14 ` [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res Yinghai Lu
@ 2010-01-21 18:18 ` Alex Chiang
2010-01-21 19:47 ` Yinghai Lu
0 siblings, 1 reply; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 18:18 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
Sorry, this is getting into bike-shed territory.
I'm a lot happier with the code now, so may as well fix up a few
style issues before it goes in.
> +static void pci_bridge_release_resources(struct pci_bus *bus,
> + unsigned long type)
> +{
[...]
> + if (changed) {
> + if (type & IORESOURCE_PREFETCH) {
> + /* avoiding touch the one without PREF */
> + type = IORESOURCE_PREFETCH;
> + }
Strictly speaking, you don't need those curly braces. If you want
readability, how about moving the comment up?
/* Only setup prefetch resources */
if (type & IORESOURCE_PREFETCH)
type = IORESOURCE_PREFETCH;
> + __pci_setup_bridge(bus, type);
> + }
> +}
> +
> +static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
> + unsigned long type,
> + enum release_type rel_type)
> +{
[...]
> +
> + /* The root bus? */
Useless comment.
> + if (pci_is_root_bus(bus))
> + return;
> +
> + if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
> + return;
> +
> + if (((rel_type == leaf_only) && is_leaf_bridge) ||
> + (rel_type == whole_subtree))
> + pci_bridge_release_resources(bus, type);
> +}
Can clean this up a bit too with short-circuit logic.
if ((rel_type == whole_subtree) || is_leaf_bridge)
pci_bridge_release_resources(bus, type);
If you clean those up, you can add my:
Reviewed-by: Alex Chiang <achiang@hp.com>
> +
> static void pci_bus_dump_res(struct pci_bus *bus)
> {
> int i;
> --
> 1.6.4.2
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res
2010-01-21 18:18 ` Alex Chiang
@ 2010-01-21 19:47 ` Yinghai Lu
0 siblings, 0 replies; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 19:47 UTC (permalink / raw)
To: Alex Chiang
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
On 01/21/2010 10:18 AM, Alex Chiang wrote:
>
> Sorry, this is getting into bike-shed territory.
>
> I'm a lot happier with the code now, so may as well fix up a few
> style issues before it goes in.
>
>> +static void pci_bridge_release_resources(struct pci_bus *bus,
>> + unsigned long type)
>> +{
>
> [...]
>
>> + if (changed) {
>> + if (type & IORESOURCE_PREFETCH) {
>> + /* avoiding touch the one without PREF */
>> + type = IORESOURCE_PREFETCH;
>> + }
>
> Strictly speaking, you don't need those curly braces. If you want
> readability, how about moving the comment up?
>
> /* Only setup prefetch resources */
> if (type & IORESOURCE_PREFETCH)
> type = IORESOURCE_PREFETCH;
>
>
>> + __pci_setup_bridge(bus, type);
>> + }
>> +}
>> +
>> +static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus,
>> + unsigned long type,
>> + enum release_type rel_type)
>> +{
>
> [...]
>
>> +
>> + /* The root bus? */
>
> Useless comment.
>
>> + if (pci_is_root_bus(bus))
>> + return;
>> +
>> + if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI)
>> + return;
>> +
>> + if (((rel_type == leaf_only) && is_leaf_bridge) ||
>> + (rel_type == whole_subtree))
>> + pci_bridge_release_resources(bus, type);
>> +}
>
> Can clean this up a bit too with short-circuit logic.
>
> if ((rel_type == whole_subtree) || is_leaf_bridge)
> pci_bridge_release_resources(bus, type);
>
> If you clean those up, you can add my:
>
> Reviewed-by: Alex Chiang <achiang@hp.com>
ok thanks.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/9] pci: add failed_list to record failed one for pci_bus_assign_resources
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
2010-01-21 6:14 ` [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 20:41 ` Alex Chiang
2010-01-21 6:14 ` [PATCH 3/9] pci: reject mmio range start from 0 on pci_bridge read Yinghai Lu
` (6 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
so later we can try to assign resource those failed devices again.
-v2: store start, end, flags aside. so could keep res cleared when assign
failed. and make following assignment of its children do not go wild
-v3: update comments
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 66 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 5b42255..41578ba 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -27,7 +27,52 @@
#include <linux/slab.h>
#include "pci.h"
-static void pbus_assign_resources_sorted(const struct pci_bus *bus)
+struct resource_list_x {
+ struct resource_list_x *next;
+ struct resource *res;
+ struct pci_dev *dev;
+ resource_size_t start;
+ resource_size_t end;
+ unsigned long flags;
+};
+
+static void add_to_failed_list(struct resource_list_x *head,
+ struct pci_dev *dev, struct resource *res)
+{
+ struct resource_list_x *list = head;
+ struct resource_list_x *ln = list->next;
+ struct resource_list_x *tmp;
+
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+ if (!tmp) {
+ pr_warning("add_to_failed_list: kmalloc() failed!\n");
+ return;
+ }
+
+ tmp->next = ln;
+ tmp->res = res;
+ tmp->dev = dev;
+ tmp->start = res->start;
+ tmp->end = res->end;
+ tmp->flags = res->flags;
+ list->next = tmp;
+}
+
+static void free_failed_list(struct resource_list_x *head)
+{
+ struct resource_list_x *list, *tmp;
+
+ for (list = head->next; list;) {
+ tmp = list;
+ list = list->next;
+ kfree(tmp);
+ }
+
+ head->next = NULL;
+}
+
+static void pbus_assign_resources_sorted(const struct pci_bus *bus,
+ struct resource_list_x *fail_head)
{
struct pci_dev *dev;
struct resource *res;
@@ -58,6 +103,13 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
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 next try
+ */
+ add_to_failed_list(fail_head, list->dev, res);
+ }
res->start = 0;
res->end = 0;
res->flags = 0;
@@ -572,19 +624,20 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_size_bridges);
-void __ref pci_bus_assign_resources(const struct pci_bus *bus)
+static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
+ struct resource_list_x *fail_head)
{
struct pci_bus *b;
struct pci_dev *dev;
- pbus_assign_resources_sorted(bus);
+ pbus_assign_resources_sorted(bus, fail_head);
list_for_each_entry(dev, &bus->devices, bus_list) {
b = dev->subordinate;
if (!b)
continue;
- pci_bus_assign_resources(b);
+ __pci_bus_assign_resources(b, fail_head);
switch (dev->class >> 8) {
case PCI_CLASS_BRIDGE_PCI:
@@ -602,6 +655,11 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus)
}
}
}
+
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
+{
+ __pci_bus_assign_resources(bus, NULL);
+}
EXPORT_SYMBOL(pci_bus_assign_resources);
static void pci_bridge_release_resources(struct pci_bus *bus,
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 2/9] pci: add failed_list to record failed one for pci_bus_assign_resources
2010-01-21 6:14 ` [PATCH 2/9] pci: add failed_list to record failed one for pci_bus_assign_resources Yinghai Lu
@ 2010-01-21 20:41 ` Alex Chiang
0 siblings, 0 replies; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 20:41 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
More bike shedding.
* Yinghai Lu <yinghai@kernel.org>:
> @@ -58,6 +103,13 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
> 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 next try
> + */
> + add_to_failed_list(fail_head, list->dev, res);
> + }
I don't really think you need that comment, so just strike it
completely and drop the curly braces.
if (fail_head && !pci_is_root_bus(list->dev->bus))
add_to_failed_list(fail_head, list->dev, res);
Reviewed-by: Alex Chiang <achiang@hp.com>
/ac
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/9] pci: reject mmio range start from 0 on pci_bridge read
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
2010-01-21 6:14 ` [PATCH 1/9] pci: add pci_bridge_release_unused_res and pci_bus_release_unused_bridge_res Yinghai Lu
2010-01-21 6:14 ` [PATCH 2/9] pci: add failed_list to record failed one for pci_bus_assign_resources Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 6:14 ` [PATCH 4/9] pci: don't shrink bridge resources Yinghai Lu
` (5 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
only need to set the value to resource.
also could keep the old setting in resource for prevent shrink bridge
resources.
-v2: change to "bar reading" to "reg reading"
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/probe.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 11824d7..8cd4fb3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -316,13 +316,17 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
limit |= (io_limit_hi << 16);
}
- if (base <= limit) {
+ if (base && base <= limit) {
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
if (!res->start)
res->start = base;
if (!res->end)
res->end = limit + 0xfff;
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ } else {
+ dev_printk(KERN_DEBUG, &dev->dev,
+ " bridge window [io %04lx - %04lx] reg reading\n",
+ base, limit);
}
res = child->resource[1];
@@ -330,11 +334,15 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
- if (base <= limit) {
+ if (base && base <= limit) {
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base;
res->end = limit + 0xfffff;
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ } else {
+ dev_printk(KERN_DEBUG, &dev->dev,
+ " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
+ base, limit + 0xfffff);
}
res = child->resource[2];
@@ -366,7 +374,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
#endif
}
}
- if (base <= limit) {
+ if (base && base <= limit) {
res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
IORESOURCE_MEM | IORESOURCE_PREFETCH;
if (res->flags & PCI_PREF_RANGE_TYPE_64)
@@ -374,6 +382,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->start = base;
res->end = limit + 0xfffff;
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ } else {
+ dev_printk(KERN_DEBUG, &dev->dev,
+ " bridge window [mem 0x%08lx - %08lx pref] reg reading\n",
+ base, limit + 0xfffff);
}
}
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 4/9] pci: don't shrink bridge resources
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (2 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 3/9] pci: reject mmio range start from 0 on pci_bridge read Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 6:14 ` [PATCH 5/9] pci: update bridge res to get more big range in pci assign unssign Yinghai Lu
` (4 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
when we are clearing leaf bridge resource and try to get big one, we could
shrink the bridge if there is no resource under it.
let check with old resource size and make sure we are trying to get big one.
-v2: keep disable window print out, still could happen on non pci hotplug system
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 41578ba..76b2d0b 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -387,7 +387,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
{
struct pci_dev *dev;
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
- unsigned long size = 0, size1 = 0;
+ unsigned long size = 0, size1 = 0, old_size;
if (!b_res)
return;
@@ -412,12 +412,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
}
if (size < min_size)
size = min_size;
+ old_size = resource_size(b_res);
+ if (old_size == 1)
+ old_size = 0;
/* To be fixed in 2.5: we should have sort of HAVE_ISA
flag in the struct pci_bus. */
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
size = (size & 0xff) + ((size & ~0xffUL) << 2);
#endif
size = ALIGN(size + size1, 4096);
+ if (size < old_size)
+ size = old_size;
if (!size) {
if (b_res->start || b_res->end)
dev_info(&bus->self->dev, "disabling bridge window "
@@ -438,7 +443,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
unsigned long type, resource_size_t min_size)
{
struct pci_dev *dev;
- resource_size_t min_align, align, size;
+ resource_size_t min_align, align, size, old_size;
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type);
@@ -488,6 +493,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
}
if (size < min_size)
size = min_size;
+ old_size = resource_size(b_res);
+ if (old_size == 1)
+ old_size = 0;
+ if (size < old_size)
+ size = old_size;
align = 0;
min_align = 0;
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 5/9] pci: update bridge res to get more big range in pci assign unssign
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (3 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 4/9] pci: don't shrink bridge resources Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 6:14 ` [PATCH 6/9] pci: introduce pci_assign_unassigned_bridge_resources Yinghai Lu
` (3 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
BIOS separate IO range between several IOHs, and on some slots, BIOS assign the
resource to the bridge, but stop assigning resource to the device under that
bridge, because the device need big resource.
1. pci assign unassign and record the failed device resource.
2. clear the BIOS assigned resource of the parent bridge of fail device
3. go back and call pci assign unsigned
4. if it still fail, will go up more bridges. and clear and try again.
use pci_try_num to control back track bridge levels.
-v2: update it with resource_list_x
-v3: make pci_try_num default to 1. and when pci_try_num is set to more than 1
will check it with max_depth, and adjust that to make sure it is bigger
enough
-v4: update to enum release_type and _used_calling
-v5: seems all doesn't like pci=try=N at this point, let remove it at first
-v6: fix typo about restore ...
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 76b2d0b..eea53f2 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -788,11 +788,65 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
}
}
+static int __init pci_bus_get_depth(struct pci_bus *bus)
+{
+ int depth = 0;
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ int ret;
+ struct pci_bus *b = dev->subordinate;
+ if (!b)
+ continue;
+
+ ret = pci_bus_get_depth(b);
+ if (ret + 1 > depth)
+ depth = ret + 1;
+ }
+
+ return depth;
+}
+static int __init pci_get_max_depth(void)
+{
+ int depth = 0;
+ struct pci_bus *bus;
+
+ list_for_each_entry(bus, &pci_root_buses, node) {
+ int ret;
+
+ ret = pci_bus_get_depth(bus);
+ if (ret > depth)
+ depth = ret;
+ }
+
+ return depth;
+}
+
+/*
+ * first try will not touch pci bridge res
+ * second and later try will clear small leaf bridge res
+ * will stop till to the max deepth if can not find good one
+ */
void __init
pci_assign_unassigned_resources(void)
{
struct pci_bus *bus;
+ int tried_times = 0;
+ enum release_type rel_type = leaf_only;
+ struct resource_list_x head, *list;
+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+ IORESOURCE_PREFETCH;
+ unsigned long failed_type;
+ int max_depth = pci_get_max_depth();
+ int pci_try_num;
+
+ head.next = NULL;
+ pci_try_num = max_depth + 1;
+ printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
+ max_depth, pci_try_num);
+
+again:
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
list_for_each_entry(bus, &pci_root_buses, node) {
@@ -800,9 +854,65 @@ pci_assign_unassigned_resources(void)
}
/* Depth last, allocate resources and update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node) {
- pci_bus_assign_resources(bus);
- pci_enable_bridges(bus);
+ __pci_bus_assign_resources(bus, &head);
+ }
+ tried_times++;
+
+ /* any device complain? */
+ if (!head.next)
+ goto enable_and_dump;
+ failed_type = 0;
+ for (list = head.next; list;) {
+ failed_type |= list->flags;
+ list = list->next;
+ }
+ /*
+ * io port are tight, don't try extra
+ * or if reach the limit, don't want to try more
+ */
+ failed_type &= type_mask;
+ if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
+ free_failed_list(&head);
+ goto enable_and_dump;
+ }
+
+ printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
+ tried_times + 1);
+
+ /* third times and later will not check if it is leaf */
+ if ((tried_times + 1) > 2)
+ rel_type = whole_subtree;
+
+ /*
+ * Try to release leaf bridge's resources that doesn't fit resource of
+ * child device under that bridge
+ */
+ for (list = head.next; list;) {
+ bus = list->dev->bus;
+ pci_bus_release_bridge_resources(bus, list->flags & type_mask,
+ rel_type);
+ list = list->next;
}
+ /* restore size and flags */
+ for (list = head.next; list;) {
+ struct resource *res = list->res;
+
+ res->start = list->start;
+ res->end = list->end;
+ res->flags = list->flags;
+ if (list->dev->subordinate)
+ res->flags = 0;
+
+ list = list->next;
+ }
+ free_failed_list(&head);
+
+ goto again;
+
+enable_and_dump:
+ /* Depth last, update the hardware. */
+ list_for_each_entry(bus, &pci_root_buses, node)
+ pci_enable_bridges(bus);
/* dump the resource on buses */
list_for_each_entry(bus, &pci_root_buses, node) {
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 6/9] pci: introduce pci_assign_unassigned_bridge_resources
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (4 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 5/9] pci: update bridge res to get more big range in pci assign unssign Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 21:02 ` Alex Chiang
2010-01-21 6:14 ` [PATCH 7/9] pci: pciehp clean flow in pciehp_configure_device Yinghai Lu
` (2 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
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.
-v2: update it with resource_list_x
-v3: remove the clear busmaster. according to Kenji
-v4: make pdev_assign_resources_sorted and pbus_assign_resources_sorted share two small functions
according to Alex.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 118 +++++++++++++++++++++++++++++++++++-----------
include/linux/pci.h | 1 +
2 files changed, 91 insertions(+), 28 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index eea53f2..8bec70f 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -71,42 +71,41 @@ static void free_failed_list(struct resource_list_x *head)
head->next = NULL;
}
-static void pbus_assign_resources_sorted(const struct pci_bus *bus,
- struct resource_list_x *fail_head)
+static void __dev_sort_resources(struct pci_dev *dev,
+ struct resource_list *head)
{
- struct pci_dev *dev;
- struct resource *res;
- struct resource_list head, *list, *tmp;
- int idx;
+ u16 class = dev->class >> 8;
- head.next = NULL;
- list_for_each_entry(dev, &bus->devices, bus_list) {
- u16 class = dev->class >> 8;
+ /* 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 classless devices or host bridges or ioapics. */
- if (class == PCI_CLASS_NOT_DEFINED ||
- class == PCI_CLASS_BRIDGE_HOST)
- continue;
+ /* 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;
+ }
- /* 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))
- continue;
- }
+ pdev_sort_resources(dev, head);
+}
- pdev_sort_resources(dev, &head);
- }
+static void __assign_resources_sorted(struct resource_list *head,
+ struct resource_list_x *fail_head)
+{
+ struct resource *res;
+ struct resource_list *list, *tmp;
+ int idx;
- for (list = head.next; list;) {
+ 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 next try
+ * for second try
*/
add_to_failed_list(fail_head, list->dev, res);
}
@@ -120,6 +119,30 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus,
}
}
+static void pdev_assign_resources_sorted(struct pci_dev *dev,
+ struct resource_list_x *fail_head)
+{
+ struct resource_list head;
+
+ head.next = NULL;
+ __dev_sort_resources(dev, &head);
+ __assign_resources_sorted(&head, fail_head);
+
+}
+
+static void pbus_assign_resources_sorted(const struct pci_bus *bus,
+ struct resource_list_x *fail_head)
+{
+ struct pci_dev *dev;
+ struct resource_list head;
+
+ head.next = NULL;
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ __dev_sort_resources(dev, &head);
+
+ __assign_resources_sorted(&head, fail_head);
+}
+
void pci_setup_cardbus(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
@@ -278,9 +301,6 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
{
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);
@@ -651,7 +671,8 @@ static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
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:
@@ -672,6 +693,34 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_assign_resources);
+static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
+ struct resource_list_x *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 pci_bridge_release_resources(struct pci_bus *bus,
unsigned long type)
{
@@ -919,3 +968,16 @@ enable_and_dump:
pci_bus_dump_resources(bus);
}
}
+
+void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
+{
+ struct pci_bus *parent = bridge->subordinate;
+ int retval;
+
+ pci_bus_size_bridges(parent);
+ __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);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6b2949c..0e240ed 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -806,6 +806,7 @@ void pci_bus_assign_resources(const struct pci_bus *bus);
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);
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 6/9] pci: introduce pci_assign_unassigned_bridge_resources
2010-01-21 6:14 ` [PATCH 6/9] pci: introduce pci_assign_unassigned_bridge_resources Yinghai Lu
@ 2010-01-21 21:02 ` Alex Chiang
0 siblings, 0 replies; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 21:02 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
* Yinghai Lu <yinghai@kernel.org>:
> 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.
>
> -v2: update it with resource_list_x
> -v3: remove the clear busmaster. according to Kenji
> -v4: make pdev_assign_resources_sorted and pbus_assign_resources_sorted share two small functions
> according to Alex.
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Reviewed-by: Alex Chiang <achiang@hp.com>
But it would be great if Kenji-san could actually get some test
cycles on this.
/ac
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 7/9] pci: pciehp clean flow in pciehp_configure_device
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (5 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 6/9] pci: introduce pci_assign_unassigned_bridge_resources Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 21:15 ` Alex Chiang
2010-01-21 6:14 ` [PATCH 8/9] pci: pciehp second try to get big range for pcie devices Yinghai Lu
2010-01-21 6:14 ` [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges Yinghai Lu
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
move out bus_size_bridges and assign resources out of pciehp_add_bridge()
and at last do them all together one time including slot bridge, to avoid to
call assign resources several times, when there are several bridges under the
slot bridge.
use pci_assign_nassigned_bridge_resources
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/hotplug/pciehp_pci.c | 23 +++++++++++++++++------
1 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 2173310..0a16444 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev)
busnr = pci_scan_bridge(parent, dev, busnr, pass);
if (!dev->subordinate)
return -1;
- pci_bus_size_bridges(dev->subordinate);
- pci_bus_assign_resources(parent);
- pci_enable_bridges(parent);
- pci_bus_add_devices(parent);
+
return 0;
}
int pciehp_configure_device(struct slot *p_slot)
{
struct pci_dev *dev;
- struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
+ struct pci_dev *bridge = p_slot->ctrl->pcie->port;
+ struct pci_bus *parent = bridge->subordinate;
int num, fn;
struct controller *ctrl = p_slot->ctrl;
@@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot *p_slot)
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
pciehp_add_bridge(dev);
}
+ pci_dev_put(dev);
+ }
+
+ pci_assign_unassigned_bridge_resources(bridge);
+
+ for (fn = 0; fn < 8; fn++) {
+ dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+ if (!dev)
+ continue;
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ pci_dev_put(dev);
+ continue;
+ }
pci_configure_slot(dev);
pci_dev_put(dev);
}
- pci_bus_assign_resources(parent);
pci_bus_add_devices(parent);
+
return 0;
}
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 7/9] pci: pciehp clean flow in pciehp_configure_device
2010-01-21 6:14 ` [PATCH 7/9] pci: pciehp clean flow in pciehp_configure_device Yinghai Lu
@ 2010-01-21 21:15 ` Alex Chiang
0 siblings, 0 replies; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 21:15 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
* Yinghai Lu <yinghai@kernel.org>:
> move out bus_size_bridges and assign resources out of pciehp_add_bridge()
> and at last do them all together one time including slot bridge, to avoid to
> call assign resources several times, when there are several bridges under the
> slot bridge.
> use pci_assign_nassigned_bridge_resources
Typo in the changelog: use pci_assign_unassigned_bridge_resources
This is another good one for Kenji-san to test.
Reviewed-by: Alex Chiang <achiang@hp.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 8/9] pci: pciehp second try to get big range for pcie devices
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (6 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 7/9] pci: pciehp clean flow in pciehp_configure_device Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 21:22 ` Alex Chiang
2010-01-21 6:14 ` [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges Yinghai Lu
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
handle the case the slot bridge that doesn't get pre-allocated big enough
resources from FW.
for example pcie devices need 256M, but the bridge only get preallocated 2M...
-v2: use resource_list_x
-v3: use tried_times instead of second tried...
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8bec70f..a9c4f9e 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -972,12 +972,62 @@ enable_and_dump:
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
{
struct pci_bus *parent = bridge->subordinate;
+ int tried_times = 0;
+ struct resource_list_x head, *list;
int retval;
+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+ IORESOURCE_PREFETCH;
+
+ head.next = NULL;
+again:
pci_bus_size_bridges(parent);
- __pci_bridge_assign_resources(bridge, NULL);
+ __pci_bridge_assign_resources(bridge, &head);
retval = pci_reenable_device(bridge);
pci_set_master(bridge);
pci_enable_bridges(parent);
+
+ tried_times++;
+
+ /* any device complain? */
+ if (!head.next)
+ return;
+
+ if (tried_times >= 2) {
+ /* still fail, don't need to try more */
+ free_failed_list(&head);
+ return;
+ }
+
+ printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
+ tried_times + 1);
+
+ /*
+ * Try to release leaf bridge's resources that doesn't fit resource of
+ * child device under that bridge
+ */
+ for (list = head.next; list;) {
+ struct pci_bus *bus = list->dev->bus;
+ unsigned long flags = list->flags;
+
+ pci_bus_release_bridge_resources(bus, flags & type_mask,
+ whole_subtree);
+ list = list->next;
+ }
+ /* retore size and flags */
+ for (list = head.next; list;) {
+ struct resource *res = list->res;
+
+ res->start = list->start;
+ res->end = list->end;
+ res->flags = list->flags;
+ if (list->dev->subordinate)
+ res->flags = 0;
+
+ list = list->next;
+ }
+ free_failed_list(&head);
+
+ goto again;
}
EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 8/9] pci: pciehp second try to get big range for pcie devices
2010-01-21 6:14 ` [PATCH 8/9] pci: pciehp second try to get big range for pcie devices Yinghai Lu
@ 2010-01-21 21:22 ` Alex Chiang
0 siblings, 0 replies; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 21:22 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
> void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
> {
> struct pci_bus *parent = bridge->subordinate;
> + int tried_times = 0;
> + struct resource_list_x head, *list;
> int retval;
> + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
> + IORESOURCE_PREFETCH;
> +
> + head.next = NULL;
>
> +again:
> pci_bus_size_bridges(parent);
> - __pci_bridge_assign_resources(bridge, NULL);
> + __pci_bridge_assign_resources(bridge, &head);
> retval = pci_reenable_device(bridge);
> pci_set_master(bridge);
> pci_enable_bridges(parent);
> +
> + tried_times++;
> +
> + /* any device complain? */
useless comment.
> + if (!head.next)
> + return;
> +
> + if (tried_times >= 2) {
stray space
> + /* still fail, don't need to try more */
useless comment
> + free_failed_list(&head);
> + return;
> + }
> +
> + printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
> + tried_times + 1);
> +
> + /*
> + * Try to release leaf bridge's resources that doesn't fit resource of
> + * child device under that bridge
> + */
> + for (list = head.next; list;) {
> + struct pci_bus *bus = list->dev->bus;
> + unsigned long flags = list->flags;
> +
> + pci_bus_release_bridge_resources(bus, flags & type_mask,
> + whole_subtree);
> + list = list->next;
> + }
> + /* retore size and flags */
"restore"
/ac
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges
2010-01-21 6:14 [PATCH 0/9] pci: update pci bridge resources Yinghai Lu
` (7 preceding siblings ...)
2010-01-21 6:14 ` [PATCH 8/9] pci: pciehp second try to get big range for pcie devices Yinghai Lu
@ 2010-01-21 6:14 ` Yinghai Lu
2010-01-21 21:32 ` Alex Chiang
8 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 6:14 UTC (permalink / raw)
To: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Alex Chiang, Bjorn Helgaas
Cc: linux-kernel, linux-pci, Yinghai Lu
make pci_bridge_check_ranges() to store the PCI_PREF_RANGE_TYPE_64 in addition
to IORESOURCE_MEM_64. just like pci_read_bridge_bases()
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a9c4f9e..8fafe73 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -359,8 +359,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
}
if (pmem) {
b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
- if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
+ if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
+ PCI_PREF_RANGE_TYPE_64) {
b_res[2].flags |= IORESOURCE_MEM_64;
+ b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
+ }
}
/* double check if bridge does support 64 bit pref */
--
1.6.4.2
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges
2010-01-21 6:14 ` [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges Yinghai Lu
@ 2010-01-21 21:32 ` Alex Chiang
2010-01-21 21:53 ` Yinghai Lu
0 siblings, 1 reply; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 21:32 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
* Yinghai Lu <yinghai@kernel.org>:
> make pci_bridge_check_ranges() to store the
> PCI_PREF_RANGE_TYPE_64 in addition to IORESOURCE_MEM_64. just
> like pci_read_bridge_bases()
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
> drivers/pci/setup-bus.c | 5 ++++-
> 1 files changed, 4 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index a9c4f9e..8fafe73 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -359,8 +359,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
> }
> if (pmem) {
> b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
> - if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
> + if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
> + PCI_PREF_RANGE_TYPE_64) {
> b_res[2].flags |= IORESOURCE_MEM_64;
> + b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
> + }
> }
My copy of pci_read_bridge_bases() in jbarnes's linux-next tree
doesn't do anything like that.
284 void __devinit pci_read_bridge_bases(struct pci_bus *child)
285 {
...
369 if (base <= limit) {
370 res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
371 IORESOURCE_MEM | IORESOURCE_PREFETCH;
372 if (res->flags & PCI_PREF_RANGE_TYPE_64)
373 res->flags |= IORESOURCE_MEM_64;
374 res->start = base;
375 res->end = limit + 0xfffff;
376 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
377 }
What's going on?
/ac
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges
2010-01-21 21:32 ` Alex Chiang
@ 2010-01-21 21:53 ` Yinghai Lu
2010-01-21 22:09 ` Alex Chiang
0 siblings, 1 reply; 19+ messages in thread
From: Yinghai Lu @ 2010-01-21 21:53 UTC (permalink / raw)
To: Alex Chiang
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
On 01/21/2010 01:32 PM, Alex Chiang wrote:
> * Yinghai Lu <yinghai@kernel.org>:
>> make pci_bridge_check_ranges() to store the
>> PCI_PREF_RANGE_TYPE_64 in addition to IORESOURCE_MEM_64. just
>> like pci_read_bridge_bases()
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>> drivers/pci/setup-bus.c | 5 ++++-
>> 1 files changed, 4 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
>> index a9c4f9e..8fafe73 100644
>> --- a/drivers/pci/setup-bus.c
>> +++ b/drivers/pci/setup-bus.c
>> @@ -359,8 +359,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
>> }
>> if (pmem) {
>> b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
>> - if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
>> + if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
>> + PCI_PREF_RANGE_TYPE_64) {
>> b_res[2].flags |= IORESOURCE_MEM_64;
>> + b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
here set PCI_PREF_RANGE_TYPE_64 too.
>> + }
>> }
>
> My copy of pci_read_bridge_bases() in jbarnes's linux-next tree
> doesn't do anything like that.
>
> 284 void __devinit pci_read_bridge_bases(struct pci_bus *child)
> 285 {
> ...
> 369 if (base <= limit) {
> 370 res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
> 371 IORESOURCE_MEM | IORESOURCE_PREFETCH;
so it could save PCI_PREF_RANGE_TYPE_64 here.
> 372 if (res->flags & PCI_PREF_RANGE_TYPE_64)
> 373 res->flags |= IORESOURCE_MEM_64;
> 374 res->start = base;
> 375 res->end = limit + 0xfffff;
> 376 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
> 377 }
YH
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 9/9] pci: set PCI_PREF_RANGE_TYPE_64 in pci_bridge_check_ranges
2010-01-21 21:53 ` Yinghai Lu
@ 2010-01-21 22:09 ` Alex Chiang
0 siblings, 0 replies; 19+ messages in thread
From: Alex Chiang @ 2010-01-21 22:09 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, Ingo Molnar, Linus Torvalds, Ivan Kokshaysky,
Kenji Kaneshige, Bjorn Helgaas, linux-kernel, linux-pci
* Yinghai Lu <yinghai@kernel.org>:
> On 01/21/2010 01:32 PM, Alex Chiang wrote:
> >> @@ -359,8 +359,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
> >> }
> >> if (pmem) {
> >> b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
> >> - if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
> >> + if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
> >> + PCI_PREF_RANGE_TYPE_64) {
> >> b_res[2].flags |= IORESOURCE_MEM_64;
> >> + b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
> here set PCI_PREF_RANGE_TYPE_64 too.
> >> + }
> >> }
> >
> > My copy of pci_read_bridge_bases() in jbarnes's linux-next tree
> > doesn't do anything like that.
> >
> > 284 void __devinit pci_read_bridge_bases(struct pci_bus *child)
> > 285 {
> > ...
> > 369 if (base <= limit) {
> > 370 res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
> > 371 IORESOURCE_MEM | IORESOURCE_PREFETCH;
> so it could save PCI_PREF_RANGE_TYPE_64 here.
> > 372 if (res->flags & PCI_PREF_RANGE_TYPE_64)
> > 373 res->flags |= IORESOURCE_MEM_64;
> > 374 res->start = base;
> > 375 res->end = limit + 0xfffff;
> > 376 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
> > 377 }
Hm, ok. Thanks for pointing it out.
/ac
^ permalink raw reply [flat|nested] 19+ messages in thread