/*
* scan.c - support for transforming the ACPI namespace into individual objects
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("scan")
#define STRUCT_TO_INT(s) (*((int*)&s))
extern struct acpi_device *acpi_root;
#define ACPI_BUS_CLASS "system_bus"
#define ACPI_BUS_HID "ACPI_BUS"
#define ACPI_BUS_DRIVER_NAME "ACPI Bus Driver"
#define ACPI_BUS_DEVICE_NAME "System Bus"
static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
static int acpi_eject_operation(acpi_handle handle, int lockable)
{
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
/*
* TBD: evaluate _PS3?
*/
if (lockable) {
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 0;
acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
}
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = 1;
/*
* TBD: _EJD support.
*/
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status)) {
return (-ENODEV);
}
return (0);
}
static ssize_t
acpi_eject_store(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
int result;
int ret = count;
int islockable;
acpi_status status;
acpi_handle handle;
acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d);
if ((!count) || (buf[0] != '1')) {
return -EINVAL;
}
#ifndef FORCE_EJECT
if (acpi_device->driver == NULL) {
ret = -ENODEV;
goto err;
}
#endif
status = acpi_get_type(acpi_device->handle, &type);
if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
ret = -ENODEV;
goto err;