diff options
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a6270cc218f6..b4a921236252 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -592,8 +592,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
592 | acpi_status status; | 592 | acpi_status status; |
593 | struct acpiphp_func *func; | 593 | struct acpiphp_func *func; |
594 | struct list_head *l; | 594 | struct list_head *l; |
595 | struct acpi_object_list arg_list; | ||
596 | union acpi_object arg; | ||
597 | 595 | ||
598 | int retval = 0; | 596 | int retval = 0; |
599 | 597 | ||
@@ -615,27 +613,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
615 | } | 613 | } |
616 | } | 614 | } |
617 | 615 | ||
618 | list_for_each (l, &slot->funcs) { | ||
619 | func = list_entry(l, struct acpiphp_func, sibling); | ||
620 | |||
621 | /* We don't want to call _EJ0 on non-existing functions. */ | ||
622 | if (func->flags & FUNC_HAS_EJ0) { | ||
623 | /* _EJ0 method take one argument */ | ||
624 | arg_list.count = 1; | ||
625 | arg_list.pointer = &arg; | ||
626 | arg.type = ACPI_TYPE_INTEGER; | ||
627 | arg.integer.value = 1; | ||
628 | |||
629 | status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); | ||
630 | if (ACPI_FAILURE(status)) { | ||
631 | warn("%s: _EJ0 failed\n", __FUNCTION__); | ||
632 | retval = -1; | ||
633 | goto err_exit; | ||
634 | } else | ||
635 | break; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | /* TBD: evaluate _STA to check if the slot is disabled */ | 616 | /* TBD: evaluate _STA to check if the slot is disabled */ |
640 | 617 | ||
641 | slot->flags &= (~SLOT_POWEREDON); | 618 | slot->flags &= (~SLOT_POWEREDON); |
@@ -782,6 +759,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
782 | } | 759 | } |
783 | 760 | ||
784 | /** | 761 | /** |
762 | * acpiphp_eject_slot - physically eject the slot | ||
763 | */ | ||
764 | static int acpiphp_eject_slot(struct acpiphp_slot *slot) | ||
765 | { | ||
766 | acpi_status status; | ||
767 | struct acpiphp_func *func; | ||
768 | struct list_head *l; | ||
769 | struct acpi_object_list arg_list; | ||
770 | union acpi_object arg; | ||
771 | |||
772 | list_for_each (l, &slot->funcs) { | ||
773 | func = list_entry(l, struct acpiphp_func, sibling); | ||
774 | |||
775 | /* We don't want to call _EJ0 on non-existing functions. */ | ||
776 | if ((func->flags & FUNC_HAS_EJ0)) { | ||
777 | /* _EJ0 method take one argument */ | ||
778 | arg_list.count = 1; | ||
779 | arg_list.pointer = &arg; | ||
780 | arg.type = ACPI_TYPE_INTEGER; | ||
781 | arg.integer.value = 1; | ||
782 | |||
783 | status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); | ||
784 | if (ACPI_FAILURE(status)) { | ||
785 | warn("%s: _EJ0 failed\n", __FUNCTION__); | ||
786 | return -1; | ||
787 | } else | ||
788 | break; | ||
789 | } | ||
790 | } | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | /** | ||
785 | * acpiphp_check_bridge - re-enumerate devices | 795 | * acpiphp_check_bridge - re-enumerate devices |
786 | * | 796 | * |
787 | * Iterate over all slots under this bridge and make sure that if a | 797 | * Iterate over all slots under this bridge and make sure that if a |
@@ -804,6 +814,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
804 | if (retval) { | 814 | if (retval) { |
805 | err("Error occurred in disabling\n"); | 815 | err("Error occurred in disabling\n"); |
806 | goto err_exit; | 816 | goto err_exit; |
817 | } else { | ||
818 | acpiphp_eject_slot(slot); | ||
807 | } | 819 | } |
808 | disabled++; | 820 | disabled++; |
809 | } else { | 821 | } else { |
@@ -1041,7 +1053,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1041 | } | 1053 | } |
1042 | } | 1054 | } |
1043 | 1055 | ||
1044 | |||
1045 | /** | 1056 | /** |
1046 | * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) | 1057 | * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) |
1047 | * | 1058 | * |
@@ -1084,7 +1095,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex | |||
1084 | case ACPI_NOTIFY_EJECT_REQUEST: | 1095 | case ACPI_NOTIFY_EJECT_REQUEST: |
1085 | /* request device eject */ | 1096 | /* request device eject */ |
1086 | dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); | 1097 | dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); |
1087 | acpiphp_disable_slot(func->slot); | 1098 | if (!(acpiphp_disable_slot(func->slot))) |
1099 | acpiphp_eject_slot(func->slot); | ||
1088 | break; | 1100 | break; |
1089 | 1101 | ||
1090 | default: | 1102 | default: |
@@ -1268,7 +1280,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) | |||
1268 | return retval; | 1280 | return retval; |
1269 | } | 1281 | } |
1270 | 1282 | ||
1271 | |||
1272 | /** | 1283 | /** |
1273 | * acpiphp_disable_slot - power off slot | 1284 | * acpiphp_disable_slot - power off slot |
1274 | */ | 1285 | */ |
@@ -1300,11 +1311,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) | |||
1300 | */ | 1311 | */ |
1301 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) | 1312 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) |
1302 | { | 1313 | { |
1303 | unsigned int sta; | 1314 | return (slot->flags & SLOT_POWEREDON); |
1304 | |||
1305 | sta = get_slot_status(slot); | ||
1306 | |||
1307 | return (sta & ACPI_STA_ENABLED) ? 1 : 0; | ||
1308 | } | 1315 | } |
1309 | 1316 | ||
1310 | 1317 | ||