aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c81
1 files changed, 21 insertions, 60 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 2e5f25969e11..e72e0adc0681 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -277,14 +277,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
277 277
278 278
279/* see if it's worth looking at this bridge */ 279/* see if it's worth looking at this bridge */
280static int detect_ejectable_slots(struct pci_bus *pbus) 280static int detect_ejectable_slots(acpi_handle handle)
281{ 281{
282 int found = acpi_pci_detect_ejectable(pbus); 282 int found;
283 struct pci_bus *pbus;
284
285 pbus = pci_bus_from_handle(handle);
286 found = acpi_pci_detect_ejectable(pbus);
283 if (!found) { 287 if (!found) {
284 acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); 288 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
285 if (!bridge_handle)
286 return 0;
287 acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
288 is_pci_dock_device, (void *)&found, NULL); 289 is_pci_dock_device, (void *)&found, NULL);
289 } 290 }
290 return found; 291 return found;
@@ -415,9 +416,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
415 416
416 417
417/* allocate and initialize host bridge data structure */ 418/* allocate and initialize host bridge data structure */
418static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) 419static void add_host_bridge(acpi_handle *handle)
419{ 420{
420 struct acpiphp_bridge *bridge; 421 struct acpiphp_bridge *bridge;
422 struct acpi_pci_root *root = acpi_pci_find_root(handle);
421 423
422 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 424 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
423 if (bridge == NULL) 425 if (bridge == NULL)
@@ -426,7 +428,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
426 bridge->type = BRIDGE_TYPE_HOST; 428 bridge->type = BRIDGE_TYPE_HOST;
427 bridge->handle = handle; 429 bridge->handle = handle;
428 430
429 bridge->pci_bus = pci_bus; 431 bridge->pci_bus = root->bus;
430 432
431 spin_lock_init(&bridge->res_lock); 433 spin_lock_init(&bridge->res_lock);
432 434
@@ -435,7 +437,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
435 437
436 438
437/* allocate and initialize PCI-to-PCI bridge data structure */ 439/* allocate and initialize PCI-to-PCI bridge data structure */
438static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) 440static void add_p2p_bridge(acpi_handle *handle)
439{ 441{
440 struct acpiphp_bridge *bridge; 442 struct acpiphp_bridge *bridge;
441 443
@@ -449,8 +451,8 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
449 bridge->handle = handle; 451 bridge->handle = handle;
450 config_p2p_bridge_flags(bridge); 452 config_p2p_bridge_flags(bridge);
451 453
452 bridge->pci_dev = pci_dev_get(pci_dev); 454 bridge->pci_dev = acpi_get_pci_dev(handle);
453 bridge->pci_bus = pci_dev->subordinate; 455 bridge->pci_bus = bridge->pci_dev->subordinate;
454 if (!bridge->pci_bus) { 456 if (!bridge->pci_bus) {
455 err("This is not a PCI-to-PCI bridge!\n"); 457 err("This is not a PCI-to-PCI bridge!\n");
456 goto err; 458 goto err;
@@ -467,7 +469,7 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
467 init_bridge_misc(bridge); 469 init_bridge_misc(bridge);
468 return; 470 return;
469 err: 471 err:
470 pci_dev_put(pci_dev); 472 pci_dev_put(bridge->pci_dev);
471 kfree(bridge); 473 kfree(bridge);
472 return; 474 return;
473} 475}
@@ -478,39 +480,21 @@ static acpi_status
478find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) 480find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
479{ 481{
480 acpi_status status; 482 acpi_status status;
481 acpi_handle dummy_handle;
482 unsigned long long tmp;
483 int device, function;
484 struct pci_dev *dev; 483 struct pci_dev *dev;
485 struct pci_bus *pci_bus = context;
486
487 status = acpi_get_handle(handle, "_ADR", &dummy_handle);
488 if (ACPI_FAILURE(status))
489 return AE_OK; /* continue */
490
491 status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
492 if (ACPI_FAILURE(status)) {
493 dbg("%s: _ADR evaluation failure\n", __func__);
494 return AE_OK;
495 }
496
497 device = (tmp >> 16) & 0xffff;
498 function = tmp & 0xffff;
499
500 dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
501 484
485 dev = acpi_get_pci_dev(handle);
502 if (!dev || !dev->subordinate) 486 if (!dev || !dev->subordinate)
503 goto out; 487 goto out;
504 488
505 /* check if this bridge has ejectable slots */ 489 /* check if this bridge has ejectable slots */
506 if ((detect_ejectable_slots(dev->subordinate) > 0)) { 490 if ((detect_ejectable_slots(handle) > 0)) {
507 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); 491 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
508 add_p2p_bridge(handle, dev); 492 add_p2p_bridge(handle);
509 } 493 }
510 494
511 /* search P2P bridges under this p2p bridge */ 495 /* search P2P bridges under this p2p bridge */
512 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 496 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
513 find_p2p_bridge, dev->subordinate, NULL); 497 find_p2p_bridge, NULL, NULL);
514 if (ACPI_FAILURE(status)) 498 if (ACPI_FAILURE(status))
515 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 499 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
516 500
@@ -525,9 +509,7 @@ static int add_bridge(acpi_handle handle)
525{ 509{
526 acpi_status status; 510 acpi_status status;
527 unsigned long long tmp; 511 unsigned long long tmp;
528 int seg, bus;
529 acpi_handle dummy_handle; 512 acpi_handle dummy_handle;
530 struct pci_bus *pci_bus;
531 513
532 /* if the bridge doesn't have _STA, we assume it is always there */ 514 /* if the bridge doesn't have _STA, we assume it is always there */
533 status = acpi_get_handle(handle, "_STA", &dummy_handle); 515 status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -542,36 +524,15 @@ static int add_bridge(acpi_handle handle)
542 return 0; 524 return 0;
543 } 525 }
544 526
545 /* get PCI segment number */
546 status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
547
548 seg = ACPI_SUCCESS(status) ? tmp : 0;
549
550 /* get PCI bus number */
551 status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
552
553 if (ACPI_SUCCESS(status)) {
554 bus = tmp;
555 } else {
556 warn("can't get bus number, assuming 0\n");
557 bus = 0;
558 }
559
560 pci_bus = pci_find_bus(seg, bus);
561 if (!pci_bus) {
562 err("Can't find bus %04x:%02x\n", seg, bus);
563 return 0;
564 }
565
566 /* check if this bridge has ejectable slots */ 527 /* check if this bridge has ejectable slots */
567 if (detect_ejectable_slots(pci_bus) > 0) { 528 if (detect_ejectable_slots(handle) > 0) {
568 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 529 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
569 add_host_bridge(handle, pci_bus); 530 add_host_bridge(handle);
570 } 531 }
571 532
572 /* search P2P bridges under this host bridge */ 533 /* search P2P bridges under this host bridge */
573 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 534 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
574 find_p2p_bridge, pci_bus, NULL); 535 find_p2p_bridge, NULL, NULL);
575 536
576 if (ACPI_FAILURE(status)) 537 if (ACPI_FAILURE(status))
577 warn("find_p2p_bridge failed (error code = 0x%x)\n", status); 538 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);