Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318815
b: refs/heads/master
c: c4753e5
h: refs/heads/master
i:
  318813: 4d55f4b
  318811: b4e1e5d
  318807: cdaaa4b
  318799: ce29b16
  318783: 62fc4b9
v: v3
  • Loading branch information
Toshi Kani authored and Len Brown committed Jun 4, 2012
1 parent 94008ba commit d353d74
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 275c58d77062bbb85dbeb3843ba04f34aa50cf8e
refs/heads/master: c4753e57b78b213f2384fa0dbafa348b087114fa
58 changes: 49 additions & 9 deletions trunk/drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,37 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
}
static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);

static void acpi_bus_hot_remove_device(void *context)
/**
* acpi_bus_hot_remove_device: hot-remove a device and its children
* @context: struct acpi_eject_event pointer (freed in this func)
*
* Hot-remove a device and its children. This function frees up the
* memory space passed by arg context, so that the caller may call
* this function asynchronously through acpi_os_hotplug_execute().
*/
void acpi_bus_hot_remove_device(void *context)
{
struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
struct acpi_device *device;
acpi_handle handle = context;
acpi_handle handle = ej_event->handle;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */

if (acpi_bus_get_device(handle, &device))
return;
goto err_out;

if (!device)
return;
goto err_out;

ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Hot-removing device %s...\n", dev_name(&device->dev)));

if (acpi_bus_trim(device, 1)) {
printk(KERN_ERR PREFIX
"Removing device failed\n");
return;
goto err_out;
}

/* power off device */
Expand All @@ -129,10 +139,21 @@ static void acpi_bus_hot_remove_device(void *context)
* TBD: _EJD support.
*/
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status))
printk(KERN_WARNING PREFIX
"Eject device failed\n");
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND)
printk(KERN_WARNING PREFIX
"Eject device failed\n");
goto err_out;
}

kfree(context);
return;

err_out:
/* Inform firmware the hot-remove operation has completed w/ error */
(void) acpi_evaluate_hotplug_ost(handle,
ej_event->event, ost_code, NULL);
kfree(context);
return;
}

Expand All @@ -144,6 +165,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
acpi_status status;
acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d);
struct acpi_eject_event *ej_event;

if ((!count) || (buf[0] != '1')) {
return -EINVAL;
Expand All @@ -160,7 +182,25 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
goto err;
}

acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle);
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
if (!ej_event) {
ret = -ENOMEM;
goto err;
}

ej_event->handle = acpi_device->handle;
if (acpi_device->flags.eject_pending) {
/* event originated from ACPI eject notification */
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
acpi_device->flags.eject_pending = 0;
} else {
/* event originated from user */
ej_event->event = ACPI_OST_EC_OSPM_EJECT;
(void) acpi_evaluate_hotplug_ost(ej_event->handle,
ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
}

acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event);
err:
return ret;
}
Expand Down
9 changes: 8 additions & 1 deletion trunk/include/acpi/acpi_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ struct acpi_device_flags {
u32 suprise_removal_ok:1;
u32 power_manageable:1;
u32 performance_manageable:1;
u32 reserved:24;
u32 eject_pending:1;
u32 reserved:23;
};

/* File System */
Expand Down Expand Up @@ -334,6 +335,11 @@ struct acpi_bus_event {
u32 data;
};

struct acpi_eject_event {
acpi_handle handle;
u32 event;
};

extern struct kobject *acpi_kobj;
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
void acpi_bus_private_data_handler(acpi_handle, void *);
Expand Down Expand Up @@ -371,6 +377,7 @@ int acpi_bus_register_driver(struct acpi_driver *driver);
void acpi_bus_unregister_driver(struct acpi_driver *driver);
int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
acpi_handle handle, int type);
void acpi_bus_hot_remove_device(void *context);
int acpi_bus_trim(struct acpi_device *start, int rmdevice);
int acpi_bus_start(struct acpi_device *device);
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
Expand Down

0 comments on commit d353d74

Please sign in to comment.