ACPI / hotplug / PCI: Rework the handling of eject requests
To avoid the need to install a hotplug notify handler for each ACPI namespace node representing a device and having a matching scan handler, move the check whether or not the ejection of the given device is enabled through its scan handler from acpi_hotplug_notify_cb() to acpi_generic_hotplug_event(). Also, move the execution of ACPI_OST_SC_EJECT_IN_PROGRESS _OST to acpi_generic_hotplug_event(), because in acpi_hotplug_notify_cb() or in acpi_eject_store() we really don't know whether or not the eject is going to be in progress (for example, acpi_hotplug_execute() may still fail without queuing up the work item). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
@ -459,6 +459,12 @@ static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
|
|||||||
return acpi_scan_device_check(adev);
|
return acpi_scan_device_check(adev);
|
||||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||||
case ACPI_OST_EC_OSPM_EJECT:
|
case ACPI_OST_EC_OSPM_EJECT:
|
||||||
|
if (adev->handler && !adev->handler->hotplug.enabled) {
|
||||||
|
dev_info(&adev->dev, "Eject disabled\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
acpi_evaluate_hotplug_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST,
|
||||||
|
ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
|
||||||
return acpi_scan_hot_remove(adev);
|
return acpi_scan_hot_remove(adev);
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -483,6 +489,10 @@ static void acpi_device_hotplug(void *data, u32 src)
|
|||||||
|
|
||||||
if (adev->flags.hotplug_notify) {
|
if (adev->flags.hotplug_notify) {
|
||||||
error = acpi_generic_hotplug_event(adev, src);
|
error = acpi_generic_hotplug_event(adev, src);
|
||||||
|
if (error == -EPERM) {
|
||||||
|
ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int (*event)(struct acpi_device *, u32);
|
int (*event)(struct acpi_device *, u32);
|
||||||
|
|
||||||
@ -512,7 +522,6 @@ static void acpi_device_hotplug(void *data, u32 src)
|
|||||||
|
|
||||||
static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
|
static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
|
||||||
{
|
{
|
||||||
struct acpi_scan_handler *handler = data;
|
|
||||||
u32 ost_code = ACPI_OST_SC_SUCCESS;
|
u32 ost_code = ACPI_OST_SC_SUCCESS;
|
||||||
struct acpi_device *adev;
|
struct acpi_device *adev;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
@ -528,13 +537,6 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
|
|||||||
|
|
||||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||||
acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
|
acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
|
||||||
if (handler && !handler->hotplug.enabled) {
|
|
||||||
acpi_handle_err(handle, "Eject disabled\n");
|
|
||||||
ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
|
|
||||||
ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_NOTIFY_DEVICE_WAKE:
|
case ACPI_NOTIFY_DEVICE_WAKE:
|
||||||
@ -632,8 +634,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
|
|||||||
if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
|
if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
|
|
||||||
ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
|
|
||||||
get_device(&acpi_device->dev);
|
get_device(&acpi_device->dev);
|
||||||
status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device,
|
status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device,
|
||||||
ACPI_OST_EC_OSPM_EJECT);
|
ACPI_OST_EC_OSPM_EJECT);
|
||||||
|
Reference in New Issue
Block a user