On Friday 12 January 2007 14:10, Bjorn Helgaas wrote: > On Wednesday 06 December 2006 10:17, Bjorn Helgaas wrote: > > Here's a non-line-wrapped version. Justin sent this yesterday > > but it didn't make it to the list for some reason, so I'm > > trying again. > > Ping! Any reaction to this? It makes a BIG difference in > boot time on large system.s Applied. thanks for the ping. -Len > > Move acpi_get_pci_rootbridge_handle() from glue.c to pci_root.c and get the > > root bridge acpi handles by searching the &acpi_pci_roots list instead of > > walking through the ACPI name space. This significantly reduces boot time > > on large I/O systems. > > > > Signed-off-by: Justin Chen <justin.chen@xxxxxx> > > > > diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c > > --- a/drivers/acpi/pci_root.c 2006-11-29 13:57:37.000000000 -0800 > > +++ b/drivers/acpi/pci_root.c 2006-12-04 14:41:14.551395167 -0800 > > @@ -116,6 +116,19 @@ > > > > EXPORT_SYMBOL(acpi_pci_unregister_driver); > > > > +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) > > +{ > > + struct acpi_pci_root *tmp; > > + > > + list_for_each_entry(tmp, &acpi_pci_roots, node) { > > + if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) > > + return tmp->device->handle; > > + } > > + return NULL; > > +} > > + > > +EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); > > + > > static acpi_status > > get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) > > { > > diff -Nru a/drivers/acpi/glue.c b/drivers/acpi/glue.c > > --- a/drivers/acpi/glue.c 2006-12-04 14:42:53.067995523 -0800 > > +++ b/drivers/acpi/glue.c 2006-12-04 14:44:42.723267617 -0800 > > @@ -86,125 +86,6 @@ > > return ret; > > } > > > > -/* Get PCI root bridge's handle from its segment and bus number */ > > -struct acpi_find_pci_root { > > - unsigned int seg; > > - unsigned int bus; > > - acpi_handle handle; > > -}; > > - > > -static acpi_status > > -do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) > > -{ > > - unsigned long *busnr = (unsigned long *)data; > > - struct acpi_resource_address64 address; > > - > > - if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && > > - resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && > > - resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) > > - return AE_OK; > > - > > - acpi_resource_to_address64(resource, &address); > > - if ((address.address_length > 0) && > > - (address.resource_type == ACPI_BUS_NUMBER_RANGE)) > > - *busnr = address.minimum; > > - > > - return AE_OK; > > -} > > - > > -static int get_root_bridge_busnr(acpi_handle handle) > > -{ > > - acpi_status status; > > - unsigned long bus, bbn; > > - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > > - > > - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); > > - > > - status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, > > - &bbn); > > - if (status == AE_NOT_FOUND) { > > - /* Assume bus = 0 */ > > - printk(KERN_INFO PREFIX > > - "Assume root bridge [%s] bus is 0\n", > > - (char *)buffer.pointer); > > - status = AE_OK; > > - bbn = 0; > > - } > > - if (ACPI_FAILURE(status)) { > > - bbn = -ENODEV; > > - goto exit; > > - } > > - if (bbn > 0) > > - goto exit; > > - > > - /* _BBN in some systems return 0 for all root bridges */ > > - bus = -1; > > - status = acpi_walk_resources(handle, METHOD_NAME__CRS, > > - do_root_bridge_busnr_callback, &bus); > > - /* If _CRS failed, we just use _BBN */ > > - if (ACPI_FAILURE(status) || (bus == -1)) > > - goto exit; > > - /* We select _CRS */ > > - if (bbn != bus) { > > - printk(KERN_INFO PREFIX > > - "_BBN and _CRS returns different value for %s. Select _CRS\n", > > - (char *)buffer.pointer); > > - bbn = bus; > > - } > > - exit: > > - kfree(buffer.pointer); > > - return (int)bbn; > > -} > > - > > -static acpi_status > > -find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) > > -{ > > - struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context; > > - unsigned long seg, bus; > > - acpi_status status; > > - int tmp; > > - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > > - > > - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); > > - > > - status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg); > > - if (status == AE_NOT_FOUND) { > > - /* Assume seg = 0 */ > > - status = AE_OK; > > - seg = 0; > > - } > > - if (ACPI_FAILURE(status)) { > > - status = AE_CTRL_DEPTH; > > - goto exit; > > - } > > - > > - tmp = get_root_bridge_busnr(handle); > > - if (tmp < 0) { > > - printk(KERN_ERR PREFIX > > - "Find root bridge failed for %s\n", > > - (char *)buffer.pointer); > > - status = AE_CTRL_DEPTH; > > - goto exit; > > - } > > - bus = tmp; > > - > > - if (seg == find->seg && bus == find->bus) > > - find->handle = handle; > > - status = AE_OK; > > - exit: > > - kfree(buffer.pointer); > > - return status; > > -} > > - > > -acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) > > -{ > > - struct acpi_find_pci_root find = { seg, bus, NULL }; > > - > > - acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); > > - return find.handle; > > -} > > -EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); > > - > > /* Get device's handler per its address under its parent */ > > struct acpi_find_child { > > acpi_handle handle; > > > > - > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > > the body of a message to majordomo@xxxxxxxxxxxxxxx > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > - > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html