|
@@ -1714,6 +1714,74 @@ err_out:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
|
|
|
+{
|
|
|
+ struct resource *res = &b->busn_res;
|
|
|
+ struct resource *parent_res, *conflict;
|
|
|
+
|
|
|
+ res->start = bus;
|
|
|
+ res->end = bus_max;
|
|
|
+ res->flags = IORESOURCE_BUS;
|
|
|
+
|
|
|
+ if (!pci_is_root_bus(b))
|
|
|
+ parent_res = &b->parent->busn_res;
|
|
|
+ else {
|
|
|
+ parent_res = get_pci_domain_busn_res(pci_domain_nr(b));
|
|
|
+ res->flags |= IORESOURCE_PCI_FIXED;
|
|
|
+ }
|
|
|
+
|
|
|
+ conflict = insert_resource_conflict(parent_res, res);
|
|
|
+
|
|
|
+ if (conflict)
|
|
|
+ dev_printk(KERN_DEBUG, &b->dev,
|
|
|
+ "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n",
|
|
|
+ res, pci_is_root_bus(b) ? "domain " : "",
|
|
|
+ parent_res, conflict->name, conflict);
|
|
|
+ else
|
|
|
+ dev_printk(KERN_DEBUG, &b->dev,
|
|
|
+ "busn_res: %pR is inserted under %s%pR\n",
|
|
|
+ res, pci_is_root_bus(b) ? "domain " : "",
|
|
|
+ parent_res);
|
|
|
+
|
|
|
+ return conflict == NULL;
|
|
|
+}
|
|
|
+
|
|
|
+int pci_bus_update_busn_res_end(struct pci_bus *b, int bus_max)
|
|
|
+{
|
|
|
+ struct resource *res = &b->busn_res;
|
|
|
+ struct resource old_res = *res;
|
|
|
+ resource_size_t size;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (res->start > bus_max)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ size = bus_max - res->start + 1;
|
|
|
+ ret = adjust_resource(res, res->start, size);
|
|
|
+ dev_printk(KERN_DEBUG, &b->dev,
|
|
|
+ "busn_res: %pR end %s updated to %02x\n",
|
|
|
+ &old_res, ret ? "can not be" : "is", bus_max);
|
|
|
+
|
|
|
+ if (!ret && !res->parent)
|
|
|
+ pci_bus_insert_busn_res(b, res->start, res->end);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+void pci_bus_release_busn_res(struct pci_bus *b)
|
|
|
+{
|
|
|
+ struct resource *res = &b->busn_res;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!res->flags || !res->parent)
|
|
|
+ return;
|
|
|
+
|
|
|
+ ret = release_resource(res);
|
|
|
+ dev_printk(KERN_DEBUG, &b->dev,
|
|
|
+ "busn_res: %pR %s released\n",
|
|
|
+ res, ret ? "can not be" : "is");
|
|
|
+}
|
|
|
+
|
|
|
struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
|
|
|
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
|
|
{
|