|
@@ -158,31 +158,17 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-acpi_memory_get_device(acpi_handle handle,
|
|
|
- struct acpi_memory_device **mem_device)
|
|
|
+static int acpi_memory_get_device(acpi_handle handle,
|
|
|
+ struct acpi_memory_device **mem_device)
|
|
|
{
|
|
|
- acpi_status status;
|
|
|
- acpi_handle phandle;
|
|
|
struct acpi_device *device = NULL;
|
|
|
- struct acpi_device *pdevice = NULL;
|
|
|
- int result;
|
|
|
+ int result = 0;
|
|
|
|
|
|
- if (!acpi_bus_get_device(handle, &device) && device)
|
|
|
- goto end;
|
|
|
+ acpi_scan_lock_acquire();
|
|
|
|
|
|
- status = acpi_get_parent(handle, &phandle);
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
- pr_warn(PREFIX "Cannot find acpi parent\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- /* Get the parent device */
|
|
|
- result = acpi_bus_get_device(phandle, &pdevice);
|
|
|
- if (result) {
|
|
|
- pr_warn(PREFIX "Cannot get acpi bus device\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ acpi_bus_get_device(handle, &device);
|
|
|
+ if (device)
|
|
|
+ goto end;
|
|
|
|
|
|
/*
|
|
|
* Now add the notified device. This creates the acpi_device
|
|
@@ -190,18 +176,28 @@ acpi_memory_get_device(acpi_handle handle,
|
|
|
*/
|
|
|
result = acpi_bus_scan(handle);
|
|
|
if (result) {
|
|
|
- pr_warn(PREFIX "Cannot add acpi bus\n");
|
|
|
- return -EINVAL;
|
|
|
+ pr_warn(PREFIX "ACPI namespace scan failed\n");
|
|
|
+ result = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ result = acpi_bus_get_device(handle, &device);
|
|
|
+ if (result) {
|
|
|
+ pr_warn(PREFIX "Missing device object\n");
|
|
|
+ result = -EINVAL;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
end:
|
|
|
*mem_device = acpi_driver_data(device);
|
|
|
if (!(*mem_device)) {
|
|
|
- pr_err(PREFIX "Driver data not found\n");
|
|
|
- return -ENODEV;
|
|
|
+ pr_err(PREFIX "driver data not found\n");
|
|
|
+ result = -ENODEV;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+out:
|
|
|
+ acpi_scan_lock_release();
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
|
|
@@ -259,12 +255,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
|
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
|
"\nReceived EJECT REQUEST notification for device\n"));
|
|
|
|
|
|
+ acpi_scan_lock_acquire();
|
|
|
if (acpi_bus_get_device(handle, &device)) {
|
|
|
+ acpi_scan_lock_release();
|
|
|
pr_err(PREFIX "Device doesn't exist\n");
|
|
|
break;
|
|
|
}
|
|
|
mem_device = acpi_driver_data(device);
|
|
|
if (!mem_device) {
|
|
|
+ acpi_scan_lock_release();
|
|
|
pr_err(PREFIX "Driver Data is NULL\n");
|
|
|
break;
|
|
|
}
|
|
@@ -274,6 +273,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
|
|
|
* acpi_bus_remove if Xen support hotremove in the future
|
|
|
*/
|
|
|
acpi_memory_disable_device(mem_device);
|
|
|
+ acpi_scan_lock_release();
|
|
|
break;
|
|
|
|
|
|
default:
|