aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-30 08:14:25 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-30 08:14:25 -0400
commit7bc583d102d6f89c3dc4b502caec6ba03c9d318f (patch)
tree550e6333f2205f006849984b52408ed796bcd0c5 /drivers/acpi/scan.c
parentda48afb26b40ebb5d6b0e84793e0662859c7ea20 (diff)
parentf943db40c29f3c82a56956e9ca36f21d6d855db9 (diff)
Merge branch 'acpi-hotplug'
* acpi-hotplug: ACPI / hotplug: Remove containers synchronously driver core / ACPI: Avoid device hot remove locking issues
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c49
1 files changed, 15 insertions, 34 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e76365136ba3..61d090b6ce25 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -287,6 +287,7 @@ static void acpi_bus_device_eject(void *context)
287 struct acpi_device *device = NULL; 287 struct acpi_device *device = NULL;
288 struct acpi_scan_handler *handler; 288 struct acpi_scan_handler *handler;
289 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 289 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
290 int error;
290 291
291 mutex_lock(&acpi_scan_lock); 292 mutex_lock(&acpi_scan_lock);
292 293
@@ -301,17 +302,13 @@ static void acpi_bus_device_eject(void *context)
301 } 302 }
302 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, 303 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
303 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 304 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
304 if (handler->hotplug.mode == AHM_CONTAINER) { 305 if (handler->hotplug.mode == AHM_CONTAINER)
305 device->flags.eject_pending = true;
306 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 306 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
307 } else {
308 int error;
309 307
310 get_device(&device->dev); 308 get_device(&device->dev);
311 error = acpi_scan_hot_remove(device); 309 error = acpi_scan_hot_remove(device);
312 if (error) 310 if (error)
313 goto err_out; 311 goto err_out;
314 }
315 312
316 out: 313 out:
317 mutex_unlock(&acpi_scan_lock); 314 mutex_unlock(&acpi_scan_lock);
@@ -496,7 +493,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
496 struct acpi_eject_event *ej_event; 493 struct acpi_eject_event *ej_event;
497 acpi_object_type not_used; 494 acpi_object_type not_used;
498 acpi_status status; 495 acpi_status status;
499 u32 ost_source;
500 int ret; 496 int ret;
501 497
502 if (!count || buf[0] != '1') 498 if (!count || buf[0] != '1')
@@ -510,43 +506,28 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
510 if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) 506 if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
511 return -ENODEV; 507 return -ENODEV;
512 508
513 mutex_lock(&acpi_scan_lock);
514
515 if (acpi_device->flags.eject_pending) {
516 /* ACPI eject notification event. */
517 ost_source = ACPI_NOTIFY_EJECT_REQUEST;
518 acpi_device->flags.eject_pending = 0;
519 } else {
520 /* Eject initiated by user space. */
521 ost_source = ACPI_OST_EC_OSPM_EJECT;
522 }
523 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); 509 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
524 if (!ej_event) { 510 if (!ej_event) {
525 ret = -ENOMEM; 511 ret = -ENOMEM;
526 goto err_out; 512 goto err_out;
527 } 513 }
528 acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, 514 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
529 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 515 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
530 ej_event->device = acpi_device; 516 ej_event->device = acpi_device;
531 ej_event->event = ost_source; 517 ej_event->event = ACPI_OST_EC_OSPM_EJECT;
532 get_device(&acpi_device->dev); 518 get_device(&acpi_device->dev);
533 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); 519 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
534 if (ACPI_FAILURE(status)) { 520 if (ACPI_SUCCESS(status))
535 put_device(&acpi_device->dev); 521 return count;
536 kfree(ej_event);
537 ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
538 goto err_out;
539 }
540 ret = count;
541 522
542 out: 523 put_device(&acpi_device->dev);
543 mutex_unlock(&acpi_scan_lock); 524 kfree(ej_event);
544 return ret; 525 ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
545 526
546 err_out: 527 err_out:
547 acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, 528 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
548 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); 529 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
549 goto out; 530 return ret;
550} 531}
551 532
552static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); 533static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);