[Hotplug_sig] [Lhms-devel] acpi emulation for memory hotplug. [1/3] acpi_sci_emulation.patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I know the almost same patch was in -mm (dropped), but this one is 
given by K.Tokunaga in past.
==

Provide an emulation environment to generate SCI interrupt on ACPI object.

Thanks,
Keiichiro Tokunaga

Signed-off-by: Keiichiro Tokunaga <tokunaga.keiich at jp.fujitsu.com>

Index: linux-2.6.17-rc5-mm2/drivers/acpi/Kconfig
===================================================================
--- linux-2.6.17-rc5-mm2.orig/drivers/acpi/Kconfig	2006-06-07 13:47:34.000000000 +0900
+++ linux-2.6.17-rc5-mm2/drivers/acpi/Kconfig	2006-06-07 13:48:04.000000000 +0900
@@ -379,4 +379,15 @@
 		$>modprobe acpi_memhotplug 
 endif	# ACPI
 
+config ACPI_SCI_EMULATE
+	bool "ACPI SCI Event Emulation Support"
+	depends on ACPI
+	depends on !IA64_SGI_SN
+	default n
+	help
+	  This driver will enable your system to emulate sci hotplug event
+	  notification through proc file system. For example user needs to
+	  echo "XXX 0" > /proc/acpi/sci/notify (where, XXX is a target ACPI
+	  device object name).
+
 endmenu
Index: linux-2.6.17-rc5-mm2/drivers/acpi/bus.c
===================================================================
--- linux-2.6.17-rc5-mm2.orig/drivers/acpi/bus.c	2006-06-07 13:47:34.000000000 +0900
+++ linux-2.6.17-rc5-mm2/drivers/acpi/bus.c	2006-06-07 13:48:04.000000000 +0900
@@ -37,6 +37,20 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#ifdef CONFIG_ACPI_SCI_EMULATE
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/acinterp.h>
+
+static int acpi_init_sci_emulate(void);
+static void acpi_sci_notify_client(char *acpi_name, u32 event);
+static int acpi_sci_notify_write_proc(struct file *file, const char *buffer, \
+	unsigned long count, void *data);
+#else
+#define acpi_init_sci_emulate()
+#endif
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("acpi_bus")
 #ifdef	CONFIG_X86
@@ -49,6 +63,9 @@
 struct acpi_device *acpi_root;
 struct proc_dir_entry *acpi_root_dir;
 EXPORT_SYMBOL(acpi_root_dir);
+#ifdef CONFIG_ACPI_SCI_EMULATE
+struct proc_dir_entry 		*acpi_sci_dir;
+#endif
 
 #define STRUCT_TO_INT(s)	(*((int*)&s))
 
@@ -702,6 +719,8 @@
 	 */
 	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
 
+	acpi_init_sci_emulate();
+
 	return 0;
 
 	/* Mimic structured exception handling */
@@ -745,3 +764,125 @@
 }
 
 subsys_initcall(acpi_init);
+
+#ifdef CONFIG_ACPI_SCI_EMULATE
+/******  Code to emulate SCI interrupt for Hotplug node insertion/removal ******/
+
+static int acpi_sci_notify_write_proc(struct file *file, const char *buffer,
+				      unsigned long count, void *data)
+{
+	u32 event;
+	char *name1 = NULL;
+	char *name2 = NULL;
+	char *end_name = NULL;
+	const char *delim = " ";
+	char *temp_buf = NULL;
+	char *temp_buf_addr = NULL;
+
+	printk(KERN_INFO PREFIX "Inside acpi_sci_notify_write_proc\n");
+
+	temp_buf = kmalloc(count+1, GFP_ATOMIC);
+	if (!temp_buf) {
+		printk(KERN_WARNING PREFIX "Inside acpi_sci_notify_wire_proc: Memory allocation failed\n");
+		return count;
+	}
+	temp_buf[count] = '\0';
+	temp_buf_addr = temp_buf;
+	memcpy(temp_buf, buffer, count);
+	name1 = strsep(&temp_buf, delim);
+	name2 = strsep(&temp_buf, delim);
+
+	if(name1 && name2)
+		event = simple_strtoul(name2, &end_name, 10);
+	else {
+		printk(KERN_WARNING PREFIX "unknown device\n");
+		kfree(temp_buf_addr);
+		return count;
+	}
+
+	printk(KERN_INFO PREFIX "ACPI device name is <%s>, event code is <%d>\n",\
+	       name1, event);
+
+	acpi_sci_notify_client(name1, event);
+
+	kfree(temp_buf_addr);
+
+	return count;
+}
+
+static void acpi_sci_notify_client(char *acpi_name, u32 event)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status, status1;
+	acpi_handle hlsb, hsb;
+	union acpi_operand_object *obj_desc;
+
+	status = acpi_get_handle(NULL, "\\_SB", &hsb);
+	status1 = acpi_get_handle(hsb, acpi_name, &hlsb);
+	if(ACPI_FAILURE(status) || ACPI_FAILURE(status1)){
+		printk(KERN_ERR PREFIX  "acpi getting handle to <\\_SB.%s> failed inside notify_client\n", \
+			acpi_name);
+		return;
+	}
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if(ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Acquiring acpi namespace mutext failed\n");
+		return;
+	}
+
+	node = acpi_ns_map_handle_to_node(hlsb);
+	if(!node) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		printk(KERN_ERR PREFIX "Mapping handle to node failed\n");
+		return;
+	}
+
+	/* Check for internal object and make sure there is a handler registered for this object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if(obj_desc) {
+		if(obj_desc->common_notify.system_notify){
+			/* Release the lock and queue the item for later exectuion */
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			status = acpi_ev_queue_notify_request(node, event);
+			if(ACPI_FAILURE(status)){
+				printk(KERN_ERR PREFIX "acpi_ev_queue_notify_request failed\n");
+			}else {
+				printk(KERN_INFO PREFIX "Notify event is queued\n");
+			}
+			return;
+		}
+	}else {
+		printk(KERN_INFO PREFIX "Notify handler not registered for this device\n");
+	}
+
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return;
+}
+
+
+static int acpi_init_sci_emulate(void)
+{
+	struct proc_dir_entry   *notify_entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_init_sci_emulate");
+
+	acpi_sci_dir = proc_mkdir("sci", acpi_root_dir);
+	if (!acpi_sci_dir)
+		return_VALUE(-ENODEV);
+
+	notify_entry = create_proc_entry("notify", \
+		S_IWUGO|S_IRUGO, acpi_sci_dir);
+	if (!notify_entry) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n", "notify"));
+	} else {
+		notify_entry->write_proc = acpi_sci_notify_write_proc;
+		notify_entry->data = NULL;
+	}
+
+	return_VALUE(0);
+}
+#endif



[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux