From 8ad095ee8a0f3c9283ca41a4caf9769a3a85faa0 Mon Sep 17 00:00:00 2001 From: Kamala Narasimhan Date: Thu, 14 May 2009 16:56:41 -0400 Subject: [PATCH] Add acpi-wmi files inadvertently removed by previous patch. --- master/xen-acpi-wmi | 466 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) diff --git a/master/xen-acpi-wmi b/master/xen-acpi-wmi index 7ad3ea5..6fe9b70 100644 --- a/master/xen-acpi-wmi +++ b/master/xen-acpi-wmi @@ -559,3 +559,469 @@ index ab35228..873e5a3 100644 obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_FRONTEND) += sfc_netfront/ obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_BACKEND) += sfc_netback/ +obj-$(CONFIG_XEN_ACPI_WMI_WRAPPER) += acpi-wmi/ +diff --git a/drivers/xen/acpi-wmi/Makefile b/drivers/xen/acpi-wmi/Makefile +new file mode 100644 +index 0000000..afe5d9d +--- /dev/null ++++ b/drivers/xen/acpi-wmi/Makefile +@@ -0,0 +1,2 @@ ++ ++obj-y := acpi-wmi.o +diff --git a/drivers/xen/acpi-wmi/acpi-wmi.c b/drivers/xen/acpi-wmi/acpi-wmi.c +new file mode 100644 +index 0000000..90d1e3f +--- /dev/null ++++ b/drivers/xen/acpi-wmi/acpi-wmi.c +@@ -0,0 +1,352 @@ ++/****************************************************************************** ++ * drivers/xen/acpi-wmi/acpi-wmi.c ++ * ++ * Copyright (c) 2009 Kamala Narasimhan ++ * Copyright (c) 2009 Citrix Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++/* Xen acpi-wmi implementation provides the interface required for userspace ++ * module (qemu) to communicate with acpi wmi wrapper kernel driver. ++ * Upon receiving request from qemu to call a WMI method or query or set WMI ++ * data, it communicates the request to kernel acpi wmi layer which then ++ * interacts with the base firmware to get the necessary information/execute ++ * relevant AML method etc. The result returned by the base firmware is then ++ * communicated back to the userspace module (qemu). ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* #define XEN_WMI_DEBUG */ ++ ++static bool xen_wmi_misc_dev_registered = false; ++static int xen_wmi_ioctl(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg); ++ ++static struct file_operations xen_wmi_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = xen_wmi_ioctl, ++}; ++ ++static struct miscdevice xen_wmi_misc = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = XEN_WMI_DEVICE_NAME, ++ .fops = &xen_wmi_fops, ++}; ++ ++/* ++ * xen_wmi_copy_input_buffer ++ */ ++int xen_wmi_copy_input_buffer(xen_wmi_buffer_t *user_buf, struct acpi_buffer *acpi_buf) ++{ ++ if ( user_buf->length <= 0 ) ++ return XEN_WMI_SUCCESS; ++ ++ acpi_buf->pointer = kmalloc(user_buf->length, GFP_KERNEL); ++ if ( acpi_buf->pointer == NULL ) ++ { ++ printk("XEN WMI: xen_wmi_copy_input_buffer - Buffer allocation failure\n"); ++ return XEN_WMI_NOT_ENOUGH_MEMORY; ++ } ++ ++ if ( copy_from_user(acpi_buf->pointer, ++ (char __user *)user_buf->pointer, ++ user_buf->length) ) ++ { ++ printk("XEN WMI: Unable to copy input buffer argument\n"); ++ kfree(acpi_buf->pointer); ++ return XEN_WMI_EFAULT; ++ } ++ ++ acpi_buf->length = user_buf->length; ++ return XEN_WMI_SUCCESS; ++} ++ ++/* ++ * xen_wmi_copy_output_buffer ++ */ ++int xen_wmi_copy_output_buffer(struct acpi_buffer *acpi_buf, xen_wmi_buffer_t *user_buf) ++{ ++ /* IMPORTANT NOTE: It is a little short sighted to assume that the return type ++ * will not be anything other than buffer type. A follow-up check-in will ++ * cover more types. ++ */ ++ ++ union acpi_object *acpi_obj = acpi_buf->pointer; ++ ++ if ( acpi_obj == NULL ) ++ { ++ printk("XEN WMI: Invalid acpi buffer!\n"); ++ return XEN_WMI_EFAULT; ++ } ++ ++ if ( acpi_obj->type != ACPI_TYPE_BUFFER ) ++ { ++ printk("XEN WMI: Unsupported acpi return object type - %d\n", acpi_obj->type); ++ return XEN_WMI_UNSUPPORTED_TYPE; ++ } ++ ++ if ( copy_to_user((char __user *) user_buf->copied_length, &acpi_obj->buffer.length, sizeof(size_t)) ) ++ { ++ printk("XEN WMI: Invalid copied length user buffer!\n"); ++ return XEN_WMI_INVALID_ARGUMENT; ++ } ++ ++ if ( user_buf->length < acpi_obj->buffer.length ) ++ { ++ printk("XEN WMI: Required buffer length is - %d\n", acpi_obj->buffer.length); ++ printk("XEN WMI: Passed in length is - %d\n", user_buf->length); ++ return XEN_WMI_BUFFER_TOO_SMALL; ++ } ++ ++ if ( copy_to_user((char __user *) user_buf->pointer, acpi_obj->buffer.pointer, acpi_obj->buffer.length) ) ++ { ++ printk("XEN WMI: Invalid user output buffer\n"); ++ return XEN_WMI_NOT_ENOUGH_MEMORY; ++ } ++ ++ return XEN_WMI_SUCCESS; ++} ++ ++#ifdef XEN_WMI_DEBUG ++ ++/* ++ * xen_wmi_print_buffer ++ */ ++void xen_wmi_print_buffer(struct acpi_buffer *acpi_buf) ++{ ++ int count; ++ union acpi_object *acpi_obj = acpi_buf->pointer; ++ ++ if ( acpi_obj == NULL || acpi_obj->type != ACPI_TYPE_BUFFER ) ++ { ++ printk("XEN WMI: Unsupported output buffer data!\n"); ++ return ; ++ } ++ ++ printk("XEN WMI: Output buffer length is - %d\n", acpi_obj->buffer.length); ++ printk("XEN WMI: Buffer: "); ++ for (count=0; count < acpi_obj->buffer.length; count++) ++ printk("%d ", ((byte *)(acpi_obj->buffer.pointer))[count]); ++ printk("\n"); ++} ++ ++#endif /* XEN_WMI_DEBUG */ ++ ++/* ++ * xen_wmi_invoke_method ++ */ ++int xen_wmi_invoke_method(xen_wmi_obj_invocation_data_t *obj_inv_data) ++{ ++ int result; ++ struct acpi_buffer in_buf, *in_arg = NULL, out_buf = {ACPI_ALLOCATE_BUFFER, NULL}; ++ ++ result = xen_wmi_copy_input_buffer(&obj_inv_data->xen_wmi_arg.xen_wmi_method_arg.in_buf, ++ &in_buf); ++ if ( result != XEN_WMI_SUCCESS ) ++ return result; ++ ++ if ( in_buf.length > 0 ) ++ in_arg = &in_buf; ++ ++ result = wmi_evaluate_method(obj_inv_data->guid, ++ obj_inv_data->xen_wmi_arg.xen_wmi_method_arg.instance, ++ obj_inv_data->xen_wmi_arg.xen_wmi_method_arg.method_id, ++ in_arg, &out_buf); ++ ++ if ( in_arg != NULL ) ++ kfree(in_buf.pointer); ++ ++ if ( out_buf.length > 0 && result == XEN_WMI_SUCCESS ) ++ { ++#ifdef XEN_WMI_DEBUG ++ xen_wmi_print_buffer(&out_buf); ++#endif ++ result = xen_wmi_copy_output_buffer(&out_buf, ++ &obj_inv_data->xen_wmi_arg.xen_wmi_method_arg.out_buf); ++ kfree(out_buf.pointer); ++ } ++ else if ( result != XEN_WMI_SUCCESS ) ++ printk("XEN WMI- Invoke WMI method failed with error - %d\n", result); ++ ++ return result; ++} ++ ++/* ++ * xen_wmi_query_object ++ */ ++int xen_wmi_query_object(xen_wmi_obj_invocation_data_t *obj_inv_data) ++{ ++ int result; ++ struct acpi_buffer out_buf = {ACPI_ALLOCATE_BUFFER, NULL}; ++ ++ result = wmi_query_block(obj_inv_data->guid, ++ obj_inv_data->xen_wmi_arg.xen_wmi_query_obj_arg.instance, ++ &out_buf); ++ ++ if ( out_buf.length > 0 && result == XEN_WMI_SUCCESS ) ++ { ++#ifdef XEN_WMI_DEBUG ++ xen_wmi_print_buffer(&out_buf); ++#endif ++ result = xen_wmi_copy_output_buffer(&out_buf, ++ &obj_inv_data->xen_wmi_arg.xen_wmi_query_obj_arg.out_buf); ++ kfree(out_buf.pointer); ++ } ++ else ++ printk("XEN WMI - Query WMI object failed with error - %d; output buffer length - %d\n", ++ result, out_buf.length); ++ ++ return result; ++} ++ ++/* ++ * xen_wmi_set_object ++ */ ++int xen_wmi_set_object(xen_wmi_obj_invocation_data_t *obj_inv_data) ++{ ++ int result; ++ struct acpi_buffer in_buf; ++ ++ if ( obj_inv_data->xen_wmi_arg.xen_wmi_set_obj_arg.in_buf.length <= 0 ) ++ return XEN_WMI_INVALID_ARGUMENT; ++ ++ result = xen_wmi_copy_input_buffer(&obj_inv_data->xen_wmi_arg.xen_wmi_set_obj_arg.in_buf, ++ &in_buf); ++ if ( result != XEN_WMI_SUCCESS ) ++ return result; ++ ++ result = wmi_set_block(obj_inv_data->guid, ++ obj_inv_data->xen_wmi_arg.xen_wmi_set_obj_arg.instance, ++ &in_buf); ++ if ( result != XEN_WMI_SUCCESS ) ++ printk("XEN WMI: Set object failed with error - %d\n", result); ++ ++ kfree(in_buf.pointer); ++ return result; ++} ++ ++/* ++ * xen_wmi_get_event_data ++ */ ++int xen_wmi_get_event_data(xen_wmi_obj_invocation_data_t *obj_inv_data) ++{ ++ int result; ++ struct acpi_buffer out_buf = {ACPI_ALLOCATE_BUFFER, NULL}; ++ ++ result = wmi_get_event_data(obj_inv_data->xen_wmi_arg.xen_wmi_event_data_arg.event_id, ++ &out_buf); ++ ++ if ( out_buf.length > 0 && result == XEN_WMI_SUCCESS ) ++ { ++#ifdef XEN_WMI_DEBUG ++ xen_wmi_print_buffer(&out_buf); ++#endif ++ result = xen_wmi_copy_output_buffer(&out_buf, ++ &obj_inv_data->xen_wmi_arg.xen_wmi_event_data_arg.out_buf); ++ kfree(out_buf.pointer); ++ } ++ else ++ printk("XEN WMI: Get event data failed with error - %d\n", result); ++ ++ return result; ++} ++ ++/* ++ * xen_wmi_ioctl ++ */ ++static int xen_wmi_ioctl(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg) ++{ ++ xen_wmi_obj_invocation_data_t obj_inv_data; ++ ++#ifdef XEN_WMI_DEBUG ++ printk("XEN WMI: In xen_wmi_ioctl - %d\n", cmd); ++#endif ++ ++ memset(&obj_inv_data, 0, sizeof(obj_inv_data)); ++ if ( copy_from_user(&obj_inv_data, (char __user *)arg, sizeof(obj_inv_data)) ) ++ { ++ printk("XEN WMI: Invalid object invocation parameter\n"); ++ return XEN_WMI_EFAULT; ++ } ++ ++ switch ( cmd ) ++ { ++ case XEN_WMI_IOCTL_CALL_METHOD: ++ return xen_wmi_invoke_method(&obj_inv_data); ++ case XEN_WMI_IOCTL_QUERY_OBJECT: ++ return xen_wmi_query_object(&obj_inv_data); ++ case XEN_WMI_IOCTL_SET_OBJECT: ++ return xen_wmi_set_object(&obj_inv_data); ++ case XEN_WMI_IOCTL_GET_EVENT_DATA: ++ return xen_wmi_get_event_data(&obj_inv_data); ++ } ++ ++ return XEN_WMI_ENOIOCTLCMD; ++} ++ ++/* ++ * xen_wmi_init ++ */ ++static int __init xen_wmi_init(void) ++{ ++ int ret; ++ ++ ret = misc_register(&xen_wmi_misc); ++ if ( ret < 0 ) ++ printk("XEN WMI: misc_register failed with error - %d\n", ret); ++ else ++ xen_wmi_misc_dev_registered = true; ++ ++#ifdef XEN_WMI_DEBUG ++ printk("XEN WMI: xen-acpi-wmi misc_register succeeded!\n"); ++#endif ++ return ret; ++} ++ ++/* ++ * xen_wmi_exit ++ */ ++static void xen_wmi_exit(void) ++{ ++ int ret; ++ ++ if ( xen_wmi_misc_dev_registered == false ) ++ return; ++ ++ if ( (ret = misc_deregister(&xen_wmi_misc)) < 0 ) ++ printk("XEN WMI: misc_deregister failed with error - %d\n", ret); ++} ++ ++module_init(xen_wmi_init); ++module_exit(xen_wmi_exit); ++MODULE_LICENSE("Dual BSD/GPL"); ++ +diff --git a/include/xen/public/acpi-wmi.h b/include/xen/public/acpi-wmi.h +new file mode 100644 +index 0000000..097639b +--- /dev/null ++++ b/include/xen/public/acpi-wmi.h +@@ -0,0 +1,94 @@ ++/****************************************************************************** ++ * acpi-wmi.h ++ * ++ * Interface to /proc/misc/xen-acpi-wmi ++ * ++ * Copyright (c) 2009 Kamala Narasimhan ++ * Copyright (c) 2009 Citrix Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++ ++#ifndef _XEN_WMI_ACPI ++#define _XEN_WMI_ACPI ++ ++/* ++ * Userspace Interface ++ */ ++ ++#define XEN_WMI_DEVICE_NAME "xen-acpi-wmi" ++#define XEN_WMI_GUID_SIZE 16 ++ ++#define XEN_WMI_SUCCESS 0 ++#define XEN_WMI_UNSUPPORTED_TYPE -1 ++#define XEN_WMI_BUFFER_TOO_SMALL -11 ++#define XEN_WMI_NOT_ENOUGH_MEMORY -12 ++#define XEN_WMI_EFAULT -14 ++#define XEN_WMI_INVALID_ARGUMENT -22 ++#define XEN_WMI_ENOIOCTLCMD -515 ++ ++#define XEN_WMI_IOCTL_CALL_METHOD 100 ++#define XEN_WMI_IOCTL_QUERY_OBJECT 101 ++#define XEN_WMI_IOCTL_SET_OBJECT 102 ++#define XEN_WMI_IOCTL_GET_EVENT_DATA 103 ++ ++typedef unsigned char byte; ++ ++typedef struct xen_wmi_buffer { ++ size_t length; ++ void *pointer; ++ size_t *copied_length; ++} xen_wmi_buffer_t; ++ ++typedef struct xen_wmi_obj_invocation_data { ++ byte guid[XEN_WMI_GUID_SIZE]; ++ union { ++ struct { ++ ushort instance; ++ uint method_id; ++ xen_wmi_buffer_t in_buf; ++ xen_wmi_buffer_t out_buf; ++ } xen_wmi_method_arg; ++ ++ struct { ++ ushort instance; ++ xen_wmi_buffer_t out_buf; ++ } xen_wmi_query_obj_arg; ++ ++ struct { ++ ushort instance; ++ xen_wmi_buffer_t in_buf; ++ } xen_wmi_set_obj_arg; ++ ++ struct { ++ ushort event_id; ++ xen_wmi_buffer_t out_buf; ++ } xen_wmi_event_data_arg; ++ } xen_wmi_arg; ++} xen_wmi_obj_invocation_data_t; ++ ++#endif /* _XEN_WMI_ACPI */ ++ -- 2.39.5