patch-2.4.10 linux/drivers/acpi/ospm/busmgr/bm_osl.c

Next file: linux/drivers/acpi/ospm/busmgr/bmdriver.c
Previous file: linux/drivers/acpi/ospm/busmgr/bm.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.9/linux/drivers/acpi/ospm/busmgr/bm_osl.c linux/drivers/acpi/ospm/busmgr/bm_osl.c
@@ -1,7 +1,7 @@
 /*****************************************************************************
  *
  * Module Name: bm_osl.c
- *   $Revision: 11 $
+ *   $Revision: 16 $
  *
  *****************************************************************************/
 
@@ -30,6 +30,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
+#include <linux/poll.h>
 #include <asm/uaccess.h>
 #include <acpi.h>
 #include "bm.h"
@@ -37,6 +38,7 @@
 
 MODULE_AUTHOR("Andrew Grover");
 MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI Bus Manager");
+MODULE_LICENSE("GPL");
 
 
 #ifdef ACPI_DEBUG
@@ -110,7 +112,7 @@
  *
  ****************************************************************************/
 
-ACPI_STATUS
+acpi_status
 bm_osl_generate_event (
 	BM_HANDLE		device_handle,
 	char			*device_type,
@@ -132,12 +134,12 @@
 	if (!event)
 		goto alloc_error;
 
-	event->device_type = acpi_os_callocate(strlen(device_type) 
+	event->device_type = acpi_os_callocate(strlen(device_type)
 		+ sizeof(char));
 	if (!event->device_type)
 		goto alloc_error;
 
-	event->device_instance = acpi_os_callocate(strlen(device_instance) 
+	event->device_instance = acpi_os_callocate(strlen(device_instance)
 		+ sizeof(char));
 	if (!event->device_instance)
 		goto alloc_error;
@@ -206,71 +208,98 @@
  *
  * FUNCTION:	bm_osl_read_event
  *
- * DESCRIPTION: Handles reads to the 'event' file by blocking user-mode 
+ * DESCRIPTION: Handles reads to the 'event' file by blocking user-mode
  *              threads until data (an event) is generated.
  *
  ****************************************************************************/
 static ssize_t
 bm_osl_read_event(
-	struct file		*file, 
-	char			*buf, 
-	size_t			count, 
+	struct file		*file,
+	char			*buf,
+	size_t			count,
 	loff_t			*ppos)
 {
-	char			str[BM_MAX_STRING_LENGTH];
-	int			size;
 	BM_OSL_EVENT		*event = NULL;
 	unsigned long		flags = 0;
+	static char		str[BM_MAX_STRING_LENGTH];
+	static int		chars_remaining = 0;
+	static char 		*ptr;
 
-	DECLARE_WAITQUEUE(wait, current);
+	if (!chars_remaining) {
+		DECLARE_WAITQUEUE(wait, current);
 
-	if (count < BM_MAX_STRING_LENGTH) {
-		return 0;
-	}
+		if (list_empty(&bm_event_list)) {
 
-	if (list_empty(&bm_event_list)) {
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
 
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&bm_event_wait_queue, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&bm_event_wait_queue, &wait);
 
-		if (list_empty(&bm_event_list)) {
-			schedule();
+			if (list_empty(&bm_event_list)) {
+				schedule();
+			}
+
+			remove_wait_queue(&bm_event_wait_queue, &wait);
+			set_current_state(TASK_RUNNING);
+
+			if (signal_pending(current)) {
+				return -ERESTARTSYS;
+			}
 		}
 
-		remove_wait_queue(&bm_event_wait_queue, &wait);
-		set_current_state(TASK_RUNNING);
+		spin_lock_irqsave(&bm_osl_event_lock, flags);
+		event = list_entry(bm_event_list.next, BM_OSL_EVENT, list);
+		list_del(&event->list);
+		spin_unlock_irqrestore(&bm_osl_event_lock, flags);
+
+		chars_remaining = sprintf(str, "%s %s %08x %08x\n",
+			event->device_type, event->device_instance,
+			event->event_type, event->event_data);
+		ptr = str;
 
-		if (signal_pending(current)) {
-			return -ERESTARTSYS;
-		}
+		acpi_os_free(event->device_type);
+		acpi_os_free(event->device_instance);
+		acpi_os_free(event);
 	}
 
-	spin_lock_irqsave(&bm_osl_event_lock, flags);
-	event = list_entry(bm_event_list.next, BM_OSL_EVENT, list);
-	list_del(&event->list);
-	spin_unlock_irqrestore(&bm_osl_event_lock, flags);
-
-	/* BUG: buffer overrun? */
-	size = sprintf(str, "%s %s %08x %08x\n",
-		event->device_type, event->device_instance,
-		event->event_type, event->event_data);
+	if (chars_remaining < count)
+		count = chars_remaining;
 	
-	acpi_os_free(event->device_type);
-	acpi_os_free(event->device_instance);
-	acpi_os_free(event);
-
-	if (copy_to_user(buf, str, size))
+	if (copy_to_user(buf, ptr, count))
 		return -EFAULT;
 
-	*ppos += size;
+	*ppos += count;
+	chars_remaining -= count;
+	ptr += count;
 
-	return size;
+	return count;
+}
+
+/****************************************************************************
+ *
+ * FUNCTION:	bm_osl_poll_event
+ *
+ * DESCRIPTION: Handles poll() of the 'event' file by blocking user-mode 
+ *              threads until data (an event) is generated.
+ *
+ ****************************************************************************/
+static unsigned int
+bm_osl_poll_event(
+	struct file		*file, 
+	poll_table		*wait)
+{
+	poll_wait(file, &bm_event_wait_queue, wait);
+	if (!list_empty(&bm_event_list))
+		return POLLIN | POLLRDNORM;
+	return 0;
 }
 
 struct file_operations proc_event_operations = {
 	open:		bm_osl_open_event,
 	read:		bm_osl_read_event,
 	release:	bm_osl_close_event,
+	poll:		bm_osl_poll_event,	
 };
 
 /****************************************************************************
@@ -282,7 +311,11 @@
 int
 bm_osl_init(void)
 {
-	ACPI_STATUS		status = AE_OK;
+	acpi_status		status = AE_OK;
+
+	status = acpi_subsystem_status();
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
 
 #ifdef ACPI_DEBUG
 	save_dbg_layer = acpi_dbg_layer;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)