@@ -412,14 +412,14 @@ 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, old_size;
+ unsigned long size = 0, size1 = 0, old_size, dev_present=0;
if (!b_res)
return;
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
-
+ dev_present=1;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
unsigned long r_size;
@@ -460,6 +460,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
b_res->start = 4096;
b_res->end = b_res->start + size - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
+
+ /* if no devices are behind this bus, inform
+ * resource-allocater to try hard but not to worry
+ * if allocations fail
+ */
+ b_res->flags |= (!dev_present) ? IORESOURCE_IGNORE_FAIL : 0;
}
/* Calculate the size of the bus and minimal alignment which
@@ -470,7 +476,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
struct pci_dev *dev;
resource_size_t min_align, align, size, old_size;
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
- int order, max_order;
+ int order, max_order, dev_present=0;
struct resource *b_res = find_free_bus_resource(bus, type);
unsigned int mem64_mask = 0;
@@ -487,6 +493,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
+ dev_present=1;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
resource_size_t r_size;
@@ -550,6 +557,13 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
b_res->end = size + min_align - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
b_res->flags |= mem64_mask;
+
+ /* if no devices are behind this bus, inform
+ * resource-allocater to try hard but not to worry
+ * if allocations fail
+ */
+ b_res->flags |= (!dev_present) ? IORESOURCE_IGNORE_FAIL : 0;
+
return 1;
}
@@ -210,7 +210,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
if (!align) {
dev_info(&dev->dev, "BAR %d: can't assign %pR "
"(bogus alignment)\n", resno, res);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
bus = dev->bus;
@@ -225,6 +226,10 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
}
if (ret) {
+ if (res->flags & IORESOURCE_IGNORE_FAIL) {
+ ret = 0;
+ goto out;
+ }
if (res->flags & IORESOURCE_MEM)
if (res->flags & IORESOURCE_PREFETCH)
type = "mem pref";
@@ -239,6 +244,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
resno, type, (unsigned long long) resource_size(res));
}
+out:
+ res->flags &= ~IORESOURCE_IGNORE_FAIL;
return ret;
}
@@ -49,6 +49,7 @@ struct resource_list {
#define IORESOURCE_SIZEALIGN 0x00040000 /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */
+#define IORESOURCE_IGNORE_FAIL 0x00800000 /* IGNORE if allocation fail*/
#define IORESOURCE_MEM_64 0x00100000
#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */