aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@srcf.ucam.org>2008-11-25 16:48:14 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:12:36 -0500
commit56ee325e25a0f76fc3267872867b3d70af179aad (patch)
treec1e840d33d1a1b315e312395b1a674380db91019 /drivers/pci/hotplug
parent86d8698027fd30cc067d2aeeb1e3603d43c83df0 (diff)
PCI/ACPI: acpiphp: Identify more removable slots
According to section 6.3.6 of the ACPI spec, the presence of an _RMV method that evaluates to 1 is sufficient to indicate that a slot is removable without needing an eject method. This patch refactors the ejectable slot detection code a little in order to flag these slots as ejectable and register them. Acpihp then binds to the expresscard slot on my HP test machine. Acked-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 3affc6472e65..1b19b7ec3e8c 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -74,7 +74,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
74 * Ejectable slot should satisfy at least these conditions: 74 * Ejectable slot should satisfy at least these conditions:
75 * 75 *
76 * 1. has _ADR method 76 * 1. has _ADR method
77 * 2. has _EJ0 method 77 * 2. has _EJ0 method or _RMV method
78 * 78 *
79 * optionally 79 * optionally
80 * 80 *
@@ -87,18 +87,25 @@ static int is_ejectable(acpi_handle handle)
87{ 87{
88 acpi_status status; 88 acpi_status status;
89 acpi_handle tmp; 89 acpi_handle tmp;
90 unsigned long long removable;
90 91
91 status = acpi_get_handle(handle, "_ADR", &tmp); 92 status = acpi_get_handle(handle, "_ADR", &tmp);
92 if (ACPI_FAILURE(status)) { 93 if (ACPI_FAILURE(status))
93 return 0; 94 return 0;
94 }
95 95
96 status = acpi_get_handle(handle, "_EJ0", &tmp); 96 status = acpi_get_handle(handle, "_EJ0", &tmp);
97 if (ACPI_FAILURE(status)) { 97 if (ACPI_SUCCESS(status))
98 return 0; 98 return 1;
99
100 status = acpi_get_handle(handle, "_RMV", &tmp);
101 if (ACPI_SUCCESS(status)) {
102 status = acpi_evaluate_integer(handle, "_RMV", NULL,
103 &removable);
104 if (ACPI_SUCCESS(status) && removable)
105 return 1;
99 } 106 }
100 107
101 return 1; 108 return 0;
102} 109}
103 110
104 111
@@ -185,16 +192,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
185 unsigned long long adr, sun; 192 unsigned long long adr, sun;
186 int device, function, retval; 193 int device, function, retval;
187 194
188 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); 195 if (!is_ejectable(handle) && !is_dock_device(handle))
189
190 if (ACPI_FAILURE(status))
191 return AE_OK;
192
193 status = acpi_get_handle(handle, "_EJ0", &tmp);
194
195 if (ACPI_FAILURE(status) && !(is_dock_device(handle)))
196 return AE_OK; 196 return AE_OK;
197 197
198 acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
198 device = (adr >> 16) & 0xffff; 199 device = (adr >> 16) & 0xffff;
199 function = adr & 0xffff; 200 function = adr & 0xffff;
200 201
@@ -205,7 +206,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
205 INIT_LIST_HEAD(&newfunc->sibling); 206 INIT_LIST_HEAD(&newfunc->sibling);
206 newfunc->handle = handle; 207 newfunc->handle = handle;
207 newfunc->function = function; 208 newfunc->function = function;
208 if (ACPI_SUCCESS(status)) 209
210 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
209 newfunc->flags = FUNC_HAS_EJ0; 211 newfunc->flags = FUNC_HAS_EJ0;
210 212
211 if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) 213 if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))