aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/pci_root.c4
-rw-r--r--drivers/acpi/scan.c141
3 files changed, 68 insertions, 79 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 809b8082c134..a0d42cf5b0c5 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -89,7 +89,7 @@ void acpi_device_add_finalize(struct acpi_device *device);
89void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); 89void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
90int acpi_bind_one(struct device *dev, acpi_handle handle); 90int acpi_bind_one(struct device *dev, acpi_handle handle);
91int acpi_unbind_one(struct device *dev); 91int acpi_unbind_one(struct device *dev);
92void acpi_bus_device_eject(void *data, u32 ost_src); 92void acpi_device_hotplug(void *data, u32 ost_src);
93bool acpi_device_is_present(struct acpi_device *adev); 93bool acpi_device_is_present(struct acpi_device *adev);
94 94
95/* -------------------------------------------------------------------------- 95/* --------------------------------------------------------------------------
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 4076491c6ded..ca05064f3ff7 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -683,11 +683,13 @@ static void hotplug_event_root(void *data, u32 type)
683 if (!root) 683 if (!root)
684 break; 684 break;
685 685
686 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
687 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
686 get_device(&root->device->dev); 688 get_device(&root->device->dev);
687 689
688 acpi_scan_lock_release(); 690 acpi_scan_lock_release();
689 691
690 acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST); 692 acpi_device_hotplug(root->device, ACPI_NOTIFY_EJECT_REQUEST);
691 return; 693 return;
692 default: 694 default:
693 acpi_handle_warn(handle, 695 acpi_handle_warn(handle,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 4fa416f94f52..dd0ff9de9277 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -206,12 +206,8 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
206 acpi_status status; 206 acpi_status status;
207 unsigned long long sta; 207 unsigned long long sta;
208 208
209 /* If there is no handle, the device node has been unregistered. */ 209 if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER)
210 if (!handle) { 210 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
211 dev_dbg(&device->dev, "ACPI handle missing\n");
212 put_device(&device->dev);
213 return -EINVAL;
214 }
215 211
216 /* 212 /*
217 * Carry out two passes here and ignore errors in the first pass, 213 * Carry out two passes here and ignore errors in the first pass,
@@ -230,7 +226,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
230 dev_warn(errdev, "Offline disabled.\n"); 226 dev_warn(errdev, "Offline disabled.\n");
231 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, 227 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
232 acpi_bus_online, NULL, NULL, NULL); 228 acpi_bus_online, NULL, NULL, NULL);
233 put_device(&device->dev);
234 return -EPERM; 229 return -EPERM;
235 } 230 }
236 acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); 231 acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev);
@@ -249,7 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
249 acpi_walk_namespace(ACPI_TYPE_ANY, handle, 244 acpi_walk_namespace(ACPI_TYPE_ANY, handle,
250 ACPI_UINT32_MAX, acpi_bus_online, 245 ACPI_UINT32_MAX, acpi_bus_online,
251 NULL, NULL, NULL); 246 NULL, NULL, NULL);
252 put_device(&device->dev);
253 return -EBUSY; 247 return -EBUSY;
254 } 248 }
255 } 249 }
@@ -259,9 +253,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
259 253
260 acpi_bus_trim(device); 254 acpi_bus_trim(device);
261 255
262 put_device(&device->dev);
263 device = NULL;
264
265 acpi_evaluate_lck(handle, 0); 256 acpi_evaluate_lck(handle, 0);
266 /* 257 /*
267 * TBD: _EJD support. 258 * TBD: _EJD support.
@@ -288,77 +279,74 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
288 return 0; 279 return 0;
289} 280}
290 281
291void acpi_bus_device_eject(void *data, u32 ost_src) 282static int acpi_scan_device_check(struct acpi_device *adev)
292{ 283{
293 struct acpi_device *device = data;
294 acpi_handle handle = device->handle;
295 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
296 int error; 284 int error;
297 285
298 lock_device_hotplug(); 286 /*
299 mutex_lock(&acpi_scan_lock); 287 * This function is only called for device objects for which matching
300 288 * scan handlers exist. The only situation in which the scan handler is
301 if (ost_src == ACPI_NOTIFY_EJECT_REQUEST) 289 * not attached to this device object yet is when the device has just
302 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, 290 * appeared (either it wasn't present at all before or it was removed
303 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 291 * and then added again).
304 292 */
305 if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) 293 if (adev->handler) {
306 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 294 dev_warn(&adev->dev, "Already enumerated\n");
307 295 return -EBUSY;
308 error = acpi_scan_hot_remove(device);
309 if (error == -EPERM) {
310 goto err_support;
311 } else if (error) {
312 goto err_out;
313 } 296 }
314 297 error = acpi_bus_scan(adev->handle);
315 out: 298 if (error) {
316 mutex_unlock(&acpi_scan_lock); 299 dev_warn(&adev->dev, "Namespace scan failure\n");
317 unlock_device_hotplug(); 300 return error;
318 return; 301 }
319 302 if (adev->handler) {
320 err_support: 303 if (adev->handler->hotplug.mode == AHM_CONTAINER)
321 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; 304 kobject_uevent(&adev->dev.kobj, KOBJ_ONLINE);
322 err_out: 305 } else {
323 acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL); 306 dev_warn(&adev->dev, "Enumeration failure\n");
324 goto out; 307 return -ENODEV;
308 }
309 return 0;
325} 310}
326 311
327static void acpi_scan_bus_device_check(void *data, u32 ost_source) 312void acpi_device_hotplug(void *data, u32 src)
328{ 313{
329 acpi_handle handle = data;
330 struct acpi_device *device;
331 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 314 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
315 struct acpi_device *adev = data;
332 int error; 316 int error;
333 317
334 lock_device_hotplug(); 318 lock_device_hotplug();
335 mutex_lock(&acpi_scan_lock); 319 mutex_lock(&acpi_scan_lock);
336 320
337 if (ost_source != ACPI_NOTIFY_BUS_CHECK) { 321 /*
338 device = NULL; 322 * The device object's ACPI handle cannot become invalid as long as we
339 acpi_bus_get_device(handle, &device); 323 * are holding acpi_scan_lock, but it may have become invalid before
340 if (acpi_device_enumerated(device)) { 324 * that lock was acquired.
341 dev_warn(&device->dev, "Attempt to re-insert\n"); 325 */
342 goto out; 326 if (adev->handle == INVALID_ACPI_HANDLE)
343 }
344 }
345 error = acpi_bus_scan(handle);
346 if (error) {
347 acpi_handle_warn(handle, "Namespace scan failure\n");
348 goto out;
349 }
350 device = NULL;
351 acpi_bus_get_device(handle, &device);
352 if (!acpi_device_enumerated(device)) {
353 acpi_handle_warn(handle, "Device not enumerated\n");
354 goto out; 327 goto out;
328
329 switch (src) {
330 case ACPI_NOTIFY_BUS_CHECK:
331 error = acpi_bus_scan(adev->handle);
332 break;
333 case ACPI_NOTIFY_DEVICE_CHECK:
334 error = acpi_scan_device_check(adev);
335 break;
336 case ACPI_NOTIFY_EJECT_REQUEST:
337 case ACPI_OST_EC_OSPM_EJECT:
338 error = acpi_scan_hot_remove(adev);
339 break;
340 default:
341 error = -EINVAL;
342 break;
355 } 343 }
356 ost_code = ACPI_OST_SC_SUCCESS; 344 if (!error)
357 if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) 345 ost_code = ACPI_OST_SC_SUCCESS;
358 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
359 346
360 out: 347 out:
361 acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); 348 acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL);
349 put_device(&adev->dev);
362 mutex_unlock(&acpi_scan_lock); 350 mutex_unlock(&acpi_scan_lock);
363 unlock_device_hotplug(); 351 unlock_device_hotplug();
364} 352}
@@ -370,6 +358,9 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
370 struct acpi_device *adev; 358 struct acpi_device *adev;
371 acpi_status status; 359 acpi_status status;
372 360
361 if (acpi_bus_get_device(handle, &adev))
362 goto err_out;
363
373 switch (type) { 364 switch (type) {
374 case ACPI_NOTIFY_BUS_CHECK: 365 case ACPI_NOTIFY_BUS_CHECK:
375 acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); 366 acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n");
@@ -384,24 +375,20 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
384 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; 375 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
385 goto err_out; 376 goto err_out;
386 } 377 }
387 if (acpi_bus_get_device(handle, &adev)) 378 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
388 goto err_out; 379 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
389 380 break;
390 get_device(&adev->dev);
391 status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type);
392 if (ACPI_SUCCESS(status))
393 return;
394
395 put_device(&adev->dev);
396 goto err_out;
397 default: 381 default:
398 /* non-hotplug event; possibly handled by other handler */ 382 /* non-hotplug event; possibly handled by other handler */
399 return; 383 return;
400 } 384 }
401 status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type); 385 get_device(&adev->dev);
386 status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
402 if (ACPI_SUCCESS(status)) 387 if (ACPI_SUCCESS(status))
403 return; 388 return;
404 389
390 put_device(&adev->dev);
391
405 err_out: 392 err_out:
406 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); 393 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
407} 394}
@@ -454,7 +441,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
454 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, 441 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
455 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 442 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
456 get_device(&acpi_device->dev); 443 get_device(&acpi_device->dev);
457 status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device, 444 status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device,
458 ACPI_OST_EC_OSPM_EJECT); 445 ACPI_OST_EC_OSPM_EJECT);
459 if (ACPI_SUCCESS(status)) 446 if (ACPI_SUCCESS(status))
460 return count; 447 return count;