Commit dc1544ea authored by Len Brown's avatar Len Brown

Merge branch 'bjorn-pci-root-v4-2.6.35' into release

parents 6e320ec1 57283776
...@@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) ...@@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
} }
struct pci_bus * __devinit struct pci_bus * __devinit
pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) pci_acpi_scan_root(struct acpi_pci_root *root)
{ {
struct acpi_device *device = root->device;
int domain = root->segment;
int bus = root->secondary.start;
struct pci_controller *controller; struct pci_controller *controller;
unsigned int windows = 0; unsigned int windows = 0;
struct pci_bus *pbus; struct pci_bus *pbus;
......
...@@ -224,8 +224,11 @@ get_current_resources(struct acpi_device *device, int busnum, ...@@ -224,8 +224,11 @@ get_current_resources(struct acpi_device *device, int busnum,
return; return;
} }
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
{ {
struct acpi_device *device = root->device;
int domain = root->segment;
int busnum = root->secondary.start;
struct pci_bus *bus; struct pci_bus *bus;
struct pci_sysdata *sd; struct pci_sysdata *sd;
int node; int node;
......
...@@ -120,7 +120,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) ...@@ -120,7 +120,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
struct acpi_pci_root *root; struct acpi_pci_root *root;
list_for_each_entry(root, &acpi_pci_roots, node) list_for_each_entry(root, &acpi_pci_roots, node)
if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) if ((root->segment == (u16) seg) &&
(root->secondary.start == (u16) bus))
return root->device->handle; return root->device->handle;
return NULL; return NULL;
} }
...@@ -154,7 +155,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge); ...@@ -154,7 +155,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge);
static acpi_status static acpi_status
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{ {
int *busnr = data; struct resource *res = data;
struct acpi_resource_address64 address; struct acpi_resource_address64 address;
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
...@@ -164,28 +165,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) ...@@ -164,28 +165,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
acpi_resource_to_address64(resource, &address); acpi_resource_to_address64(resource, &address);
if ((address.address_length > 0) && if ((address.address_length > 0) &&
(address.resource_type == ACPI_BUS_NUMBER_RANGE)) (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
*busnr = address.minimum; res->start = address.minimum;
res->end = address.minimum + address.address_length - 1;
}
return AE_OK; return AE_OK;
} }
static acpi_status try_get_root_bridge_busnr(acpi_handle handle, static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
unsigned long long *bus) struct resource *res)
{ {
acpi_status status; acpi_status status;
int busnum;
busnum = -1; res->start = -1;
status = status =
acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_walk_resources(handle, METHOD_NAME__CRS,
get_root_bridge_busnr_callback, &busnum); get_root_bridge_busnr_callback, res);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return status; return status;
/* Check if we really get a bus number from _CRS */ if (res->start == -1)
if (busnum == -1)
return AE_ERROR; return AE_ERROR;
*bus = busnum;
return AE_OK; return AE_OK;
} }
...@@ -429,34 +429,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) ...@@ -429,34 +429,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
struct acpi_device *child; struct acpi_device *child;
u32 flags, base_flags; u32 flags, base_flags;
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
return -ENOMEM;
segment = 0; segment = 0;
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
&segment); &segment);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
return -ENODEV; result = -ENODEV;
goto end;
} }
/* Check _CRS first, then _BBN. If no _BBN, default to zero. */ /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
bus = 0; root->secondary.flags = IORESOURCE_BUS;
status = try_get_root_bridge_busnr(device->handle, &bus); status = try_get_root_bridge_busnr(device->handle, &root->secondary);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/*
* We need both the start and end of the downstream bus range
* to interpret _CBA (MMCONFIG base address), so it really is
* supposed to be in _CRS. If we don't find it there, all we
* can do is assume [_BBN-0xFF] or [0-0xFF].
*/
root->secondary.end = 0xFF;
printk(KERN_WARNING FW_BUG PREFIX
"no secondary bus range in _CRS\n");
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_SUCCESS(status))
printk(KERN_ERR PREFIX root->secondary.start = bus;
"no bus number in _CRS and can't evaluate _BBN\n"); else if (status == AE_NOT_FOUND)
return -ENODEV; root->secondary.start = 0;
else {
printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
result = -ENODEV;
goto end;
} }
} }
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
return -ENOMEM;
INIT_LIST_HEAD(&root->node); INIT_LIST_HEAD(&root->node);
root->device = device; root->device = device;
root->segment = segment & 0xFFFF; root->segment = segment & 0xFFFF;
root->bus_nr = bus & 0xFF;
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
device->driver_data = root; device->driver_data = root;
...@@ -475,9 +488,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) ...@@ -475,9 +488,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
/* TBD: Locking */ /* TBD: Locking */
list_add_tail(&root->node, &acpi_pci_roots); list_add_tail(&root->node, &acpi_pci_roots);
printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
acpi_device_name(device), acpi_device_bid(device), acpi_device_name(device), acpi_device_bid(device),
root->segment, root->bus_nr); root->segment, &root->secondary);
/* /*
* Scan the Root Bridge * Scan the Root Bridge
...@@ -486,11 +499,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) ...@@ -486,11 +499,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
* PCI namespace does not get created until this call is made (and * PCI namespace does not get created until this call is made (and
* thus the root bridge's pci_dev does not exist). * thus the root bridge's pci_dev does not exist).
*/ */
root->bus = pci_acpi_scan_root(device, segment, bus); root->bus = pci_acpi_scan_root(root);
if (!root->bus) { if (!root->bus) {
printk(KERN_ERR PREFIX printk(KERN_ERR PREFIX
"Bus %04x:%02x not present in PCI namespace\n", "Bus %04x:%02x not present in PCI namespace\n",
root->segment, root->bus_nr); root->segment, (unsigned int)root->secondary.start);
result = -ENODEV; result = -ENODEV;
goto end; goto end;
} }
......
...@@ -373,7 +373,7 @@ struct acpi_pci_root { ...@@ -373,7 +373,7 @@ struct acpi_pci_root {
struct acpi_pci_id id; struct acpi_pci_id id;
struct pci_bus *bus; struct pci_bus *bus;
u16 segment; u16 segment;
u8 bus_nr; struct resource secondary; /* downstream bus range */
u32 osc_support_set; /* _OSC state of support bits */ u32 osc_support_set; /* _OSC state of support bits */
u32 osc_control_set; /* _OSC state of control bits */ u32 osc_control_set; /* _OSC state of control bits */
......
...@@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device); ...@@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device);
/* Arch-defined function to add a bus to the system */ /* Arch-defined function to add a bus to the system */
struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root);
int bus);
void pci_acpi_crs_quirks(void); void pci_acpi_crs_quirks(void);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment