diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 03:39:43 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:39:43 -0500 |
commit | b2576e1d4408e134e2188c967b1f28af39cd79d4 (patch) | |
tree | 004f3c82faab760f304ce031d6d2f572e7746a50 /drivers/pci/hotplug/acpi_pcihp.c | |
parent | 3cc8a5f4ba91f67bbdb81a43a99281a26aab8d77 (diff) | |
parent | 2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff) |
Merge branch 'linus' into release
Diffstat (limited to 'drivers/pci/hotplug/acpi_pcihp.c')
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2c981cbb0719..1c1141801060 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -500,5 +500,74 @@ int acpi_root_bridge(acpi_handle handle) | |||
500 | } | 500 | } |
501 | EXPORT_SYMBOL_GPL(acpi_root_bridge); | 501 | EXPORT_SYMBOL_GPL(acpi_root_bridge); |
502 | 502 | ||
503 | |||
504 | static int is_ejectable(acpi_handle handle) | ||
505 | { | ||
506 | acpi_status status; | ||
507 | acpi_handle tmp; | ||
508 | unsigned long long removable; | ||
509 | status = acpi_get_handle(handle, "_ADR", &tmp); | ||
510 | if (ACPI_FAILURE(status)) | ||
511 | return 0; | ||
512 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
513 | if (ACPI_SUCCESS(status)) | ||
514 | return 1; | ||
515 | status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); | ||
516 | if (ACPI_SUCCESS(status) && removable) | ||
517 | return 1; | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot | ||
523 | * @pbus: the PCI bus of the PCI slot corresponding to 'handle' | ||
524 | * @handle: ACPI handle to check | ||
525 | * | ||
526 | * Return 1 if handle is ejectable PCI slot, 0 otherwise. | ||
527 | */ | ||
528 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) | ||
529 | { | ||
530 | acpi_handle bridge_handle, parent_handle; | ||
531 | |||
532 | if (!(bridge_handle = acpi_pci_get_bridge_handle(pbus))) | ||
533 | return 0; | ||
534 | if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle)))) | ||
535 | return 0; | ||
536 | if (bridge_handle != parent_handle) | ||
537 | return 0; | ||
538 | return is_ejectable(handle); | ||
539 | } | ||
540 | EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable); | ||
541 | |||
542 | static acpi_status | ||
543 | check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
544 | { | ||
545 | int *found = (int *)context; | ||
546 | if (is_ejectable(handle)) { | ||
547 | *found = 1; | ||
548 | return AE_CTRL_TERMINATE; | ||
549 | } | ||
550 | return AE_OK; | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots | ||
555 | * @pbus - PCI bus to scan | ||
556 | * | ||
557 | * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise. | ||
558 | */ | ||
559 | int acpi_pci_detect_ejectable(struct pci_bus *pbus) | ||
560 | { | ||
561 | acpi_handle handle; | ||
562 | int found = 0; | ||
563 | |||
564 | if (!(handle = acpi_pci_get_bridge_handle(pbus))) | ||
565 | return 0; | ||
566 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
567 | check_hotplug, (void *)&found, NULL); | ||
568 | return found; | ||
569 | } | ||
570 | EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); | ||
571 | |||
503 | module_param(debug_acpi, bool, 0644); | 572 | module_param(debug_acpi, bool, 0644); |
504 | MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); | 573 | MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); |