+diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
+index 4a1f934..fe798e6 100644
+--- a/drivers/acpi/Kconfig
++++ b/drivers/acpi/Kconfig
+@@ -217,6 +217,14 @@ config ACPI_WMI
+ It is safe to enable this driver even if your DSDT doesn't define
+ any ACPI-WMI devices.
+
++config XEN_ACPI_WMI
++ tristate "XEN WMI"
++ depends on X86
++ depends on !ACPI_WMI
++ help
++ This driver adds support for the ACPI-WMI (Windows Management
++ Instrumentation) mapper device (PNP0C14) under Xen.
++
+ config ACPI_ASUS
+ tristate "ASUS/Medion Laptop Extras"
+ depends on X86
+diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
+index 8a41da8..4f085f8 100644
+--- a/drivers/acpi/Makefile
++++ b/drivers/acpi/Makefile
+@@ -64,6 +64,7 @@ obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
+ obj-$(CONFIG_ACPI_DEBUG) += debug.o
+ obj-$(CONFIG_ACPI_NUMA) += numa.o
+ obj-$(CONFIG_ACPI_WMI) += wmi.o
++obj-$(CONFIG_XEN_ACPI_WMI) += xen-wmi.o
+ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
+ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
+ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
-index 283f908..2359480 100644
+index d274fc6..82d05ee 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
-@@ -123,6 +123,12 @@ static struct acpi_ec {
+@@ -123,6 +123,14 @@ static struct acpi_ec {
int acpi_ec_intr = 1; /* Default is interrupt mode */
-+static u32 wmi_event_data_index = 0;
-+extern u8 in_query_wmi_event_data;
-+extern const u8 wmi_ec_max_data_size;
-+extern u32 wmi_ec_port_data_size;
-+extern u8 wmi_ec_port_data[32];
++#if defined(CONFIG_XEN_ACPI_WMI)
++ static u32 wmi_event_data_index = 0;
++ extern u8 in_query_wmi_event_data;
++ extern const u8 wmi_ec_max_data_size;
++ extern u32 wmi_ec_port_data_size;
++ extern u8 wmi_ec_port_data[32];
++#endif
+
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
-@@ -377,6 +383,22 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
+@@ -377,6 +385,23 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
result = acpi_ec_transaction(ec, &t, 0);
*data = d;
+
++#if defined(CONFIG_XEN_ACPI_WMI)
+ /* HACK ALERT
+ * Please refer to wmi.c for an explanation on why we added this hack.
+ */
+ wmi_event_data_index++;
+ }
+ }
-+
++#endif
return result;
}
-diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
-index cfe2c83..7765da4 100644
---- a/drivers/acpi/wmi.c
-+++ b/drivers/acpi/wmi.c
-@@ -1,13 +1,18 @@
- /*
- * ACPI-WMI mapping driver
- *
-- * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+diff --git a/drivers/acpi/xen-wmi.c b/drivers/acpi/xen-wmi.c
+new file mode 100644
+index 0000000..7765da4
+--- /dev/null
++++ b/drivers/acpi/xen-wmi.c
+@@ -0,0 +1,625 @@
++/*
++ * ACPI-WMI mapping driver
++ *
+ * Copyright (C) 2007-2008 Carlos Corbacho <carlos <at> strangeworlds.co.uk>
- *
-- * GUID parsing code from ldm.c is:
-- * Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org>
-- * Copyright (c) 2001-2007 Anton Altaparmakov
-- * Copyright (C) 2001,2002 Jakob Kemi <jakob.kemi@telia.com>
++ *
+ * Modifications:
+ * Copyright (c) 2009 Kamala Narasimhan - Citrix Systems, Inc.
- *
++ *
+ * Following modifications where made to fit our usecase -
+ * a) Route WMI events to acpid.
+ * b) Remove exports not required for our usecase, remove notification
+ * c) Minor device id issue.
+ * d) Remove GUID parsing code as our usecase does not require supporting
+ * 36 char guid input.
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
-@@ -32,6 +37,7 @@
- #include <linux/types.h>
- #include <linux/list.h>
- #include <linux/acpi.h>
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/list.h>
++#include <linux/acpi.h>
+#include <linux/dmi.h>
- #include <acpi/acpi_bus.h>
- #include <acpi/acpi_drivers.h>
-
-@@ -45,8 +51,6 @@ MODULE_LICENSE("GPL");
- #undef PREFIX
- #define PREFIX "ACPI: WMI: "
-
--static DEFINE_MUTEX(wmi_data_lock);
--
- struct guid_block {
- char guid[16];
- union {
-@@ -64,11 +68,25 @@ struct wmi_block {
- struct list_head list;
- struct guid_block gblock;
- acpi_handle handle;
-- wmi_notify_handler handler;
-- void *handler_data;
- };
-
- static struct wmi_block wmi_blocks;
++#include <acpi/acpi_bus.h>
++#include <acpi/acpi_drivers.h>
++
++ACPI_MODULE_NAME("wmi");
++MODULE_AUTHOR("Carlos Corbacho");
++MODULE_DESCRIPTION("ACPI-WMI Mapping Driver");
++MODULE_LICENSE("GPL");
++
++#define ACPI_WMI_CLASS "wmi"
++
++#undef PREFIX
++#define PREFIX "ACPI: WMI: "
++
++struct guid_block {
++ char guid[16];
++ union {
++ char object_id[2];
++ struct {
++ unsigned char notify_id;
++ unsigned char reserved;
++ };
++ };
++ u8 instance_count;
++ u8 flags;
++};
++
++struct wmi_block {
++ struct list_head list;
++ struct guid_block gblock;
++ acpi_handle handle;
++};
++
++static struct wmi_block wmi_blocks;
+static DEFINE_MUTEX(wmi_mutex);
+
+/*
+const u8 wmi_ec_max_data_size = 32;
+u32 wmi_ec_port_data_size = 0;
+u8 wmi_ec_port_data[32];
-
- /*
- * If the GUID data block is marked as expensive, we must enable and
-@@ -81,11 +99,10 @@ static struct wmi_block wmi_blocks;
-
- static int acpi_wmi_remove(struct acpi_device *device, int type);
- static int acpi_wmi_add(struct acpi_device *device);
--
- static const struct acpi_device_id wmi_device_ids[] = {
-- {"PNP0C14", 0},
-- {"pnp0c14", 0},
-- {"", 0},
++
++/*
++ * If the GUID data block is marked as expensive, we must enable and
++ * explicitily disable data collection.
++ */
++#define ACPI_WMI_EXPENSIVE 0x1
++#define ACPI_WMI_METHOD 0x2 /* GUID is a method */
++#define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */
++#define ACPI_WMI_EVENT 0x8 /* GUID is an event */
++
++static int acpi_wmi_remove(struct acpi_device *device, int type);
++static int acpi_wmi_add(struct acpi_device *device);
++static const struct acpi_device_id wmi_device_ids[] = {
+ {"PNP0C14", 0},
+ {"pnp0c14", 0},
+ {"", 0},
- };
- MODULE_DEVICE_TABLE(acpi, wmi_device_ids);
-
-@@ -99,116 +116,17 @@ static struct acpi_driver acpi_wmi_driver = {
- },
- };
-
--/*
-- * GUID parsing functions
-- */
--
--/**
-- * wmi_parse_hexbyte - Convert a ASCII hex number to a byte
-- * @src: Pointer to at least 2 characters to convert.
-- *
-- * Convert a two character ASCII hex string to a number.
-- *
-- * Return: 0-255 Success, the byte was parsed correctly
-- * -1 Error, an invalid character was supplied
-- */
--static int wmi_parse_hexbyte(const u8 *src)
--{
-- unsigned int x; /* For correct wrapping */
-- int h;
--
-- /* high part */
-- x = src[0];
-- if (x - '0' <= '9' - '0') {
-- h = x - '0';
-- } else if (x - 'a' <= 'f' - 'a') {
-- h = x - 'a' + 10;
-- } else if (x - 'A' <= 'F' - 'A') {
-- h = x - 'A' + 10;
-- } else {
-- return -1;
-- }
-- h <<= 4;
--
-- /* low part */
-- x = src[1];
-- if (x - '0' <= '9' - '0')
-- return h | (x - '0');
-- if (x - 'a' <= 'f' - 'a')
-- return h | (x - 'a' + 10);
-- if (x - 'A' <= 'F' - 'A')
-- return h | (x - 'A' + 10);
-- return -1;
--}
--
--/**
-- * wmi_swap_bytes - Rearrange GUID bytes to match GUID binary
-- * @src: Memory block holding binary GUID (16 bytes)
-- * @dest: Memory block to hold byte swapped binary GUID (16 bytes)
-- *
-- * Byte swap a binary GUID to match it's real GUID value
-- */
--static void wmi_swap_bytes(u8 *src, u8 *dest)
--{
-- int i;
--
-- for (i = 0; i <= 3; i++)
-- memcpy(dest + i, src + (3 - i), 1);
--
-- for (i = 0; i <= 1; i++)
-- memcpy(dest + 4 + i, src + (5 - i), 1);
--
-- for (i = 0; i <= 1; i++)
-- memcpy(dest + 6 + i, src + (7 - i), 1);
--
-- memcpy(dest + 8, src + 8, 8);
--}
--
--/**
-- * wmi_parse_guid - Convert GUID from ASCII to binary
-- * @src: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
-- * @dest: Memory block to hold binary GUID (16 bytes)
-- *
-- * N.B. The GUID need not be NULL terminated.
-- *
-- * Return: 'true' @dest contains binary GUID
-- * 'false' @dest contents are undefined
-- */
--static bool wmi_parse_guid(const u8 *src, u8 *dest)
--{
-- static const int size[] = { 4, 2, 2, 2, 6 };
-- int i, j, v;
--
-- if (src[8] != '-' || src[13] != '-' ||
-- src[18] != '-' || src[23] != '-')
-- return false;
--
-- for (j = 0; j < 5; j++, src++) {
-- for (i = 0; i < size[j]; i++, src += 2, *dest++ = v) {
-- v = wmi_parse_hexbyte(src);
-- if (v < 0)
-- return false;
-- }
-- }
--
-- return true;
--}
--
- static bool find_guid(const char *guid_string, struct wmi_block **out)
- {
-- char tmp[16], guid_input[16];
- struct wmi_block *wblock;
- struct guid_block *block;
- struct list_head *p;
-
-- wmi_parse_guid(guid_string, tmp);
-- wmi_swap_bytes(tmp, guid_input);
--
- list_for_each(p, &wmi_blocks.list) {
- wblock = list_entry(p, struct wmi_block, list);
- block = &wblock->gblock;
-
-- if (memcmp(block->guid, guid_input, 16) == 0) {
++};
++MODULE_DEVICE_TABLE(acpi, wmi_device_ids);
++
++static struct acpi_driver acpi_wmi_driver = {
++ .name = "wmi",
++ .class = ACPI_WMI_CLASS,
++ .ids = wmi_device_ids,
++ .ops = {
++ .add = acpi_wmi_add,
++ .remove = acpi_wmi_remove,
++ },
++};
++
++static bool find_guid(const char *guid_string, struct wmi_block **out)
++{
++ struct wmi_block *wblock;
++ struct guid_block *block;
++ struct list_head *p;
++
++ list_for_each(p, &wmi_blocks.list) {
++ wblock = list_entry(p, struct wmi_block, list);
++ block = &wblock->gblock;
++
+ if (memcmp(block->guid, guid_string, 16) == 0) {
- if (out)
- *out = wblock;
- return 1;
-@@ -217,12 +135,46 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
- return 0;
- }
-
++ if (out)
++ *out = wblock;
++ return 1;
++ }
++ }
++ return 0;
++}
++
+static acpi_status wmi_enable_event_data_blocks(int enable)
+{
+ struct list_head *p;
+ return AE_OK; /* if we don't have a wmi block (though odd), just return success */
+}
+
- /*
- * Exported WMI functions
- */
- /**
- * wmi_evaluate_method - Evaluate a WMI method
-- * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
++/*
++ * Exported WMI functions
++ */
++/**
++ * wmi_evaluate_method - Evaluate a WMI method
+ * @guid_string: 16 byte guid
- * @instance: Instance index
- * @method_id: Method ID to call
- * &in: Buffer containing input for the method call
-@@ -247,7 +199,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
- block = &wblock->gblock;
- handle = wblock->handle;
-
-- if (!(block->flags & ACPI_WMI_METHOD))
++ * @instance: Instance index
++ * @method_id: Method ID to call
++ * &in: Buffer containing input for the method call
++ * &out: Empty buffer to return the method results
++ *
++ * Call an ACPI-WMI method
++ */
++acpi_status wmi_evaluate_method(const char *guid_string, u8 instance,
++u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
++{
++ struct guid_block *block = NULL;
++ struct wmi_block *wblock = NULL;
++ acpi_handle handle;
++ acpi_status status;
++ struct acpi_object_list input;
++ union acpi_object params[3];
++ char method[4] = "WM";
++
++ if (!find_guid(guid_string, &wblock))
++ return AE_BAD_ADDRESS;
++
++ block = &wblock->gblock;
++ handle = wblock->handle;
++
+ if (!(block->flags & ACPI_WMI_METHOD))
- return AE_BAD_DATA;
-
- if (block->instance_count < instance)
-@@ -282,7 +234,7 @@ EXPORT_SYMBOL_GPL(wmi_evaluate_method);
-
- /**
- * wmi_query_block - Return contents of a WMI block
-- * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
++ return AE_BAD_DATA;
++
++ if (block->instance_count < instance)
++ return AE_BAD_PARAMETER;
++
++ input.count = 2;
++ input.pointer = params;
++ params[0].type = ACPI_TYPE_INTEGER;
++ params[0].integer.value = instance;
++ params[1].type = ACPI_TYPE_INTEGER;
++ params[1].integer.value = method_id;
++
++ if (in) {
++ input.count = 3;
++
++ if (block->flags & ACPI_WMI_STRING) {
++ params[2].type = ACPI_TYPE_STRING;
++ } else {
++ params[2].type = ACPI_TYPE_BUFFER;
++ }
++ params[2].buffer.length = in->length;
++ params[2].buffer.pointer = in->pointer;
++ }
++
++ strncat(method, block->object_id, 2);
++
++ status = acpi_evaluate_object(handle, method, &input, out);
++
++ return status;
++}
++EXPORT_SYMBOL_GPL(wmi_evaluate_method);
++
++/**
++ * wmi_query_block - Return contents of a WMI block
+ * @guid_string: 16 byte guid
- * @instance: Instance index
- * &out: Empty buffer to return the contents of the data block to
- *
-@@ -338,10 +290,10 @@ struct acpi_buffer *out)
- * expensive, but have no corresponding WCxx method. So we
- * should not fail if this happens.
- */
-- wc_status = acpi_get_handle(handle, wc_method, &wc_handle);
-- if (ACPI_SUCCESS(wc_status))
-- wc_status = acpi_evaluate_object(handle, wc_method,
-- &wc_input, NULL);
++ * @instance: Instance index
++ * &out: Empty buffer to return the contents of the data block to
++ *
++ * Return the contents of an ACPI-WMI data block to a buffer
++ */
++acpi_status wmi_query_block(const char *guid_string, u8 instance,
++struct acpi_buffer *out)
++{
++ struct guid_block *block = NULL;
++ struct wmi_block *wblock = NULL;
++ acpi_handle handle, wc_handle;
++ acpi_status status, wc_status = AE_ERROR;
++ struct acpi_object_list input, wc_input;
++ union acpi_object wc_params[1], wq_params[1];
++ char method[4];
++ char wc_method[4] = "WC";
++
++ if (!guid_string || !out)
++ return AE_BAD_PARAMETER;
++
++ if (!find_guid(guid_string, &wblock))
++ return AE_BAD_ADDRESS;
++
++ block = &wblock->gblock;
++ handle = wblock->handle;
++
++ if (block->instance_count < instance)
++ return AE_BAD_PARAMETER;
++
++ /* Check GUID is a data block */
++ if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
++ return AE_BAD_ADDRESS;
++
++ input.count = 1;
++ input.pointer = wq_params;
++ wq_params[0].type = ACPI_TYPE_INTEGER;
++ wq_params[0].integer.value = instance;
++
++ /*
++ * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
++ * enable collection.
++ */
++ if (block->flags & ACPI_WMI_EXPENSIVE) {
++ wc_input.count = 1;
++ wc_input.pointer = wc_params;
++ wc_params[0].type = ACPI_TYPE_INTEGER;
++ wc_params[0].integer.value = 1;
++
++ strncat(wc_method, block->object_id, 2);
++
++ /*
++ * Some GUIDs break the specification by declaring themselves
++ * expensive, but have no corresponding WCxx method. So we
++ * should not fail if this happens.
++ */
+ wc_status = acpi_get_handle(handle, wc_method, &wc_handle);
+ if (ACPI_SUCCESS(wc_status))
+ wc_status = acpi_evaluate_object(handle, wc_method,
+ &wc_input, NULL);
- }
-
- strcpy(method, "WQ");
-@@ -365,7 +317,7 @@ EXPORT_SYMBOL_GPL(wmi_query_block);
-
- /**
- * wmi_set_block - Write to a WMI block
-- * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
++ }
++
++ strcpy(method, "WQ");
++ strncat(method, block->object_id, 2);
++
++ status = acpi_evaluate_object(handle, method, &input, out);
++
++ /*
++ * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
++ * the WQxx method failed - we should disable collection anyway.
++ */
++ if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
++ wc_params[0].integer.value = 0;
++ status = acpi_evaluate_object(handle,
++ wc_method, &wc_input, NULL);
++ }
++
++ return status;
++}
++EXPORT_SYMBOL_GPL(wmi_query_block);
++
++/**
++ * wmi_set_block - Write to a WMI block
+ * @guid_string: 16 byte guid
- * @instance: Instance index
- * &in: Buffer containing new values for the data block
- *
-@@ -417,61 +369,6 @@ const struct acpi_buffer *in)
- EXPORT_SYMBOL_GPL(wmi_set_block);
-
- /**
-- * wmi_install_notify_handler - Register handler for WMI events
-- * @handler: Function to handle notifications
-- * @data: Data to be returned to handler when event is fired
-- *
-- * Register a handler for events sent to the ACPI-WMI mapper device.
-- */
--acpi_status wmi_install_notify_handler(const char *guid,
--wmi_notify_handler handler, void *data)
--{
-- struct wmi_block *block;
--
-- if (!guid || !handler)
-- return AE_BAD_PARAMETER;
--
-- find_guid(guid, &block);
-- if (!block)
-- return AE_NOT_EXIST;
--
-- if (block->handler)
-- return AE_ALREADY_ACQUIRED;
--
-- block->handler = handler;
-- block->handler_data = data;
--
-- return AE_OK;
--}
--EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
--
--/**
-- * wmi_uninstall_notify_handler - Unregister handler for WMI events
-- *
-- * Unregister handler for events sent to the ACPI-WMI mapper device.
-- */
--acpi_status wmi_remove_notify_handler(const char *guid)
--{
-- struct wmi_block *block;
--
-- if (!guid)
-- return AE_BAD_PARAMETER;
--
-- find_guid(guid, &block);
-- if (!block)
-- return AE_NOT_EXIST;
--
-- if (!block->handler)
-- return AE_NULL_ENTRY;
--
-- block->handler = NULL;
-- block->handler_data = NULL;
--
-- return AE_OK;
--}
--EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
--
--/**
- * wmi_get_event_data - Get WMI data associated with an event
- *
- * @event - Event to find
-@@ -486,6 +383,8 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
- struct guid_block *gblock;
- struct wmi_block *wblock;
- struct list_head *p;
++ * @instance: Instance index
++ * &in: Buffer containing new values for the data block
++ *
++ * Write the contents of the input buffer to an ACPI-WMI data block
++ */
++acpi_status wmi_set_block(const char *guid_string, u8 instance,
++const struct acpi_buffer *in)
++{
++ struct guid_block *block = NULL;
++ struct wmi_block *wblock = NULL;
++ acpi_handle handle;
++ struct acpi_object_list input;
++ union acpi_object params[2];
++ char method[4] = "WS";
++
++ if (!guid_string || !in)
++ return AE_BAD_DATA;
++
++ if (!find_guid(guid_string, &wblock))
++ return AE_BAD_ADDRESS;
++
++ block = &wblock->gblock;
++ handle = wblock->handle;
++
++ if (block->instance_count < instance)
++ return AE_BAD_PARAMETER;
++
++ /* Check GUID is a data block */
++ if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
++ return AE_BAD_ADDRESS;
++
++ input.count = 2;
++ input.pointer = params;
++ params[0].type = ACPI_TYPE_INTEGER;
++ params[0].integer.value = instance;
++
++ if (block->flags & ACPI_WMI_STRING) {
++ params[1].type = ACPI_TYPE_STRING;
++ } else {
++ params[1].type = ACPI_TYPE_BUFFER;
++ }
++ params[1].buffer.length = in->length;
++ params[1].buffer.pointer = in->pointer;
++
++ strncat(method, block->object_id, 2);
++
++ return acpi_evaluate_object(handle, method, &input, NULL);
++}
++EXPORT_SYMBOL_GPL(wmi_set_block);
++
++/**
++ * wmi_get_event_data - Get WMI data associated with an event
++ *
++ * @event - Event to find
++ * &out - Buffer to hold event data
++ *
++ * Returns extra data associated with an event in WMI.
++ */
++acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
++{
++ struct acpi_object_list input;
++ union acpi_object params[1];
++ struct guid_block *gblock;
++ struct wmi_block *wblock;
++ struct list_head *p;
+ acpi_status status;
+ uint count;
-
- input.count = 1;
- input.pointer = params;
-@@ -497,27 +396,31 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
- gblock = &wblock->gblock;
-
- if ((gblock->flags & ACPI_WMI_EVENT) &&
-- (gblock->notify_id == event))
-- return acpi_evaluate_object(wblock->handle, "_WED",
++
++ input.count = 1;
++ input.pointer = params;
++ params[0].type = ACPI_TYPE_INTEGER;
++ params[0].integer.value = event;
++
++ list_for_each(p, &wmi_blocks.list) {
++ wblock = list_entry(p, struct wmi_block, list);
++ gblock = &wblock->gblock;
++
++ if ((gblock->flags & ACPI_WMI_EVENT) &&
+ (gblock->notify_id == event)) {
+ mutex_lock(&wmi_mutex);
+ if ( enable_wmi_event_data_hack == TRUE ) {
+ in_query_wmi_event_data = TRUE;
+ }
+ status = acpi_evaluate_object(wblock->handle, "_WED",
- &input, out);
++ &input, out);
+ if ( enable_wmi_event_data_hack == TRUE ) {
+ for ( count = 0; count < wmi_ec_port_data_size; count++)
+ ((char *)((union acpi_object *)
+ mutex_unlock(&wmi_mutex);
+ return status;
+ }
- }
-
- return AE_NOT_FOUND;
- }
- EXPORT_SYMBOL_GPL(wmi_get_event_data);
-
--/**
-- * wmi_has_guid - Check if a GUID is available
-- * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
-- *
-- * Check if a given GUID is defined by _WDG
-- */
--bool wmi_has_guid(const char *guid_string)
--{
-- return find_guid(guid_string, NULL);
--}
--EXPORT_SYMBOL_GPL(wmi_has_guid);
--
- /*
- * Parse the _WDG method for the GUID data blocks
- */
-@@ -621,12 +524,7 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
-
- if ((block->flags & ACPI_WMI_EVENT) &&
- (block->notify_id == event)) {
-- if (wblock->handler)
-- wblock->handler(event, wblock->handler_data);
--
-- acpi_bus_generate_netlink_event(
-- device->pnp.device_class, device->dev.bus_id,
-- event, 0);
++ }
++
++ return AE_NOT_FOUND;
++}
++EXPORT_SYMBOL_GPL(wmi_get_event_data);
++
++/*
++ * Parse the _WDG method for the GUID data blocks
++ */
++static __init acpi_status parse_wdg(acpi_handle handle)
++{
++ struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
++ union acpi_object *obj;
++ struct guid_block *gblock;
++ struct wmi_block *wblock;
++ acpi_status status;
++ u32 i, total;
++
++ status = acpi_evaluate_object(handle, "_WDG", NULL, &out);
++
++ if (ACPI_FAILURE(status))
++ return status;
++
++ obj = (union acpi_object *) out.pointer;
++
++ if (obj->type != ACPI_TYPE_BUFFER)
++ return AE_ERROR;
++
++ total = obj->buffer.length / sizeof(struct guid_block);
++
++ gblock = kzalloc(obj->buffer.length, GFP_KERNEL);
++ if (!gblock)
++ return AE_NO_MEMORY;
++
++ memcpy(gblock, obj->buffer.pointer, obj->buffer.length);
++
++ for (i = 0; i < total; i++) {
++ wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
++ if (!wblock)
++ return AE_NO_MEMORY;
++
++ wblock->gblock = gblock[i];
++ wblock->handle = handle;
++ list_add_tail(&wblock->list, &wmi_blocks.list);
++ }
++
++ kfree(out.pointer);
++ kfree(gblock);
++
++ return status;
++}
++
++/*
++ * WMI can have EmbeddedControl access regions. In which case, we just want to
++ * hand these off to the EC driver.
++ */
++static acpi_status
++acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
++ u32 bits, acpi_integer * value,
++ void *handler_context, void *region_context)
++{
++ int result = 0, i = 0;
++ u8 temp = 0;
++
++ if ((address > 0xFF) || !value)
++ return AE_BAD_PARAMETER;
++
++ if (function != ACPI_READ && function != ACPI_WRITE)
++ return AE_BAD_PARAMETER;
++
++ if (bits != 8)
++ return AE_BAD_PARAMETER;
++
++ if (function == ACPI_READ) {
++ result = ec_read(address, &temp);
++ (*value) |= ((acpi_integer)temp) << i;
++ } else {
++ temp = 0xff & ((*value) >> i);
++ result = ec_write(address, temp);
++ }
++
++ switch (result) {
++ case -EINVAL:
++ return AE_BAD_PARAMETER;
++ break;
++ case -ENODEV:
++ return AE_NOT_FOUND;
++ break;
++ case -ETIME:
++ return AE_TIME;
++ break;
++ default:
++ return AE_OK;
++ }
++}
++
++static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
++{
++ struct guid_block *block;
++ struct wmi_block *wblock;
++ struct list_head *p;
++ struct acpi_device *device = data;
++
++ list_for_each(p, &wmi_blocks.list) {
++ wblock = list_entry(p, struct wmi_block, list);
++ block = &wblock->gblock;
++
++ if ((block->flags & ACPI_WMI_EVENT) &&
++ (block->notify_id == event)) {
+ acpi_bus_generate_proc_event(device, event, 0);
- break;
- }
- }
-@@ -640,6 +538,7 @@ static int acpi_wmi_remove(struct acpi_device *device, int type)
- acpi_remove_address_space_handler(device->handle,
- ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
-
++ break;
++ }
++ }
++}
++
++static int acpi_wmi_remove(struct acpi_device *device, int type)
++{
++ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
++ acpi_wmi_notify);
++
++ acpi_remove_address_space_handler(device->handle,
++ ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
++
+ wmi_enable_event_data_blocks(0);
- return 0;
- }
-
-@@ -659,26 +558,33 @@ static int __init acpi_wmi_add(struct acpi_device *device)
- ACPI_ADR_SPACE_EC,
- &acpi_wmi_ec_space_handler,
- NULL, NULL);
-- if (ACPI_FAILURE(status))
++ return 0;
++}
++
++static int __init acpi_wmi_add(struct acpi_device *device)
++{
++ acpi_status status;
++ int result = 0;
++
++ status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
++ acpi_wmi_notify, device);
++ if (ACPI_FAILURE(status)) {
++ printk(KERN_ERR PREFIX "Error installing notify handler\n");
++ return -ENODEV;
++ }
++
++ status = acpi_install_address_space_handler(device->handle,
++ ACPI_ADR_SPACE_EC,
++ &acpi_wmi_ec_space_handler,
++ NULL, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Error installing EC region handler\n");
- return -ENODEV;
++ return -ENODEV;
+ }
-
- status = parse_wdg(device->handle);
- if (ACPI_FAILURE(status)) {
-- printk(KERN_ERR PREFIX "Error installing EC region handler\n");
++
++ status = parse_wdg(device->handle);
++ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "parse_wdg failed!\n");
- return -ENODEV;
- }
-
++ return -ENODEV;
++ }
++
+ /* No need to check and fail if wmi_enable_event_data_blocks should fail.
+ * wmi_enable_event_data_blocks will print an error message.
+ */
+ wmi_enable_event_data_blocks(1);
- return result;
- }
-
- static int __init acpi_wmi_init(void)
- {
- acpi_status result;
++ return result;
++}
++
++static int __init acpi_wmi_init(void)
++{
++ acpi_status result;
+ char *dmi_sys_info;
-
- INIT_LIST_HEAD(&wmi_blocks.list);
-
-- if (acpi_disabled)
-- return -ENODEV;
++
++ INIT_LIST_HEAD(&wmi_blocks.list);
++
+ if (acpi_disabled)
+ return -ENODEV;
-
- result = acpi_bus_register_driver(&acpi_wmi_driver);
-
-@@ -688,6 +594,13 @@ static int __init acpi_wmi_init(void)
- printk(KERN_INFO PREFIX "Mapper loaded\n");
- }
-
++
++ result = acpi_bus_register_driver(&acpi_wmi_driver);
++
++ if (result < 0) {
++ printk(KERN_INFO PREFIX "Error loading mapper\n");
++ } else {
++ printk(KERN_INFO PREFIX "Mapper loaded\n");
++ }
++
+ dmi_sys_info = dmi_get_system_info(DMI_SYS_VENDOR);
+ if ( dmi_sys_info == NULL )
+ return result;
+ if ( strstr(dmi_sys_info, "Dell") != NULL )
+ enable_wmi_event_data_hack = TRUE;
+
- return result;
- }
++ return result;
++}
++
++static void __exit acpi_wmi_exit(void)
++{
++ struct list_head *p, *tmp;
++ struct wmi_block *wblock;
++
++ acpi_bus_unregister_driver(&acpi_wmi_driver);
++
++ list_for_each_safe(p, tmp, &wmi_blocks.list) {
++ wblock = list_entry(p, struct wmi_block, list);
++
++ list_del(p);
++ kfree(wblock);
++ }
++
++ printk(KERN_INFO PREFIX "Mapper unloaded\n");
++}
++
++module_init(acpi_wmi_init);
++module_exit(acpi_wmi_exit);
+diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
+index 191f01b..225cd32 100644
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -856,16 +856,36 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+ */
+ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
+ {
+- const unsigned int forced_release_keys[] = {
+- 0x94,
+- };
+- int i;
++ const unsigned int forced_release_keys[] = {
++ 0x94,
++ };
++ int i;
++
++ if (atkbd->set == 2)
++ for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
++ __set_bit(forced_release_keys[i],
++ atkbd->force_release_mask);
++}
-@@ -708,5 +621,5 @@ static void __exit acpi_wmi_exit(void)
- printk(KERN_INFO PREFIX "Mapper unloaded\n");
+- if (atkbd->set == 2)
+- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
+- __set_bit(forced_release_keys[i],
+- atkbd->force_release_mask);
++#if defined(CONFIG_XEN_ACPI_WMI)
++/*
++ * HP 6930p/2930p generates 0xe001 scancode (Note: 0xe0 being escape code,
++ * the second byte gets or'ed to 0x80 thus ending up as 0x81 below).
++ * We map it to an unused keycode which our qemu code captures to inject
++ * 0xe001 to the Windows guest space. OEM tools will then make further
++ * queries through WMI upon receiving this scancode within guest.
++ */
++static void atkbd_hp_xx30p_keymap_fixup(struct atkbd *atkbd)
++{
++ const unsigned int oem_features_scan_code = 0x81;
++
++ if (atkbd->set == 2)
++ {
++ atkbd->keycode[oem_features_scan_code] = KEY_PROG1;
++ __set_bit(oem_features_scan_code, atkbd->force_release_mask);
++ }
}
++#endif
--subsys_initcall(acpi_wmi_init);
-+module_init(acpi_wmi_init);
- module_exit(acpi_wmi_exit);
+ /*
+ * Inventec system with broken key release on volume keys
+@@ -1519,6 +1539,26 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+ .callback = atkbd_setup_fixup,
+ .driver_data = atkbd_hp_keymap_fixup,
+ },
++#if defined(CONFIG_XEN_ACPI_WMI)
++ {
++ .ident = "HP 6930p",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 6930p"),
++ },
++ .callback = atkbd_setup_fixup,
++ .driver_data = atkbd_hp_xx30p_keymap_fixup,
++ },
++ {
++ .ident = "HP 2530p",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 2530p"),
++ },
++ .callback = atkbd_setup_fixup,
++ .driver_data = atkbd_hp_xx30p_keymap_fixup,
++ },
++#endif
+ {
+ .ident = "Inventec Symphony",
+ .matches = {
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
-index c672d05..a215f63 100644
+index 1d8ef04..1513725 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
-@@ -265,6 +265,13 @@ config XEN_NR_GUEST_DEVICES
- Specify the total number of virtual devices (i.e. both frontend
- and backend) that you want the kernel to be able to service.
+@@ -311,6 +311,20 @@ config XEN_SYSFS
+ help
+ Xen hypervisor attributes will show up under /sys/hypervisor/.
++config XEN_ACPI_WMI_WRAPPER
++ tristate "Xen ACPI WMI wrapper driver"
++ depends on XEN_ACPI_WMI
++ help
++ Facilitates OEM specific hotkey implementation within
++ guest space.
++
+config XEN_ACPI_WMI_WRAPPER
+ tristate "Xen ACPI WMI wrapper driver"
+ depends on ACPI_WMI
prompt "Xen version compatibility"
default XEN_COMPAT_030002_AND_LATER
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
-index ab35228..873e5a3 100644
+index f7a72d3..f41a5cf 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
-@@ -30,3 +30,4 @@ obj-$(CONFIG_XEN_GRANT_DEV) += gntdev/
+@@ -30,4 +30,5 @@ obj-$(CONFIG_XEN_GRANT_DEV) += gntdev/
obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_UTIL) += sfc_netutil/
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/
+ obj-$(CONFIG_XEN_NETCHANNEL2) += netchannel2/
diff --git a/drivers/xen/acpi-wmi/Makefile b/drivers/xen/acpi-wmi/Makefile
new file mode 100644
index 0000000..afe5d9d
+module_exit(xen_wmi_exit);
+MODULE_LICENSE("Dual BSD/GPL");
+
+diff --git a/include/linux/acpi.h b/include/linux/acpi.h
+index b834d34..cd5c2be 100644
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -182,7 +182,7 @@ extern int ec_transaction(u8 command,
+
+ #endif /*CONFIG_ACPI_EC*/
+
+-#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
++#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) || defined(CONFIG_XEN_ACPI_WMI)
+
+ typedef void (*wmi_notify_handler) (u32 value, void *context);
+
diff --git a/include/xen/public/acpi-wmi.h b/include/xen/public/acpi-wmi.h
new file mode 100644
index 0000000..097639b