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 | ||
