diff options
Diffstat (limited to 'drivers/acpi/pci_root.c')
| -rw-r--r-- | drivers/acpi/pci_root.c | 297 |
1 files changed, 164 insertions, 133 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 196f97d00956..8a5bf3b356fa 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -63,9 +63,10 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
| 63 | 63 | ||
| 64 | struct acpi_pci_root { | 64 | struct acpi_pci_root { |
| 65 | struct list_head node; | 65 | struct list_head node; |
| 66 | struct acpi_device * device; | 66 | struct acpi_device *device; |
| 67 | struct acpi_pci_id id; | ||
| 68 | struct pci_bus *bus; | 67 | struct pci_bus *bus; |
| 68 | u16 segment; | ||
| 69 | u8 bus_nr; | ||
| 69 | 70 | ||
| 70 | u32 osc_support_set; /* _OSC state of support bits */ | 71 | u32 osc_support_set; /* _OSC state of support bits */ |
| 71 | u32 osc_control_set; /* _OSC state of control bits */ | 72 | u32 osc_control_set; /* _OSC state of control bits */ |
| @@ -82,7 +83,7 @@ static DEFINE_MUTEX(osc_lock); | |||
| 82 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) | 83 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) |
| 83 | { | 84 | { |
| 84 | int n = 0; | 85 | int n = 0; |
| 85 | struct list_head *entry; | 86 | struct acpi_pci_root *root; |
| 86 | 87 | ||
| 87 | struct acpi_pci_driver **pptr = &sub_driver; | 88 | struct acpi_pci_driver **pptr = &sub_driver; |
| 88 | while (*pptr) | 89 | while (*pptr) |
| @@ -92,9 +93,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) | |||
| 92 | if (!driver->add) | 93 | if (!driver->add) |
| 93 | return 0; | 94 | return 0; |
| 94 | 95 | ||
| 95 | list_for_each(entry, &acpi_pci_roots) { | 96 | list_for_each_entry(root, &acpi_pci_roots, node) { |
| 96 | struct acpi_pci_root *root; | ||
| 97 | root = list_entry(entry, struct acpi_pci_root, node); | ||
| 98 | driver->add(root->device->handle); | 97 | driver->add(root->device->handle); |
| 99 | n++; | 98 | n++; |
| 100 | } | 99 | } |
| @@ -106,7 +105,7 @@ EXPORT_SYMBOL(acpi_pci_register_driver); | |||
| 106 | 105 | ||
| 107 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | 106 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) |
| 108 | { | 107 | { |
| 109 | struct list_head *entry; | 108 | struct acpi_pci_root *root; |
| 110 | 109 | ||
| 111 | struct acpi_pci_driver **pptr = &sub_driver; | 110 | struct acpi_pci_driver **pptr = &sub_driver; |
| 112 | while (*pptr) { | 111 | while (*pptr) { |
| @@ -120,28 +119,48 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
| 120 | if (!driver->remove) | 119 | if (!driver->remove) |
| 121 | return; | 120 | return; |
| 122 | 121 | ||
| 123 | list_for_each(entry, &acpi_pci_roots) { | 122 | list_for_each_entry(root, &acpi_pci_roots, node) |
| 124 | struct acpi_pci_root *root; | ||
| 125 | root = list_entry(entry, struct acpi_pci_root, node); | ||
| 126 | driver->remove(root->device->handle); | 123 | driver->remove(root->device->handle); |
| 127 | } | ||
| 128 | } | 124 | } |
| 129 | 125 | ||
| 130 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 126 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
| 131 | 127 | ||
| 132 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | 128 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) |
| 133 | { | 129 | { |
| 134 | struct acpi_pci_root *tmp; | 130 | struct acpi_pci_root *root; |
| 135 | 131 | ||
| 136 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | 132 | list_for_each_entry(root, &acpi_pci_roots, node) |
| 137 | if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) | 133 | if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) |
| 138 | return tmp->device->handle; | 134 | return root->device->handle; |
| 139 | } | ||
| 140 | return NULL; | 135 | return NULL; |
| 141 | } | 136 | } |
| 142 | 137 | ||
| 143 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | 138 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); |
| 144 | 139 | ||
| 140 | /** | ||
| 141 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | ||
| 142 | * @handle - the ACPI CA node in question. | ||
| 143 | * | ||
| 144 | * Note: we could make this API take a struct acpi_device * instead, but | ||
| 145 | * for now, it's more convenient to operate on an acpi_handle. | ||
| 146 | */ | ||
| 147 | int acpi_is_root_bridge(acpi_handle handle) | ||
| 148 | { | ||
| 149 | int ret; | ||
| 150 | struct acpi_device *device; | ||
| 151 | |||
| 152 | ret = acpi_bus_get_device(handle, &device); | ||
| 153 | if (ret) | ||
| 154 | return 0; | ||
| 155 | |||
| 156 | ret = acpi_match_device_ids(device, root_device_ids); | ||
| 157 | if (ret) | ||
| 158 | return 0; | ||
| 159 | else | ||
| 160 | return 1; | ||
| 161 | } | ||
| 162 | EXPORT_SYMBOL_GPL(acpi_is_root_bridge); | ||
| 163 | |||
| 145 | static acpi_status | 164 | static acpi_status |
| 146 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 165 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
| 147 | { | 166 | { |
| @@ -161,19 +180,22 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | |||
| 161 | return AE_OK; | 180 | return AE_OK; |
| 162 | } | 181 | } |
| 163 | 182 | ||
| 164 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) | 183 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, |
| 184 | unsigned long long *bus) | ||
| 165 | { | 185 | { |
| 166 | acpi_status status; | 186 | acpi_status status; |
| 187 | int busnum; | ||
| 167 | 188 | ||
| 168 | *busnum = -1; | 189 | busnum = -1; |
| 169 | status = | 190 | status = |
| 170 | acpi_walk_resources(handle, METHOD_NAME__CRS, | 191 | acpi_walk_resources(handle, METHOD_NAME__CRS, |
| 171 | get_root_bridge_busnr_callback, busnum); | 192 | get_root_bridge_busnr_callback, &busnum); |
| 172 | if (ACPI_FAILURE(status)) | 193 | if (ACPI_FAILURE(status)) |
| 173 | return status; | 194 | return status; |
| 174 | /* Check if we really get a bus number from _CRS */ | 195 | /* Check if we really get a bus number from _CRS */ |
| 175 | if (*busnum == -1) | 196 | if (busnum == -1) |
| 176 | return AE_ERROR; | 197 | return AE_ERROR; |
| 198 | *bus = busnum; | ||
| 177 | return AE_OK; | 199 | return AE_OK; |
| 178 | } | 200 | } |
| 179 | 201 | ||
| @@ -298,6 +320,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
| 298 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | 320 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) |
| 299 | { | 321 | { |
| 300 | struct acpi_pci_root *root; | 322 | struct acpi_pci_root *root; |
| 323 | |||
| 301 | list_for_each_entry(root, &acpi_pci_roots, node) { | 324 | list_for_each_entry(root, &acpi_pci_roots, node) { |
| 302 | if (root->device->handle == handle) | 325 | if (root->device->handle == handle) |
| 303 | return root; | 326 | return root; |
| @@ -305,6 +328,87 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | |||
| 305 | return NULL; | 328 | return NULL; |
| 306 | } | 329 | } |
| 307 | 330 | ||
| 331 | struct acpi_handle_node { | ||
| 332 | struct list_head node; | ||
| 333 | acpi_handle handle; | ||
| 334 | }; | ||
| 335 | |||
| 336 | /** | ||
| 337 | * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev | ||
| 338 | * @handle: the handle in question | ||
| 339 | * | ||
| 340 | * Given an ACPI CA handle, the desired PCI device is located in the | ||
| 341 | * list of PCI devices. | ||
| 342 | * | ||
| 343 | * If the device is found, its reference count is increased and this | ||
| 344 | * function returns a pointer to its data structure. The caller must | ||
| 345 | * decrement the reference count by calling pci_dev_put(). | ||
| 346 | * If no device is found, %NULL is returned. | ||
| 347 | */ | ||
| 348 | struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | ||
| 349 | { | ||
| 350 | int dev, fn; | ||
| 351 | unsigned long long adr; | ||
| 352 | acpi_status status; | ||
| 353 | acpi_handle phandle; | ||
| 354 | struct pci_bus *pbus; | ||
| 355 | struct pci_dev *pdev = NULL; | ||
| 356 | struct acpi_handle_node *node, *tmp; | ||
| 357 | struct acpi_pci_root *root; | ||
| 358 | LIST_HEAD(device_list); | ||
| 359 | |||
| 360 | /* | ||
| 361 | * Walk up the ACPI CA namespace until we reach a PCI root bridge. | ||
| 362 | */ | ||
| 363 | phandle = handle; | ||
| 364 | while (!acpi_is_root_bridge(phandle)) { | ||
| 365 | node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL); | ||
| 366 | if (!node) | ||
| 367 | goto out; | ||
| 368 | |||
| 369 | INIT_LIST_HEAD(&node->node); | ||
| 370 | node->handle = phandle; | ||
| 371 | list_add(&node->node, &device_list); | ||
| 372 | |||
| 373 | status = acpi_get_parent(phandle, &phandle); | ||
| 374 | if (ACPI_FAILURE(status)) | ||
| 375 | goto out; | ||
| 376 | } | ||
| 377 | |||
| 378 | root = acpi_pci_find_root(phandle); | ||
| 379 | if (!root) | ||
| 380 | goto out; | ||
| 381 | |||
| 382 | pbus = root->bus; | ||
| 383 | |||
| 384 | /* | ||
| 385 | * Now, walk back down the PCI device tree until we return to our | ||
| 386 | * original handle. Assumes that everything between the PCI root | ||
| 387 | * bridge and the device we're looking for must be a P2P bridge. | ||
| 388 | */ | ||
| 389 | list_for_each_entry(node, &device_list, node) { | ||
| 390 | acpi_handle hnd = node->handle; | ||
| 391 | status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr); | ||
| 392 | if (ACPI_FAILURE(status)) | ||
| 393 | goto out; | ||
| 394 | dev = (adr >> 16) & 0xffff; | ||
| 395 | fn = adr & 0xffff; | ||
| 396 | |||
| 397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | ||
| 398 | if (hnd == handle) | ||
| 399 | break; | ||
| 400 | |||
| 401 | pbus = pdev->subordinate; | ||
| 402 | pci_dev_put(pdev); | ||
| 403 | } | ||
| 404 | out: | ||
| 405 | list_for_each_entry_safe(node, tmp, &device_list, node) | ||
| 406 | kfree(node); | ||
| 407 | |||
| 408 | return pdev; | ||
| 409 | } | ||
| 410 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | ||
| 411 | |||
| 308 | /** | 412 | /** |
| 309 | * acpi_pci_osc_control_set - commit requested control to Firmware | 413 | * acpi_pci_osc_control_set - commit requested control to Firmware |
| 310 | * @handle: acpi_handle for the target ACPI object | 414 | * @handle: acpi_handle for the target ACPI object |
| @@ -363,31 +467,46 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); | |||
| 363 | 467 | ||
| 364 | static int __devinit acpi_pci_root_add(struct acpi_device *device) | 468 | static int __devinit acpi_pci_root_add(struct acpi_device *device) |
| 365 | { | 469 | { |
| 366 | int result = 0; | 470 | unsigned long long segment, bus; |
| 367 | struct acpi_pci_root *root = NULL; | 471 | acpi_status status; |
| 368 | struct acpi_pci_root *tmp; | 472 | int result; |
| 369 | acpi_status status = AE_OK; | 473 | struct acpi_pci_root *root; |
| 370 | unsigned long long value = 0; | 474 | acpi_handle handle; |
| 371 | acpi_handle handle = NULL; | ||
| 372 | struct acpi_device *child; | 475 | struct acpi_device *child; |
| 373 | u32 flags, base_flags; | 476 | u32 flags, base_flags; |
| 374 | 477 | ||
| 478 | segment = 0; | ||
| 479 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
| 480 | &segment); | ||
| 481 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
| 482 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); | ||
| 483 | return -ENODEV; | ||
| 484 | } | ||
| 375 | 485 | ||
| 376 | if (!device) | 486 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
| 377 | return -EINVAL; | 487 | bus = 0; |
| 488 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
| 489 | if (ACPI_FAILURE(status)) { | ||
| 490 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); | ||
| 491 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
| 492 | printk(KERN_ERR PREFIX | ||
| 493 | "no bus number in _CRS and can't evaluate _BBN\n"); | ||
| 494 | return -ENODEV; | ||
| 495 | } | ||
| 496 | } | ||
| 378 | 497 | ||
| 379 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 498 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
| 380 | if (!root) | 499 | if (!root) |
| 381 | return -ENOMEM; | 500 | return -ENOMEM; |
| 382 | INIT_LIST_HEAD(&root->node); | ||
| 383 | 501 | ||
| 502 | INIT_LIST_HEAD(&root->node); | ||
| 384 | root->device = device; | 503 | root->device = device; |
| 504 | root->segment = segment & 0xFFFF; | ||
| 505 | root->bus_nr = bus & 0xFF; | ||
| 385 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 506 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
| 386 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 507 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
| 387 | device->driver_data = root; | 508 | device->driver_data = root; |
| 388 | 509 | ||
| 389 | device->ops.bind = acpi_pci_bind; | ||
| 390 | |||
| 391 | /* | 510 | /* |
| 392 | * All supported architectures that use ACPI have support for | 511 | * All supported architectures that use ACPI have support for |
| 393 | * PCI domains, so we indicate this in _OSC support capabilities. | 512 | * PCI domains, so we indicate this in _OSC support capabilities. |
| @@ -395,79 +514,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 395 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 514 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
| 396 | acpi_pci_osc_support(root, flags); | 515 | acpi_pci_osc_support(root, flags); |
| 397 | 516 | ||
| 398 | /* | ||
| 399 | * Segment | ||
| 400 | * ------- | ||
| 401 | * Obtained via _SEG, if exists, otherwise assumed to be zero (0). | ||
| 402 | */ | ||
| 403 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
| 404 | &value); | ||
| 405 | switch (status) { | ||
| 406 | case AE_OK: | ||
| 407 | root->id.segment = (u16) value; | ||
| 408 | break; | ||
| 409 | case AE_NOT_FOUND: | ||
| 410 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 411 | "Assuming segment 0 (no _SEG)\n")); | ||
| 412 | root->id.segment = 0; | ||
| 413 | break; | ||
| 414 | default: | ||
| 415 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG")); | ||
| 416 | result = -ENODEV; | ||
| 417 | goto end; | ||
| 418 | } | ||
| 419 | |||
| 420 | /* | ||
| 421 | * Bus | ||
| 422 | * --- | ||
| 423 | * Obtained via _BBN, if exists, otherwise assumed to be zero (0). | ||
| 424 | */ | ||
| 425 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, | ||
| 426 | &value); | ||
| 427 | switch (status) { | ||
| 428 | case AE_OK: | ||
| 429 | root->id.bus = (u16) value; | ||
| 430 | break; | ||
| 431 | case AE_NOT_FOUND: | ||
| 432 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); | ||
| 433 | root->id.bus = 0; | ||
| 434 | break; | ||
| 435 | default: | ||
| 436 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN")); | ||
| 437 | result = -ENODEV; | ||
| 438 | goto end; | ||
| 439 | } | ||
| 440 | |||
| 441 | /* Some systems have wrong _BBN */ | ||
| 442 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | ||
| 443 | if ((tmp->id.segment == root->id.segment) | ||
| 444 | && (tmp->id.bus == root->id.bus)) { | ||
| 445 | int bus = 0; | ||
| 446 | acpi_status status; | ||
| 447 | |||
| 448 | printk(KERN_ERR PREFIX | ||
| 449 | "Wrong _BBN value, reboot" | ||
| 450 | " and use option 'pci=noacpi'\n"); | ||
| 451 | |||
| 452 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
| 453 | if (ACPI_FAILURE(status)) | ||
| 454 | break; | ||
| 455 | if (bus != root->id.bus) { | ||
| 456 | printk(KERN_INFO PREFIX | ||
| 457 | "PCI _CRS %d overrides _BBN 0\n", bus); | ||
| 458 | root->id.bus = bus; | ||
| 459 | } | ||
| 460 | break; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | /* | ||
| 464 | * Device & Function | ||
| 465 | * ----------------- | ||
| 466 | * Obtained from _ADR (which has already been evaluated for us). | ||
| 467 | */ | ||
| 468 | root->id.device = device->pnp.bus_address >> 16; | ||
| 469 | root->id.function = device->pnp.bus_address & 0xFFFF; | ||
| 470 | |||
| 471 | /* | 517 | /* |
| 472 | * TBD: Need PCI interface for enumeration/configuration of roots. | 518 | * TBD: Need PCI interface for enumeration/configuration of roots. |
| 473 | */ | 519 | */ |
| @@ -477,7 +523,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 477 | 523 | ||
| 478 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", | 524 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", |
| 479 | acpi_device_name(device), acpi_device_bid(device), | 525 | acpi_device_name(device), acpi_device_bid(device), |
| 480 | root->id.segment, root->id.bus); | 526 | root->segment, root->bus_nr); |
| 481 | 527 | ||
| 482 | /* | 528 | /* |
| 483 | * Scan the Root Bridge | 529 | * Scan the Root Bridge |
| @@ -486,11 +532,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 486 | * PCI namespace does not get created until this call is made (and | 532 | * PCI namespace does not get created until this call is made (and |
| 487 | * thus the root bridge's pci_dev does not exist). | 533 | * thus the root bridge's pci_dev does not exist). |
| 488 | */ | 534 | */ |
| 489 | root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); | 535 | root->bus = pci_acpi_scan_root(device, segment, bus); |
| 490 | if (!root->bus) { | 536 | if (!root->bus) { |
| 491 | printk(KERN_ERR PREFIX | 537 | printk(KERN_ERR PREFIX |
| 492 | "Bus %04x:%02x not present in PCI namespace\n", | 538 | "Bus %04x:%02x not present in PCI namespace\n", |
| 493 | root->id.segment, root->id.bus); | 539 | root->segment, root->bus_nr); |
| 494 | result = -ENODEV; | 540 | result = -ENODEV; |
| 495 | goto end; | 541 | goto end; |
| 496 | } | 542 | } |
| @@ -500,7 +546,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 500 | * ----------------------- | 546 | * ----------------------- |
| 501 | * Thus binding the ACPI and PCI devices. | 547 | * Thus binding the ACPI and PCI devices. |
| 502 | */ | 548 | */ |
| 503 | result = acpi_pci_bind_root(device, &root->id, root->bus); | 549 | result = acpi_pci_bind_root(device); |
| 504 | if (result) | 550 | if (result) |
| 505 | goto end; | 551 | goto end; |
| 506 | 552 | ||
| @@ -511,8 +557,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 511 | */ | 557 | */ |
| 512 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | 558 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
| 513 | if (ACPI_SUCCESS(status)) | 559 | if (ACPI_SUCCESS(status)) |
| 514 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, | 560 | result = acpi_pci_irq_add_prt(device->handle, root->bus); |
| 515 | root->id.bus); | ||
| 516 | 561 | ||
| 517 | /* | 562 | /* |
| 518 | * Scan and bind all _ADR-Based Devices | 563 | * Scan and bind all _ADR-Based Devices |
| @@ -531,42 +576,28 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 531 | if (flags != base_flags) | 576 | if (flags != base_flags) |
| 532 | acpi_pci_osc_support(root, flags); | 577 | acpi_pci_osc_support(root, flags); |
| 533 | 578 | ||
| 534 | end: | 579 | return 0; |
| 535 | if (result) { | ||
| 536 | if (!list_empty(&root->node)) | ||
| 537 | list_del(&root->node); | ||
| 538 | kfree(root); | ||
| 539 | } | ||
| 540 | 580 | ||
| 581 | end: | ||
| 582 | if (!list_empty(&root->node)) | ||
| 583 | list_del(&root->node); | ||
| 584 | kfree(root); | ||
| 541 | return result; | 585 | return result; |
| 542 | } | 586 | } |
| 543 | 587 | ||
| 544 | static int acpi_pci_root_start(struct acpi_device *device) | 588 | static int acpi_pci_root_start(struct acpi_device *device) |
| 545 | { | 589 | { |
| 546 | struct acpi_pci_root *root; | 590 | struct acpi_pci_root *root = acpi_driver_data(device); |
| 547 | 591 | ||
| 548 | 592 | pci_bus_add_devices(root->bus); | |
| 549 | list_for_each_entry(root, &acpi_pci_roots, node) { | 593 | return 0; |
| 550 | if (root->device == device) { | ||
| 551 | pci_bus_add_devices(root->bus); | ||
| 552 | return 0; | ||
| 553 | } | ||
| 554 | } | ||
| 555 | return -ENODEV; | ||
| 556 | } | 594 | } |
| 557 | 595 | ||
| 558 | static int acpi_pci_root_remove(struct acpi_device *device, int type) | 596 | static int acpi_pci_root_remove(struct acpi_device *device, int type) |
| 559 | { | 597 | { |
| 560 | struct acpi_pci_root *root = NULL; | 598 | struct acpi_pci_root *root = acpi_driver_data(device); |
| 561 | |||
| 562 | |||
| 563 | if (!device || !acpi_driver_data(device)) | ||
| 564 | return -EINVAL; | ||
| 565 | |||
| 566 | root = acpi_driver_data(device); | ||
| 567 | 599 | ||
| 568 | kfree(root); | 600 | kfree(root); |
| 569 | |||
| 570 | return 0; | 601 | return 0; |
| 571 | } | 602 | } |
| 572 | 603 | ||
