Merge branch 'topic/yinghai-busn-alloc' into next
* topic/yinghai-busn-alloc: (33 commits) PCI: hotplug: remove pci_do_scan_bus() PCI: sgihp: use generic pci_hp_add_bridge() PCI: ibmhp: use generic pci_hp_add_bridge() PCI: cpqhp: use generic pci_hp_add_bridge() PCI: shpchp: use generic pci_hp_add_bridge() PCI: cpci_hotplug: use generic pci_hp_add_bridge() PCI: pciehp: use generic pci_hp_add_bridge() PCI: add generic pci_hp_add_bridge() PCI: sgihp: register busn_res PCI: ibmhp: register busn_res PCI: cpqhp: register busn_res PCI: shpchp: register busn_res PCI: cpci_hotplug: register busn_res PCI: insert busn_res for child bus PCI: register busn_res for iov bus tile/PCI: use pci_scan_root_bus instead pci_scan_bus parisc/PCI: register busn_res for root buses powerpc/PCI: register busn_res for root buses sparc/PCI: register busn_res for root buses ia64/PCI: register busn_res for root buses ...
This commit is contained in:
@@ -359,7 +359,7 @@ common_init_pci(void)
|
||||
hose, &resources);
|
||||
hose->bus = bus;
|
||||
hose->need_domain_info = need_domain_info;
|
||||
next_busno = bus->subordinate + 1;
|
||||
next_busno = bus->busn_res.end + 1;
|
||||
/* Don't allow 8-bit bus number overflow inside the hose -
|
||||
reserve some space for bridges. */
|
||||
if (next_busno > 224) {
|
||||
|
@@ -461,7 +461,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
|
||||
if (!sys->bus)
|
||||
panic("PCI: unable to scan bus!");
|
||||
|
||||
busnr = sys->bus->subordinate + 1;
|
||||
busnr = sys->bus->busn_res.end + 1;
|
||||
|
||||
list_add(&sys->node, head);
|
||||
} else {
|
||||
|
@@ -351,6 +351,8 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
#endif
|
||||
|
||||
INIT_LIST_HEAD(&info.resources);
|
||||
/* insert busn resource at first */
|
||||
pci_add_resource(&info.resources, &root->secondary);
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
|
||||
&windows);
|
||||
if (windows) {
|
||||
@@ -384,7 +386,7 @@ pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pbus->subordinate = pci_scan_child_bus(pbus);
|
||||
pci_scan_child_bus(pbus);
|
||||
return pbus;
|
||||
|
||||
out3:
|
||||
|
@@ -1506,10 +1506,10 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
pci_free_resource_list(&resources);
|
||||
return;
|
||||
}
|
||||
bus->secondary = hose->first_busno;
|
||||
bus->busn_res.start = hose->first_busno;
|
||||
hose->bus = bus;
|
||||
|
||||
hose->last_busno = bus->subordinate;
|
||||
hose->last_busno = bus->busn_res.end;
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
|
@@ -102,7 +102,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
|
||||
need_domain_info = need_domain_info || hose->index;
|
||||
hose->need_domain_info = need_domain_info;
|
||||
if (bus) {
|
||||
next_busno = bus->subordinate + 1;
|
||||
next_busno = bus->busn_res.end + 1;
|
||||
/* Don't allow 8-bit bus number overflow inside the hose -
|
||||
reserve some space for bridges. */
|
||||
if (next_busno > 224) {
|
||||
|
@@ -30,6 +30,7 @@ struct pci_controller {
|
||||
int first_busno;
|
||||
int last_busno;
|
||||
int self_busno;
|
||||
struct resource busn;
|
||||
|
||||
void __iomem *io_base_virt;
|
||||
#ifdef CONFIG_PPC64
|
||||
|
@@ -1637,6 +1637,11 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
/* Wire up PHB bus resources */
|
||||
pcibios_setup_phb_resources(hose, &resources);
|
||||
|
||||
hose->busn.start = hose->first_busno;
|
||||
hose->busn.end = hose->last_busno;
|
||||
hose->busn.flags = IORESOURCE_BUS;
|
||||
pci_add_resource(&resources, &hose->busn);
|
||||
|
||||
/* Create an empty bus for the toplevel */
|
||||
bus = pci_create_root_bus(hose->parent, hose->first_busno,
|
||||
hose->ops, hose, &resources);
|
||||
@@ -1646,7 +1651,6 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
pci_free_resource_list(&resources);
|
||||
return;
|
||||
}
|
||||
bus->secondary = hose->first_busno;
|
||||
hose->bus = bus;
|
||||
|
||||
/* Get probe mode and perform scan */
|
||||
@@ -1654,13 +1658,14 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
|
||||
if (node && ppc_md.pci_probe_mode)
|
||||
mode = ppc_md.pci_probe_mode(bus);
|
||||
pr_debug(" probe mode: %d\n", mode);
|
||||
if (mode == PCI_PROBE_DEVTREE) {
|
||||
bus->subordinate = hose->last_busno;
|
||||
if (mode == PCI_PROBE_DEVTREE)
|
||||
of_scan_bus(node, bus);
|
||||
}
|
||||
|
||||
if (mode == PCI_PROBE_NORMAL)
|
||||
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
|
||||
if (mode == PCI_PROBE_NORMAL) {
|
||||
pci_bus_update_busn_res_end(bus, 255);
|
||||
hose->last_busno = pci_scan_child_bus(bus);
|
||||
pci_bus_update_busn_res_end(bus, hose->last_busno);
|
||||
}
|
||||
|
||||
/* Platform gets a chance to do some global fixups before
|
||||
* we proceed to resource allocation
|
||||
|
@@ -236,7 +236,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
|
||||
|
||||
for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
|
||||
bus = pci_bus_b(ln);
|
||||
if (in_bus >= bus->number && in_bus <= bus->subordinate)
|
||||
if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
|
||||
break;
|
||||
bus = NULL;
|
||||
}
|
||||
|
@@ -240,7 +240,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev)
|
||||
}
|
||||
|
||||
bus->primary = dev->bus->number;
|
||||
bus->subordinate = busrange[1];
|
||||
pci_bus_insert_busn_res(bus, busrange[0], busrange[1]);
|
||||
bus->bridge_ctl = 0;
|
||||
|
||||
/* parse ranges property */
|
||||
|
@@ -589,7 +589,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
|
||||
dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER;
|
||||
fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER;
|
||||
parent = pe->pbus->self;
|
||||
count = pe->pbus->subordinate - pe->pbus->secondary + 1;
|
||||
count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1;
|
||||
switch(count) {
|
||||
case 1: bcomp = OpalPciBusAll; break;
|
||||
case 2: bcomp = OpalPciBus7Bits; break;
|
||||
@@ -816,11 +816,11 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev,
|
||||
pe->pdev = NULL;
|
||||
pe->tce32_seg = -1;
|
||||
pe->mve_number = -1;
|
||||
pe->rid = bus->secondary << 8;
|
||||
pe->rid = bus->busn_res.start << 8;
|
||||
pe->dma_weight = 0;
|
||||
|
||||
pe_info(pe, "Secondary busses %d..%d associated with PE\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
pe_info(pe, "Secondary busses %pR associated with PE\n",
|
||||
&bus->busn_res);
|
||||
|
||||
if (pnv_ioda_configure_pe(phb, pe)) {
|
||||
/* XXX What do we do here ? */
|
||||
|
@@ -121,7 +121,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
|
||||
if (!num)
|
||||
return;
|
||||
pcibios_setup_bus_devices(bus);
|
||||
max = bus->secondary;
|
||||
max = bus->busn_res.start;
|
||||
for (pass=0; pass < 2; pass++)
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
|
||||
|
@@ -59,7 +59,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
|
||||
need_domain_info = need_domain_info || hose->index;
|
||||
hose->need_domain_info = need_domain_info;
|
||||
if (bus) {
|
||||
next_busno = bus->subordinate + 1;
|
||||
next_busno = bus->busn_res.end + 1;
|
||||
/* Don't allow 8-bit bus number overflow inside the hose -
|
||||
reserve some space for bridges. */
|
||||
if (next_busno > 224) {
|
||||
|
@@ -535,7 +535,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
|
||||
}
|
||||
|
||||
bus->primary = dev->bus->number;
|
||||
bus->subordinate = busrange[1];
|
||||
pci_bus_insert_busn_res(bus, busrange[0], busrange[1]);
|
||||
bus->bridge_ctl = 0;
|
||||
|
||||
/* parse ranges property, or cook one up by hand for Simba */
|
||||
@@ -685,6 +685,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
|
||||
pbm->io_space.start);
|
||||
pci_add_resource_offset(&resources, &pbm->mem_space,
|
||||
pbm->mem_space.start);
|
||||
pbm->busn.start = pbm->pci_first_busno;
|
||||
pbm->busn.end = pbm->pci_last_busno;
|
||||
pbm->busn.flags = IORESOURCE_BUS;
|
||||
pci_add_resource(&resources, &pbm->busn);
|
||||
bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
|
||||
pbm, &resources);
|
||||
if (!bus) {
|
||||
@@ -693,8 +697,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
|
||||
pci_free_resource_list(&resources);
|
||||
return NULL;
|
||||
}
|
||||
bus->secondary = pbm->pci_first_busno;
|
||||
bus->subordinate = pbm->pci_last_busno;
|
||||
|
||||
pci_of_scan_bus(pbm, node, bus);
|
||||
pci_bus_add_devices(bus);
|
||||
|
@@ -97,6 +97,7 @@ struct pci_pbm_info {
|
||||
/* PBM I/O and Memory space resources. */
|
||||
struct resource io_space;
|
||||
struct resource mem_space;
|
||||
struct resource busn;
|
||||
|
||||
/* Base of PCI Config space, can be per-PBM or shared. */
|
||||
unsigned long config_space;
|
||||
|
@@ -310,6 +310,7 @@ int __init pcibios_init(void)
|
||||
if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
|
||||
struct pci_controller *controller = &controllers[i];
|
||||
struct pci_bus *bus;
|
||||
LIST_HEAD(resources);
|
||||
|
||||
if (tile_init_irqs(i, controller)) {
|
||||
pr_err("PCI: Could not initialize IRQs\n");
|
||||
@@ -327,9 +328,11 @@ int __init pcibios_init(void)
|
||||
* This is inlined in linux/pci.h and calls into
|
||||
* pci_scan_bus_parented() in probe.c.
|
||||
*/
|
||||
bus = pci_scan_bus(0, controller->ops, controller);
|
||||
pci_add_resource(&resources, &ioport_resource);
|
||||
pci_add_resource(&resources, &iomem_resource);
|
||||
bus = pci_scan_root_bus(NULL, 0, controller->ops, controller, &resources);
|
||||
controller->root_bus = bus;
|
||||
controller->last_busno = bus->subordinate;
|
||||
controller->last_busno = bus->busn_res.end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +369,7 @@ int __init pcibios_init(void)
|
||||
*/
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
|
||||
(PCI_SLOT(dev->devfn) == 0)) {
|
||||
next_bus = dev->subordinate;
|
||||
next_bus = dev->busn_res.end;
|
||||
controllers[i].mem_resources[0] =
|
||||
*next_bus->resource[0];
|
||||
controllers[i].mem_resources[1] =
|
||||
|
@@ -12,7 +12,6 @@ struct pci_root_info {
|
||||
char name[16];
|
||||
unsigned int res_num;
|
||||
struct resource *res;
|
||||
int busnum;
|
||||
struct pci_sysdata sd;
|
||||
};
|
||||
|
||||
@@ -347,7 +346,9 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
|
||||
{
|
||||
size_t size;
|
||||
|
||||
sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
|
||||
info->bridge = device;
|
||||
|
||||
info->res_num = 0;
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
|
||||
info);
|
||||
@@ -360,8 +361,6 @@ probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
|
||||
if (!info->res)
|
||||
return;
|
||||
|
||||
sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
|
||||
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
|
||||
info);
|
||||
}
|
||||
@@ -426,6 +425,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
} else {
|
||||
probe_pci_root_info(info, device, busnum, domain);
|
||||
|
||||
/* insert busn res at first */
|
||||
pci_add_resource(&resources, &root->secondary);
|
||||
/*
|
||||
* _CRS with no apertures is normal, so only fall back to
|
||||
* defaults or native bridge info if we're ignoring _CRS.
|
||||
@@ -440,7 +441,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
|
||||
&resources);
|
||||
if (bus) {
|
||||
bus->subordinate = pci_scan_child_bus(bus);
|
||||
pci_scan_child_bus(bus);
|
||||
pci_set_host_bridge_release(
|
||||
to_pci_host_bridge(bus->bridge),
|
||||
release_pci_root_info, info);
|
||||
|
@@ -121,7 +121,6 @@ static int __init early_fill_mp_bus_info(void)
|
||||
link = (reg >> 8) & 0x03;
|
||||
|
||||
info = alloc_pci_root_info(min_bus, max_bus, node, link);
|
||||
sprintf(info->name, "PCI Bus #%02x", min_bus);
|
||||
}
|
||||
|
||||
/* get the default node and link for left over res */
|
||||
@@ -300,9 +299,9 @@ static int __init early_fill_mp_bus_info(void)
|
||||
int busnum;
|
||||
struct pci_root_res *root_res;
|
||||
|
||||
busnum = info->bus_min;
|
||||
printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
|
||||
info->bus_min, info->bus_max, info->node, info->link);
|
||||
busnum = info->busn.start;
|
||||
printk(KERN_DEBUG "bus: %pR on node %x link %x\n",
|
||||
&info->busn, info->node, info->link);
|
||||
list_for_each_entry(root_res, &info->resources, list)
|
||||
printk(KERN_DEBUG "bus: %02x %pR\n",
|
||||
busnum, &root_res->res);
|
||||
|
@@ -14,7 +14,7 @@ static struct pci_root_info *x86_find_pci_root_info(int bus)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(info, &pci_root_infos, list)
|
||||
if (info->bus_min == bus)
|
||||
if (info->busn.start == bus)
|
||||
return info;
|
||||
|
||||
return NULL;
|
||||
@@ -24,6 +24,8 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
|
||||
{
|
||||
struct pci_root_info *info = x86_find_pci_root_info(bus);
|
||||
struct pci_root_res *root_res;
|
||||
struct pci_host_bridge_window *window;
|
||||
bool found = false;
|
||||
|
||||
if (!info)
|
||||
goto default_resources;
|
||||
@@ -31,6 +33,16 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
|
||||
printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
|
||||
bus);
|
||||
|
||||
/* already added by acpi ? */
|
||||
list_for_each_entry(window, resources, list)
|
||||
if (window->res->flags & IORESOURCE_BUS) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
pci_add_resource(resources, &info->busn);
|
||||
|
||||
list_for_each_entry(root_res, &info->resources, list) {
|
||||
struct resource *res;
|
||||
struct resource *root;
|
||||
@@ -66,9 +78,13 @@ struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max,
|
||||
if (!info)
|
||||
return info;
|
||||
|
||||
sprintf(info->name, "PCI Bus #%02x", bus_min);
|
||||
|
||||
INIT_LIST_HEAD(&info->resources);
|
||||
info->bus_min = bus_min;
|
||||
info->bus_max = bus_max;
|
||||
info->busn.name = info->name;
|
||||
info->busn.start = bus_min;
|
||||
info->busn.end = bus_max;
|
||||
info->busn.flags = IORESOURCE_BUS;
|
||||
info->node = node;
|
||||
info->link = link;
|
||||
|
||||
|
@@ -13,8 +13,7 @@ struct pci_root_info {
|
||||
struct list_head list;
|
||||
char name[12];
|
||||
struct list_head resources;
|
||||
int bus_min;
|
||||
int bus_max;
|
||||
struct resource busn;
|
||||
int node;
|
||||
int link;
|
||||
};
|
||||
|
@@ -187,7 +187,7 @@ static int __init pcibios_init(void)
|
||||
bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
|
||||
pci_ctrl->ops, pci_ctrl, &resources);
|
||||
pci_ctrl->bus = bus;
|
||||
pci_ctrl->last_busno = bus->subordinate;
|
||||
pci_ctrl->last_busno = bus->busn_res.end;
|
||||
if (next_busno <= pci_ctrl->last_busno)
|
||||
next_busno = pci_ctrl->last_busno+1;
|
||||
}
|
||||
|
@@ -661,7 +661,7 @@ static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
|
||||
if (drhd->devices[i] &&
|
||||
drhd->devices[i]->subordinate &&
|
||||
drhd->devices[i]->subordinate->number <= bus &&
|
||||
drhd->devices[i]->subordinate->subordinate >= bus)
|
||||
drhd->devices[i]->subordinate->busn_res.end >= bus)
|
||||
return drhd->iommu;
|
||||
}
|
||||
|
||||
|
@@ -14168,7 +14168,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
if (bridge->subordinate &&
|
||||
(bridge->subordinate->number <=
|
||||
tp->pdev->bus->number) &&
|
||||
(bridge->subordinate->subordinate >=
|
||||
(bridge->subordinate->busn_res.end >=
|
||||
tp->pdev->bus->number)) {
|
||||
tg3_flag_set(tp, 5701_DMA_BUG);
|
||||
pci_dev_put(bridge);
|
||||
@@ -14196,7 +14196,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
if (bridge && bridge->subordinate &&
|
||||
(bridge->subordinate->number <=
|
||||
tp->pdev->bus->number) &&
|
||||
(bridge->subordinate->subordinate >=
|
||||
(bridge->subordinate->busn_res.end >=
|
||||
tp->pdev->bus->number)) {
|
||||
tg3_flag_set(tp, 40BIT_DMA_BUG);
|
||||
pci_dev_put(bridge);
|
||||
|
@@ -174,7 +174,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 *val)
|
||||
{
|
||||
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
|
||||
void __iomem *base_addr = d->hba.base_addr;
|
||||
unsigned long flags;
|
||||
@@ -209,7 +209,7 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 val)
|
||||
{
|
||||
struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
|
||||
void __iomem *base_addr = d->hba.base_addr;
|
||||
unsigned long flags;
|
||||
@@ -554,7 +554,7 @@ dino_fixup_bus(struct pci_bus *bus)
|
||||
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
|
||||
|
||||
DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
|
||||
__func__, bus, bus->secondary,
|
||||
__func__, bus, bus->busn_res.start,
|
||||
bus->bridge->platform_data);
|
||||
|
||||
/* Firmware doesn't set up card-mode dino, so we have to */
|
||||
@@ -898,6 +898,7 @@ static int __init dino_probe(struct parisc_device *dev)
|
||||
LIST_HEAD(resources);
|
||||
struct pci_bus *bus;
|
||||
unsigned long hpa = dev->hpa.start;
|
||||
int max;
|
||||
|
||||
name = "Dino";
|
||||
if (is_card_dino(&dev->id)) {
|
||||
@@ -983,6 +984,10 @@ static int __init dino_probe(struct parisc_device *dev)
|
||||
if (dino_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
|
||||
|
||||
dino_dev->hba.bus_num.start = dino_current_bus;
|
||||
dino_dev->hba.bus_num.end = 255;
|
||||
dino_dev->hba.bus_num.flags = IORESOURCE_BUS;
|
||||
pci_add_resource(&resources, &dino_dev->hba.bus_num);
|
||||
/*
|
||||
** It's not used to avoid chicken/egg problems
|
||||
** with configuration accessor functions.
|
||||
@@ -998,12 +1003,13 @@ static int __init dino_probe(struct parisc_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bus->subordinate = pci_scan_child_bus(bus);
|
||||
max = pci_scan_child_bus(bus);
|
||||
pci_bus_update_busn_res_end(bus, max);
|
||||
|
||||
/* This code *depends* on scanning being single threaded
|
||||
* if it isn't, this global bus number count will fail
|
||||
*/
|
||||
dino_current_bus = bus->subordinate + 1;
|
||||
dino_current_bus = max + 1;
|
||||
pci_bus_assign_resources(bus);
|
||||
pci_bus_add_devices(bus);
|
||||
return 0;
|
||||
|
@@ -532,7 +532,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
|
||||
intr_slot = PCI_SLOT(pcidev->devfn);
|
||||
}
|
||||
DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n",
|
||||
pcidev->bus->secondary, intr_slot, intr_pin);
|
||||
pcidev->bus->busn_res.start, intr_slot, intr_pin);
|
||||
|
||||
return irt_find_irqline(isi, intr_slot, intr_pin);
|
||||
}
|
||||
|
@@ -189,8 +189,8 @@ lba_dump_res(struct resource *r, int d)
|
||||
|
||||
static int lba_device_present(u8 bus, u8 dfn, struct lba_device *d)
|
||||
{
|
||||
u8 first_bus = d->hba.hba_bus->secondary;
|
||||
u8 last_sub_bus = d->hba.hba_bus->subordinate;
|
||||
u8 first_bus = d->hba.hba_bus->busn_res.start;
|
||||
u8 last_sub_bus = d->hba.hba_bus->busn_res.end;
|
||||
|
||||
if ((bus < first_bus) ||
|
||||
(bus > last_sub_bus) ||
|
||||
@@ -364,7 +364,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
|
||||
static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
|
||||
{
|
||||
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 tok = LBA_CFG_TOK(local_bus, devfn);
|
||||
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
|
||||
|
||||
@@ -380,7 +380,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) {
|
||||
if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) {
|
||||
DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos);
|
||||
/* either don't want to look or know device isn't present. */
|
||||
*data = ~0U;
|
||||
@@ -431,7 +431,7 @@ lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
|
||||
static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
|
||||
{
|
||||
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 tok = LBA_CFG_TOK(local_bus,devfn);
|
||||
|
||||
if ((pos > 255) || (devfn > 255))
|
||||
@@ -444,7 +444,7 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) {
|
||||
if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) {
|
||||
DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data);
|
||||
return 1; /* New Workaround */
|
||||
}
|
||||
@@ -481,7 +481,7 @@ static struct pci_ops elroy_cfg_ops = {
|
||||
static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
|
||||
{
|
||||
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 tok = LBA_CFG_TOK(local_bus, devfn);
|
||||
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
|
||||
|
||||
@@ -514,7 +514,7 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i
|
||||
{
|
||||
struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
|
||||
u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start;
|
||||
u32 tok = LBA_CFG_TOK(local_bus,devfn);
|
||||
|
||||
if ((pos > 255) || (devfn > 255))
|
||||
@@ -636,7 +636,7 @@ lba_fixup_bus(struct pci_bus *bus)
|
||||
struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
|
||||
|
||||
DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
|
||||
bus, bus->secondary, bus->bridge->platform_data);
|
||||
bus, (int)bus->busn_res.start, bus->bridge->platform_data);
|
||||
|
||||
/*
|
||||
** Properly Setup MMIO resources for this bus.
|
||||
@@ -989,6 +989,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
|
||||
case PAT_PBNUM:
|
||||
lba_dev->hba.bus_num.start = p->start;
|
||||
lba_dev->hba.bus_num.end = p->end;
|
||||
lba_dev->hba.bus_num.flags = IORESOURCE_BUS;
|
||||
break;
|
||||
|
||||
case PAT_LMMIO:
|
||||
@@ -1366,6 +1367,7 @@ lba_driver_probe(struct parisc_device *dev)
|
||||
void *tmp_obj;
|
||||
char *version;
|
||||
void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096);
|
||||
int max;
|
||||
|
||||
/* Read HW Rev First */
|
||||
func_class = READ_REG32(addr + LBA_FCLASS);
|
||||
@@ -1502,6 +1504,8 @@ lba_driver_probe(struct parisc_device *dev)
|
||||
if (lba_dev->hba.gmmio_space.flags)
|
||||
pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
|
||||
|
||||
pci_add_resource(&resources, &lba_dev->hba.bus_num);
|
||||
|
||||
dev->dev.platform_data = lba_dev;
|
||||
lba_bus = lba_dev->hba.hba_bus =
|
||||
pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
|
||||
@@ -1511,7 +1515,7 @@ lba_driver_probe(struct parisc_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
lba_bus->subordinate = pci_scan_child_bus(lba_bus);
|
||||
max = pci_scan_child_bus(lba_bus);
|
||||
|
||||
/* This is in lieu of calling pci_assign_unassigned_resources() */
|
||||
if (is_pdc_pat()) {
|
||||
@@ -1541,7 +1545,7 @@ lba_driver_probe(struct parisc_device *dev)
|
||||
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
|
||||
}
|
||||
|
||||
lba_next_bus = lba_bus->subordinate + 1;
|
||||
lba_next_bus = max + 1;
|
||||
pci_bus_add_devices(lba_bus);
|
||||
|
||||
/* Whew! Finally done! Tell services we got this one covered. */
|
||||
|
@@ -4,18 +4,26 @@
|
||||
#include <linux/export.h>
|
||||
#include "pci.h"
|
||||
|
||||
|
||||
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
|
||||
int __ref pci_hp_add_bridge(struct pci_dev *dev)
|
||||
{
|
||||
unsigned int max;
|
||||
struct pci_bus *parent = dev->bus;
|
||||
int pass, busnr, start = parent->busn_res.start;
|
||||
int end = parent->busn_res.end;
|
||||
|
||||
max = pci_scan_child_bus(bus);
|
||||
for (busnr = start; busnr <= end; busnr++) {
|
||||
if (!pci_find_bus(pci_domain_nr(parent), busnr))
|
||||
break;
|
||||
}
|
||||
if (busnr-- > end) {
|
||||
printk(KERN_ERR "No bus number available for hot-added bridge %s\n",
|
||||
pci_name(dev));
|
||||
return -1;
|
||||
}
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
busnr = pci_scan_bridge(parent, dev, busnr, pass);
|
||||
if (!dev->subordinate)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Make the discovered devices available.
|
||||
*/
|
||||
pci_bus_add_devices(bus);
|
||||
|
||||
return max;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_do_scan_bus);
|
||||
EXPORT_SYMBOL_GPL(pci_hp_add_bridge);
|
||||
|
@@ -100,11 +100,11 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
|
||||
PCI_PRIMARY_BUS,
|
||||
&buses);
|
||||
|
||||
if (((buses >> 8) & 0xff) != bus->secondary) {
|
||||
if (((buses >> 8) & 0xff) != bus->busn_res.start) {
|
||||
buses = (buses & 0xff000000)
|
||||
| ((unsigned int)(bus->primary) << 0)
|
||||
| ((unsigned int)(bus->secondary) << 8)
|
||||
| ((unsigned int)(bus->subordinate) << 16);
|
||||
| ((unsigned int)(bus->busn_res.start) << 8)
|
||||
| ((unsigned int)(bus->busn_res.end) << 16);
|
||||
pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
@@ -692,7 +692,7 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
|
||||
* bus->subordinate value because it could have
|
||||
* padding in it.
|
||||
*/
|
||||
max = bus->secondary;
|
||||
max = bus->busn_res.start;
|
||||
|
||||
list_for_each(tmp, &bus->children) {
|
||||
n = pci_bus_max_busnr(pci_bus_b(tmp));
|
||||
|
@@ -285,42 +285,19 @@ int __ref cpci_configure_slot(struct slot *slot)
|
||||
for (fn = 0; fn < 8; fn++) {
|
||||
struct pci_dev *dev;
|
||||
|
||||
dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
|
||||
dev = pci_get_slot(parent,
|
||||
PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
|
||||
if (!dev)
|
||||
continue;
|
||||
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
|
||||
/* Find an unused bus number for the new bridge */
|
||||
struct pci_bus *child;
|
||||
unsigned char busnr, start = parent->secondary;
|
||||
unsigned char end = parent->subordinate;
|
||||
|
||||
for (busnr = start; busnr <= end; busnr++) {
|
||||
if (!pci_find_bus(pci_domain_nr(parent),
|
||||
busnr))
|
||||
break;
|
||||
}
|
||||
if (busnr >= end) {
|
||||
err("No free bus for hot-added bridge\n");
|
||||
pci_dev_put(dev);
|
||||
continue;
|
||||
}
|
||||
child = pci_add_new_bus(parent, dev, busnr);
|
||||
if (!child) {
|
||||
err("Cannot add new bus for %s\n",
|
||||
pci_name(dev));
|
||||
pci_dev_put(dev);
|
||||
continue;
|
||||
}
|
||||
child->subordinate = pci_do_scan_bus(child);
|
||||
pci_bus_size_bridges(child);
|
||||
}
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
|
||||
pci_hp_add_bridge(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
pci_bus_assign_resources(parent);
|
||||
pci_assign_unassigned_bridge_resources(parent->self);
|
||||
|
||||
pci_bus_add_devices(parent);
|
||||
pci_enable_bridges(parent);
|
||||
|
||||
dbg("%s - exit", __func__);
|
||||
return 0;
|
||||
|
@@ -83,7 +83,6 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
|
||||
|
||||
int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
|
||||
{
|
||||
unsigned char bus;
|
||||
struct pci_bus *child;
|
||||
int num;
|
||||
|
||||
@@ -106,9 +105,10 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
|
||||
}
|
||||
|
||||
if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
|
||||
child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
|
||||
pci_do_scan_bus(child);
|
||||
pci_hp_add_bridge(func->pci_dev);
|
||||
child = func->pci_dev->subordinate;
|
||||
if (child)
|
||||
pci_bus_add_devices(child);
|
||||
}
|
||||
|
||||
pci_dev_put(func->pci_dev);
|
||||
|
@@ -775,7 +775,6 @@ static u8 bus_structure_fixup(u8 busno)
|
||||
|
||||
static int ibm_configure_device(struct pci_func *func)
|
||||
{
|
||||
unsigned char bus;
|
||||
struct pci_bus *child;
|
||||
int num;
|
||||
int flag = 0; /* this is to make sure we don't double scan the bus,
|
||||
@@ -805,9 +804,10 @@ static int ibm_configure_device(struct pci_func *func)
|
||||
}
|
||||
}
|
||||
if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
|
||||
pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
|
||||
child = pci_add_new_bus(func->dev->bus, func->dev, bus);
|
||||
pci_do_scan_bus(child);
|
||||
pci_hp_add_bridge(func->dev);
|
||||
child = func->dev->subordinate;
|
||||
if (child)
|
||||
pci_bus_add_devices(child);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -34,29 +34,6 @@
|
||||
#include "../pci.h"
|
||||
#include "pciehp.h"
|
||||
|
||||
static int __ref pciehp_add_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus *parent = dev->bus;
|
||||
int pass, busnr, start = parent->secondary;
|
||||
int end = parent->subordinate;
|
||||
|
||||
for (busnr = start; busnr <= end; busnr++) {
|
||||
if (!pci_find_bus(pci_domain_nr(parent), busnr))
|
||||
break;
|
||||
}
|
||||
if (busnr-- > end) {
|
||||
err("No bus number available for hot-added bridge %s\n",
|
||||
pci_name(dev));
|
||||
return -1;
|
||||
}
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
busnr = pci_scan_bridge(parent, dev, busnr, pass);
|
||||
if (!dev->subordinate)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pciehp_configure_device(struct slot *p_slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
@@ -85,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot)
|
||||
if (!dev)
|
||||
continue;
|
||||
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
|
||||
pciehp_add_bridge(dev);
|
||||
}
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
|
||||
pci_hp_add_bridge(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
|
@@ -397,13 +397,11 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
|
||||
else
|
||||
sn_io_slot_fixup(dev);
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
unsigned char sec_bus;
|
||||
pci_read_config_byte(dev, PCI_SECONDARY_BUS,
|
||||
&sec_bus);
|
||||
new_bus = pci_add_new_bus(dev->bus, dev,
|
||||
sec_bus);
|
||||
pci_scan_child_bus(new_bus);
|
||||
new_ppb = 1;
|
||||
pci_hp_add_bridge(dev);
|
||||
if (dev->subordinate) {
|
||||
new_bus = dev->subordinate;
|
||||
new_ppb = 1;
|
||||
}
|
||||
}
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
@@ -37,9 +37,10 @@
|
||||
int __ref shpchp_configure_device(struct slot *p_slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
|
||||
int num, fn;
|
||||
struct controller *ctrl = p_slot->ctrl;
|
||||
struct pci_dev *bridge = ctrl->pci_dev;
|
||||
struct pci_bus *parent = bridge->subordinate;
|
||||
int num, fn;
|
||||
|
||||
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
|
||||
if (dev) {
|
||||
@@ -61,39 +62,23 @@ int __ref shpchp_configure_device(struct slot *p_slot)
|
||||
if (!dev)
|
||||
continue;
|
||||
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
|
||||
/* Find an unused bus number for the new bridge */
|
||||
struct pci_bus *child;
|
||||
unsigned char busnr, start = parent->secondary;
|
||||
unsigned char end = parent->subordinate;
|
||||
for (busnr = start; busnr <= end; busnr++) {
|
||||
if (!pci_find_bus(pci_domain_nr(parent),
|
||||
busnr))
|
||||
break;
|
||||
}
|
||||
if (busnr > end) {
|
||||
ctrl_err(ctrl,
|
||||
"No free bus for hot-added bridge\n");
|
||||
pci_dev_put(dev);
|
||||
continue;
|
||||
}
|
||||
child = pci_add_new_bus(parent, dev, busnr);
|
||||
if (!child) {
|
||||
ctrl_err(ctrl, "Cannot add new bus for %s\n",
|
||||
pci_name(dev));
|
||||
pci_dev_put(dev);
|
||||
continue;
|
||||
}
|
||||
child->subordinate = pci_do_scan_bus(child);
|
||||
pci_bus_size_bridges(child);
|
||||
}
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
|
||||
pci_hp_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(p_slot->device, fn));
|
||||
if (!dev)
|
||||
continue;
|
||||
pci_configure_slot(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
pci_bus_assign_resources(parent);
|
||||
pci_bus_add_devices(parent);
|
||||
pci_enable_bridges(parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -73,13 +73,13 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
|
||||
}
|
||||
}
|
||||
out += sprintf(out, "Free resources: bus numbers\n");
|
||||
for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) {
|
||||
for (busnr = bus->busn_res.start; busnr <= bus->busn_res.end; busnr++) {
|
||||
if (!pci_find_bus(pci_domain_nr(bus), busnr))
|
||||
break;
|
||||
}
|
||||
if (busnr < bus->subordinate)
|
||||
if (busnr < bus->busn_res.end)
|
||||
out += sprintf(out, "start = %8.8x, length = %8.8x\n",
|
||||
busnr, (bus->subordinate - busnr));
|
||||
busnr, (int)(bus->busn_res.end - busnr));
|
||||
|
||||
return out - buf;
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
child->subordinate = busnr;
|
||||
pci_bus_insert_busn_res(child, busnr, busnr);
|
||||
child->dev.parent = bus->bridge;
|
||||
rc = pci_bus_add_child(child);
|
||||
if (rc) {
|
||||
@@ -327,7 +327,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
|
||||
iov->offset = offset;
|
||||
iov->stride = stride;
|
||||
|
||||
if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) {
|
||||
if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->busn_res.end) {
|
||||
dev_err(&dev->dev, "SR-IOV: bus number out of range\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@@ -110,7 +110,7 @@ unsigned char pci_bus_max_busnr(struct pci_bus* bus)
|
||||
struct list_head *tmp;
|
||||
unsigned char max, n;
|
||||
|
||||
max = bus->subordinate;
|
||||
max = bus->busn_res.end;
|
||||
list_for_each(tmp, &bus->children) {
|
||||
n = pci_bus_max_busnr(pci_bus_b(tmp));
|
||||
if(n > max)
|
||||
|
@@ -124,7 +124,7 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
|
||||
#endif
|
||||
|
||||
/* Functions for PCI Hotplug drivers to use */
|
||||
extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
|
||||
int pci_hp_add_bridge(struct pci_dev *dev);
|
||||
|
||||
#ifdef HAVE_PCI_LEGACY
|
||||
extern void pci_create_legacy_files(struct pci_bus *bus);
|
||||
|
@@ -16,10 +16,47 @@
|
||||
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
|
||||
#define CARDBUS_RESERVE_BUSNR 3
|
||||
|
||||
struct resource busn_resource = {
|
||||
.name = "PCI busn",
|
||||
.start = 0,
|
||||
.end = 255,
|
||||
.flags = IORESOURCE_BUS,
|
||||
};
|
||||
|
||||
/* Ugh. Need to stop exporting this to modules. */
|
||||
LIST_HEAD(pci_root_buses);
|
||||
EXPORT_SYMBOL(pci_root_buses);
|
||||
|
||||
static LIST_HEAD(pci_domain_busn_res_list);
|
||||
|
||||
struct pci_domain_busn_res {
|
||||
struct list_head list;
|
||||
struct resource res;
|
||||
int domain_nr;
|
||||
};
|
||||
|
||||
static struct resource *get_pci_domain_busn_res(int domain_nr)
|
||||
{
|
||||
struct pci_domain_busn_res *r;
|
||||
|
||||
list_for_each_entry(r, &pci_domain_busn_res_list, list)
|
||||
if (r->domain_nr == domain_nr)
|
||||
return &r->res;
|
||||
|
||||
r = kzalloc(sizeof(*r), GFP_KERNEL);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
r->domain_nr = domain_nr;
|
||||
r->res.start = 0;
|
||||
r->res.end = 0xff;
|
||||
r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED;
|
||||
|
||||
list_add_tail(&r->list, &pci_domain_busn_res_list);
|
||||
|
||||
return &r->res;
|
||||
}
|
||||
|
||||
static int find_anything(struct device *dev, void *data)
|
||||
{
|
||||
return 1;
|
||||
@@ -381,8 +418,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
|
||||
if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
|
||||
return;
|
||||
|
||||
dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
|
||||
child->secondary, child->subordinate,
|
||||
dev_info(&dev->dev, "PCI bridge to %pR%s\n",
|
||||
&child->busn_res,
|
||||
dev->transparent ? " (subtractive decode)" : "");
|
||||
|
||||
pci_bus_remove_resources(child);
|
||||
@@ -599,9 +636,9 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
|
||||
* Set up the primary, secondary and subordinate
|
||||
* bus numbers.
|
||||
*/
|
||||
child->number = child->secondary = busnr;
|
||||
child->primary = parent->secondary;
|
||||
child->subordinate = 0xff;
|
||||
child->number = child->busn_res.start = busnr;
|
||||
child->primary = parent->busn_res.start;
|
||||
child->busn_res.end = 0xff;
|
||||
|
||||
if (!bridge)
|
||||
return child;
|
||||
@@ -643,8 +680,8 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
|
||||
if (!pcibios_assign_all_busses())
|
||||
return;
|
||||
|
||||
while (parent->parent && parent->subordinate < max) {
|
||||
parent->subordinate = max;
|
||||
while (parent->parent && parent->busn_res.end < max) {
|
||||
parent->busn_res.end = max;
|
||||
pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
|
||||
parent = parent->parent;
|
||||
}
|
||||
@@ -718,15 +755,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
|
||||
if (!child)
|
||||
goto out;
|
||||
child->primary = primary;
|
||||
child->subordinate = subordinate;
|
||||
pci_bus_insert_busn_res(child, secondary, subordinate);
|
||||
child->bridge_ctl = bctl;
|
||||
}
|
||||
|
||||
cmax = pci_scan_child_bus(child);
|
||||
if (cmax > max)
|
||||
max = cmax;
|
||||
if (child->subordinate > max)
|
||||
max = child->subordinate;
|
||||
if (child->busn_res.end > max)
|
||||
max = child->busn_res.end;
|
||||
} else {
|
||||
/*
|
||||
* We need to assign a number to this bus which we always
|
||||
@@ -756,11 +793,12 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
|
||||
child = pci_add_new_bus(bus, dev, ++max);
|
||||
if (!child)
|
||||
goto out;
|
||||
pci_bus_insert_busn_res(child, max, 0xff);
|
||||
}
|
||||
buses = (buses & 0xff000000)
|
||||
| ((unsigned int)(child->primary) << 0)
|
||||
| ((unsigned int)(child->secondary) << 8)
|
||||
| ((unsigned int)(child->subordinate) << 16);
|
||||
| ((unsigned int)(child->busn_res.start) << 8)
|
||||
| ((unsigned int)(child->busn_res.end) << 16);
|
||||
|
||||
/*
|
||||
* yenta.c forces a secondary latency timer of 176.
|
||||
@@ -805,8 +843,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
|
||||
break;
|
||||
while (parent->parent) {
|
||||
if ((!pcibios_assign_all_busses()) &&
|
||||
(parent->subordinate > max) &&
|
||||
(parent->subordinate <= max+i)) {
|
||||
(parent->busn_res.end > max) &&
|
||||
(parent->busn_res.end <= max+i)) {
|
||||
j = 1;
|
||||
}
|
||||
parent = parent->parent;
|
||||
@@ -827,7 +865,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
|
||||
/*
|
||||
* Set the subordinate bus number to its real value.
|
||||
*/
|
||||
child->subordinate = max;
|
||||
pci_bus_update_busn_res_end(child, max);
|
||||
pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
|
||||
}
|
||||
|
||||
@@ -837,19 +875,19 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
|
||||
|
||||
/* Has only triggered on CardBus, fixup is in yenta_socket */
|
||||
while (bus->parent) {
|
||||
if ((child->subordinate > bus->subordinate) ||
|
||||
(child->number > bus->subordinate) ||
|
||||
if ((child->busn_res.end > bus->busn_res.end) ||
|
||||
(child->number > bus->busn_res.end) ||
|
||||
(child->number < bus->number) ||
|
||||
(child->subordinate < bus->number)) {
|
||||
dev_info(&child->dev, "[bus %02x-%02x] %s "
|
||||
"hidden behind%s bridge %s [bus %02x-%02x]\n",
|
||||
child->number, child->subordinate,
|
||||
(bus->number > child->subordinate &&
|
||||
bus->subordinate < child->number) ?
|
||||
(child->busn_res.end < bus->number)) {
|
||||
dev_info(&child->dev, "%pR %s "
|
||||
"hidden behind%s bridge %s %pR\n",
|
||||
&child->busn_res,
|
||||
(bus->number > child->busn_res.end &&
|
||||
bus->busn_res.end < child->number) ?
|
||||
"wholly" : "partially",
|
||||
bus->self->transparent ? " transparent" : "",
|
||||
dev_name(&bus->dev),
|
||||
bus->number, bus->subordinate);
|
||||
&bus->busn_res);
|
||||
}
|
||||
bus = bus->parent;
|
||||
}
|
||||
@@ -1548,7 +1586,7 @@ EXPORT_SYMBOL_GPL(pcie_bus_configure_settings);
|
||||
|
||||
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
|
||||
{
|
||||
unsigned int devfn, pass, max = bus->secondary;
|
||||
unsigned int devfn, pass, max = bus->busn_res.start;
|
||||
struct pci_dev *dev;
|
||||
|
||||
dev_dbg(&bus->dev, "scanning bus\n");
|
||||
@@ -1642,7 +1680,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
/* Create legacy_io and legacy_mem files for this bus */
|
||||
pci_create_legacy_files(b);
|
||||
|
||||
b->number = b->secondary = bus;
|
||||
b->number = b->busn_res.start = bus;
|
||||
|
||||
if (parent)
|
||||
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
|
||||
@@ -1654,7 +1692,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
list_move_tail(&window->list, &bridge->windows);
|
||||
res = window->res;
|
||||
offset = window->offset;
|
||||
pci_bus_add_resource(b, res, 0);
|
||||
if (res->flags & IORESOURCE_BUS)
|
||||
pci_bus_insert_busn_res(b, bus, res->end);
|
||||
else
|
||||
pci_bus_add_resource(b, res, 0);
|
||||
if (offset) {
|
||||
if (resource_type(res) == IORESOURCE_IO)
|
||||
fmt = " (bus address [%#06llx-%#06llx])";
|
||||
@@ -1684,16 +1725,104 @@ 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)
|
||||
{
|
||||
struct pci_host_bridge_window *window;
|
||||
bool found = false;
|
||||
struct pci_bus *b;
|
||||
int max;
|
||||
|
||||
list_for_each_entry(window, resources, list)
|
||||
if (window->res->flags & IORESOURCE_BUS) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
if (!found) {
|
||||
dev_info(&b->dev,
|
||||
"No busn resource found for root bus, will use [bus %02x-ff]\n",
|
||||
bus);
|
||||
pci_bus_insert_busn_res(b, bus, 255);
|
||||
}
|
||||
|
||||
max = pci_scan_child_bus(b);
|
||||
|
||||
if (!found)
|
||||
pci_bus_update_busn_res_end(b, max);
|
||||
|
||||
pci_bus_add_devices(b);
|
||||
return b;
|
||||
}
|
||||
@@ -1708,9 +1837,10 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
|
||||
|
||||
pci_add_resource(&resources, &ioport_resource);
|
||||
pci_add_resource(&resources, &iomem_resource);
|
||||
pci_add_resource(&resources, &busn_resource);
|
||||
b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
|
||||
if (b)
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
pci_scan_child_bus(b);
|
||||
else
|
||||
pci_free_resource_list(&resources);
|
||||
return b;
|
||||
@@ -1725,9 +1855,10 @@ struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
|
||||
|
||||
pci_add_resource(&resources, &ioport_resource);
|
||||
pci_add_resource(&resources, &iomem_resource);
|
||||
pci_add_resource(&resources, &busn_resource);
|
||||
b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
|
||||
if (b) {
|
||||
b->subordinate = pci_scan_child_bus(b);
|
||||
pci_scan_child_bus(b);
|
||||
pci_bus_add_devices(b);
|
||||
} else {
|
||||
pci_free_resource_list(&resources);
|
||||
|
@@ -68,6 +68,7 @@ void pci_remove_bus(struct pci_bus *pci_bus)
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
list_del(&pci_bus->node);
|
||||
pci_bus_release_busn_res(pci_bus);
|
||||
up_write(&pci_bus_sem);
|
||||
if (!pci_bus->is_added)
|
||||
return;
|
||||
|
@@ -404,8 +404,8 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||
struct resource *res;
|
||||
struct pci_bus_region region;
|
||||
|
||||
dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
dev_info(&bridge->dev, "CardBus bridge to %pR\n",
|
||||
&bus->busn_res);
|
||||
|
||||
res = bus->resource[0];
|
||||
pcibios_resource_to_bus(bridge, ®ion, res);
|
||||
@@ -553,8 +553,8 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
|
||||
{
|
||||
struct pci_dev *bridge = bus->self;
|
||||
|
||||
dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
dev_info(&bridge->dev, "PCI bridge to %pR\n",
|
||||
&bus->busn_res);
|
||||
|
||||
if (type & IORESOURCE_IO)
|
||||
pci_setup_bridge_io(bus);
|
||||
@@ -745,8 +745,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
|
||||
if (!size0 && !size1) {
|
||||
if (b_res->start || b_res->end)
|
||||
dev_info(&bus->self->dev, "disabling bridge window "
|
||||
"%pR to [bus %02x-%02x] (unused)\n", b_res,
|
||||
bus->secondary, bus->subordinate);
|
||||
"%pR to %pR (unused)\n", b_res,
|
||||
&bus->busn_res);
|
||||
b_res->flags = 0;
|
||||
return;
|
||||
}
|
||||
@@ -757,8 +757,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
|
||||
if (size1 > size0 && realloc_head) {
|
||||
add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
|
||||
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
|
||||
"%pR to [bus %02x-%02x] add_size %lx\n", b_res,
|
||||
bus->secondary, bus->subordinate, size1-size0);
|
||||
"%pR to %pR add_size %lx\n", b_res,
|
||||
&bus->busn_res, size1-size0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,8 +863,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
||||
if (!size0 && !size1) {
|
||||
if (b_res->start || b_res->end)
|
||||
dev_info(&bus->self->dev, "disabling bridge window "
|
||||
"%pR to [bus %02x-%02x] (unused)\n", b_res,
|
||||
bus->secondary, bus->subordinate);
|
||||
"%pR to %pR (unused)\n", b_res,
|
||||
&bus->busn_res);
|
||||
b_res->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -874,8 +874,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
||||
if (size1 > size0 && realloc_head) {
|
||||
add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
|
||||
dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
|
||||
"%pR to [bus %02x-%02x] add_size %llx\n", b_res,
|
||||
bus->secondary, bus->subordinate, (unsigned long long)size1-size0);
|
||||
"%pR to %pR add_size %llx\n", b_res,
|
||||
&bus->busn_res, (unsigned long long)size1-size0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ int __ref cb_alloc(struct pcmcia_socket *s)
|
||||
s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
|
||||
pci_fixup_cardbus(bus);
|
||||
|
||||
max = bus->secondary;
|
||||
max = bus->busn_res.start;
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
list_for_each_entry(dev, &bus->devices, bus_list)
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
|
||||
|
@@ -1048,8 +1048,8 @@ static void yenta_config_init(struct yenta_socket *socket)
|
||||
config_writeb(socket, PCI_LATENCY_TIMER, 168);
|
||||
config_writel(socket, PCI_PRIMARY_BUS,
|
||||
(176 << 24) | /* sec. latency timer */
|
||||
(dev->subordinate->subordinate << 16) | /* subordinate bus */
|
||||
(dev->subordinate->secondary << 8) | /* secondary bus */
|
||||
((unsigned int)dev->subordinate->busn_res.end << 16) | /* subordinate bus */
|
||||
((unsigned int)dev->subordinate->busn_res.start << 8) | /* secondary bus */
|
||||
dev->subordinate->primary); /* primary bus */
|
||||
|
||||
/*
|
||||
@@ -1086,14 +1086,14 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
||||
struct pci_bus *bridge_to_fix = cardbus_bridge->parent;
|
||||
|
||||
/* Check bus numbers are already set up correctly: */
|
||||
if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate)
|
||||
if (bridge_to_fix->busn_res.end >= cardbus_bridge->busn_res.end)
|
||||
return; /* The subordinate number is ok, nothing to do */
|
||||
|
||||
if (!bridge_to_fix->parent)
|
||||
return; /* Root bridges are ok */
|
||||
|
||||
/* stay within the limits of the bus range of the parent: */
|
||||
upper_limit = bridge_to_fix->parent->subordinate;
|
||||
upper_limit = bridge_to_fix->parent->busn_res.end;
|
||||
|
||||
/* check the bus ranges of all silbling bridges to prevent overlap */
|
||||
list_for_each(tmp, &bridge_to_fix->parent->children) {
|
||||
@@ -1104,36 +1104,36 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
||||
* current upper limit, set the new upper limit to
|
||||
* the bus number below the silbling's range:
|
||||
*/
|
||||
if (silbling->secondary > bridge_to_fix->subordinate
|
||||
&& silbling->secondary <= upper_limit)
|
||||
upper_limit = silbling->secondary - 1;
|
||||
if (silbling->busn_res.start > bridge_to_fix->busn_res.end
|
||||
&& silbling->busn_res.start <= upper_limit)
|
||||
upper_limit = silbling->busn_res.start - 1;
|
||||
}
|
||||
|
||||
/* Show that the wanted subordinate number is not possible: */
|
||||
if (cardbus_bridge->subordinate > upper_limit)
|
||||
if (cardbus_bridge->busn_res.end > upper_limit)
|
||||
dev_printk(KERN_WARNING, &cardbus_bridge->dev,
|
||||
"Upper limit for fixing this "
|
||||
"bridge's parent bridge: #%02x\n", upper_limit);
|
||||
|
||||
/* If we have room to increase the bridge's subordinate number, */
|
||||
if (bridge_to_fix->subordinate < upper_limit) {
|
||||
if (bridge_to_fix->busn_res.end < upper_limit) {
|
||||
|
||||
/* use the highest number of the hidden bus, within limits */
|
||||
unsigned char subordinate_to_assign =
|
||||
min(cardbus_bridge->subordinate, upper_limit);
|
||||
min_t(int, cardbus_bridge->busn_res.end, upper_limit);
|
||||
|
||||
dev_printk(KERN_INFO, &bridge_to_fix->dev,
|
||||
"Raising subordinate bus# of parent "
|
||||
"bus (#%02x) from #%02x to #%02x\n",
|
||||
bridge_to_fix->number,
|
||||
bridge_to_fix->subordinate, subordinate_to_assign);
|
||||
(int)bridge_to_fix->busn_res.end, subordinate_to_assign);
|
||||
|
||||
/* Save the new subordinate in the bus struct of the bridge */
|
||||
bridge_to_fix->subordinate = subordinate_to_assign;
|
||||
bridge_to_fix->busn_res.end = subordinate_to_assign;
|
||||
|
||||
/* and update the PCI config space with the new subordinate */
|
||||
pci_write_config_byte(bridge_to_fix->self,
|
||||
PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate);
|
||||
PCI_SUBORDINATE_BUS, bridge_to_fix->busn_res.end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -368,6 +368,8 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
|
||||
return (pdev->error_state != pci_channel_io_normal);
|
||||
}
|
||||
|
||||
extern struct resource busn_resource;
|
||||
|
||||
struct pci_host_bridge_window {
|
||||
struct list_head list;
|
||||
struct resource *res; /* host bridge aperture (CPU address) */
|
||||
@@ -419,6 +421,7 @@ struct pci_bus {
|
||||
struct list_head slots; /* list of slots on this bus */
|
||||
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
|
||||
struct list_head resources; /* address space routed to this bus */
|
||||
struct resource busn_res; /* bus numbers routed to this bus */
|
||||
|
||||
struct pci_ops *ops; /* configuration access functions */
|
||||
void *sysdata; /* hook for sys-specific extension */
|
||||
@@ -426,8 +429,6 @@ struct pci_bus {
|
||||
|
||||
unsigned char number; /* bus number */
|
||||
unsigned char primary; /* number of primary bridge */
|
||||
unsigned char secondary; /* number of secondary bridge */
|
||||
unsigned char subordinate; /* max number of subordinate buses */
|
||||
unsigned char max_bus_speed; /* enum pci_bus_speed */
|
||||
unsigned char cur_bus_speed; /* enum pci_bus_speed */
|
||||
|
||||
@@ -668,6 +669,9 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
|
||||
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources);
|
||||
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
|
||||
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
|
||||
void pci_bus_release_busn_res(struct pci_bus *b);
|
||||
struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources);
|
||||
|
@@ -722,14 +722,12 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t
|
||||
|
||||
write_lock(&resource_lock);
|
||||
|
||||
if (!parent)
|
||||
goto skip;
|
||||
|
||||
if ((start < parent->start) || (end > parent->end))
|
||||
goto out;
|
||||
|
||||
for (tmp = res->child; tmp; tmp = tmp->sibling) {
|
||||
if ((tmp->start < start) || (tmp->end > end))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (res->sibling && (res->sibling->start <= end))
|
||||
goto out;
|
||||
|
||||
@@ -741,6 +739,11 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t
|
||||
goto out;
|
||||
}
|
||||
|
||||
skip:
|
||||
for (tmp = res->child; tmp; tmp = tmp->sibling)
|
||||
if ((tmp->start < start) || (tmp->end > end))
|
||||
goto out;
|
||||
|
||||
res->start = start;
|
||||
res->end = end;
|
||||
result = 0;
|
||||
|
Reference in New Issue
Block a user