in hotplug/ibmphp_res.c [180:358]
int __init ibmphp_rsrc_init(void)
{
struct ebda_pci_rsrc *curr;
struct range_node *newrange = NULL;
struct bus_node *newbus = NULL;
struct bus_node *bus_cur;
struct bus_node *bus_prev;
struct resource_node *new_io = NULL;
struct resource_node *new_mem = NULL;
struct resource_node *new_pfmem = NULL;
int rc;
list_for_each_entry(curr, &ibmphp_ebda_pci_rsrc_head,
ebda_pci_rsrc_list) {
if (!(curr->rsrc_type & PCIDEVMASK)) {
/* EBDA still lists non PCI devices, so ignore... */
debug("this is not a PCI DEVICE in rsrc_init, please take care\n");
// continue;
}
/* this is a primary bus resource */
if (curr->rsrc_type & PRIMARYBUSMASK) {
/* memory */
if ((curr->rsrc_type & RESTYPE) == MMASK) {
/* no bus structure exists in place yet */
if (list_empty(&gbuses)) {
rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
} else {
bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
/* found our bus */
if (bus_cur) {
rc = alloc_bus_range(&bus_cur, &newrange, curr, MEM, 0);
if (rc)
return rc;
} else {
/* went through all the buses and didn't find ours, need to create a new bus node */
rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
}
}
} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
/* prefetchable memory */
if (list_empty(&gbuses)) {
/* no bus structure exists in place yet */
rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
} else {
bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
if (bus_cur) {
/* found our bus */
rc = alloc_bus_range(&bus_cur, &newrange, curr, PFMEM, 0);
if (rc)
return rc;
} else {
/* went through all the buses and didn't find ours, need to create a new bus node */
rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
}
}
} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
/* IO */
if (list_empty(&gbuses)) {
/* no bus structure exists in place yet */
rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
} else {
bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
if (bus_cur) {
rc = alloc_bus_range(&bus_cur, &newrange, curr, IO, 0);
if (rc)
return rc;
} else {
/* went through all the buses and didn't find ours, need to create a new bus node */
rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1);
if (rc)
return rc;
list_add_tail(&newbus->bus_list, &gbuses);
debug("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
}
}
} else {
; /* type is reserved WHAT TO DO IN THIS CASE???
NOTHING TO DO??? */
}
} else {
/* regular pci device resource */
if ((curr->rsrc_type & RESTYPE) == MMASK) {
/* Memory resource */
new_mem = alloc_resources(curr);
if (!new_mem)
return -ENOMEM;
new_mem->type = MEM;
/*
* if it didn't find the bus, means PCI dev
* came b4 the Primary Bus info, so need to
* create a bus rangeno becomes a problem...
* assign a -1 and then update once the range
* actually appears...
*/
if (ibmphp_add_resource(new_mem) < 0) {
newbus = alloc_error_bus(curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstMem = new_mem;
++newbus->needMemUpdate;
new_mem->rangeno = -1;
}
debug("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
/* PFMemory resource */
new_pfmem = alloc_resources(curr);
if (!new_pfmem)
return -ENOMEM;
new_pfmem->type = PFMEM;
new_pfmem->fromMem = 0;
if (ibmphp_add_resource(new_pfmem) < 0) {
newbus = alloc_error_bus(curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstPFMem = new_pfmem;
++newbus->needPFMemUpdate;
new_pfmem->rangeno = -1;
}
debug("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
/* IO resource */
new_io = alloc_resources(curr);
if (!new_io)
return -ENOMEM;
new_io->type = IO;
/*
* if it didn't find the bus, means PCI dev
* came b4 the Primary Bus info, so need to
* create a bus rangeno becomes a problem...
* Can assign a -1 and then update once the
* range actually appears...
*/
if (ibmphp_add_resource(new_io) < 0) {
newbus = alloc_error_bus(curr, 0, 0);
if (!newbus)
return -ENOMEM;
newbus->firstIO = new_io;
++newbus->needIOUpdate;
new_io->rangeno = -1;
}
debug("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
}
}
}
list_for_each_entry(bus_cur, &gbuses, bus_list) {
/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
rc = update_bridge_ranges(&bus_cur);
if (rc)
return rc;
}
return once_over(); /* This is to align ranges (so no -1) */
}