aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c69
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 */
764static 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 */
1301u8 acpiphp_get_power_status(struct acpiphp_slot *slot) 1312u8 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