next_busno = hose->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) {
next_busno = 0;
need_domain_info = 1;
}
/* * This interrupt-safe spinlock protects all accesses to PCI * configuration space.
*/
DEFINE_RAW_SPINLOCK(pci_config_lock); static DEFINE_MUTEX(pci_scan_mutex);
int register_pci_controller(struct pci_channel *hose)
{ int i;
for (i = 0; i < hose->nr_resources; i++) { struct resource *res = hose->resources + i;
if (res->flags & IORESOURCE_DISABLED) continue;
if (res->flags & IORESOURCE_IO) { if (request_resource(&ioport_resource, res) < 0) goto out;
} else { if (request_resource(&iomem_resource, res) < 0) goto out;
}
}
*hose_tail = hose;
hose_tail = &hose->next;
/* * Do not panic here but later - this might happen before console init.
*/ if (!hose->io_map_base) {
pr_warn("registering PCI controller with io_map_base unset\n");
}
/* * Setup the ERR/PERR and SERR timers, if available.
*/
pcibios_enable_timers(hose);
/* * Scan the bus if it is register after the PCI subsystem * initialization.
*/ if (pci_initialized) {
mutex_lock(&pci_scan_mutex);
pcibios_scanbus(hose);
mutex_unlock(&pci_scan_mutex);
}
return 0;
out: for (--i; i >= 0; i--)
release_resource(&hose->resources[i]);
pr_warn("Skipping PCI bus scan due to resource conflict\n"); return -1;
}
/* Scan all of the recorded PCI controllers. */ for (hose = hose_head; hose; hose = hose->next)
pcibios_scanbus(hose);
pci_initialized = 1;
return 0;
}
subsys_initcall(pcibios_init);
/* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the * addresses to be allocated in the 0x000-0x0ff region * modulo 0x400.
*/
resource_size_t pcibios_align_resource(void *data, conststruct resource *res,
resource_size_t size, resource_size_t align)
{ struct pci_dev *dev = data; struct pci_channel *hose = dev->sysdata;
resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO) { if (start < PCIBIOS_MIN_IO + hose->resources[0].start)
start = PCIBIOS_MIN_IO + hose->resources[0].start;
/* * Put everything into 0x00-0xff region modulo 0x400.
*/ if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
}
return start;
}
staticvoid __init
pcibios_bus_report_status_early(struct pci_channel *hose, int top_bus, int current_bus, unsignedint status_mask, int warn)
{ unsignedint pci_devfn;
u16 status; int ret;
for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { if (PCI_FUNC(pci_devfn)) continue;
ret = early_read_config_word(hose, top_bus, current_bus,
pci_devfn, PCI_STATUS, &status); if (ret != PCIBIOS_SUCCESSFUL) continue; if (status == 0xffff) continue;
early_write_config_word(hose, top_bus, current_bus,
pci_devfn, PCI_STATUS,
status & status_mask); if (warn)
pr_cont("(%02x:%02x: %04X) ", current_bus, pci_devfn,
status);
}
}
/* * We can't use pci_find_device() here since we are * called from interrupt context.
*/ staticvoid __ref
pcibios_bus_report_status(struct pci_bus *bus, unsignedint status_mask, int warn)
{ struct pci_dev *dev;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.