patch-1.3.26 linux/drivers/char/mouse.c

Next file: linux/drivers/char/mouse.h
Previous file: linux/drivers/char/busmouse.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.25/linux/drivers/char/mouse.c linux/drivers/char/mouse.c
@@ -12,57 +12,56 @@
  *
  * Made things a lot mode modular - easy to compile in just one or two
  * of the mouse drivers, as they are now completely independent. Linus.
+ *
+ * Support for loadable modules. 8-Sep-95 Philip Blundell <[email protected]>
  */
 
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
 #include <linux/fs.h>
 #include <linux/errno.h>
 #include <linux/mouse.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
+#include <linux/malloc.h>
+
+#include "mouse.h"
 
 /*
- * note that you can remove any or all of the drivers by undefining
- * the minor values in <linux/mouse.h>
+ * Head entry for the doubly linked mouse list
  */
-extern struct file_operations bus_mouse_fops;
-extern struct file_operations psaux_fops;
-extern struct file_operations ms_bus_mouse_fops;
-extern struct file_operations atixl_busmouse_fops;
+static struct mouse mouse_list = { 0, "head", NULL, &mouse_list, &mouse_list };
 
+#ifndef MODULE
 extern unsigned long bus_mouse_init(unsigned long);
 extern unsigned long psaux_init(unsigned long);
 extern unsigned long ms_bus_mouse_init(unsigned long);
 extern unsigned long atixl_busmouse_init(unsigned long);
+#endif
 
 static int mouse_open(struct inode * inode, struct file * file)
 {
 	int minor = MINOR(inode->i_rdev);
+	struct mouse *c = mouse_list.next;
+	file->f_op = NULL;
 
-	switch (minor) {
-#ifdef CONFIG_BUSMOUSE
-		case BUSMOUSE_MINOR:
-	                file->f_op = &bus_mouse_fops;
-	                break;
-#endif
-#if defined CONFIG_PSMOUSE || defined CONFIG_82C710_MOUSE
-		case PSMOUSE_MINOR:
-	                file->f_op = &psaux_fops;
-	                break;
-#endif
-#ifdef CONFIG_MS_BUSMOUSE
-		case MS_BUSMOUSE_MINOR:
-		        file->f_op = &ms_bus_mouse_fops;
-		        break;
-#endif
-#ifdef CONFIG_ATIXL_BUSMOUSE
-		case ATIXL_BUSMOUSE_MINOR:
-			file->f_op = &atixl_busmouse_fops;
+	while (c != &mouse_list) {
+		if (c->minor == minor) {
+			file->f_op = c->fops;
 			break;
-#endif
-		default:
-			return -ENODEV;
+		}
+		c = c->next;
 	}
+
+	if (file->f_op == NULL)
+		return -ENODEV;
         return file->f_op->open(inode,file);
 }
 
@@ -78,8 +77,37 @@
         NULL		/* release */
 };
 
+int mouse_register(struct mouse * mouse)
+{
+	if (mouse->next || mouse->prev)
+		return -EBUSY;
+	mouse->next = &mouse_list;
+	mouse->prev = mouse_list.prev;
+	mouse->prev->next = mouse;
+	mouse->next->prev = mouse;
+	return 0;
+}
+
+int mouse_deregister(struct mouse * mouse)
+{
+	if (!mouse->next || !mouse->prev)
+		return -EINVAL;
+	mouse->prev->next = mouse->next;
+	mouse->next->prev = mouse->prev;
+	mouse->next = NULL;
+	mouse->prev = NULL;
+	return 0;
+}
+
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+
+int init_module(void)
+#else
 unsigned long mouse_init(unsigned long kmem_start)
+#endif
 {
+#ifndef MODULE
 #ifdef CONFIG_BUSMOUSE
 	kmem_start = bus_mouse_init(kmem_start);
 #endif
@@ -92,8 +120,34 @@
 #ifdef CONFIG_ATIXL_BUSMOUSE
  	kmem_start = atixl_busmouse_init(kmem_start);
 #endif
-	if (register_chrdev(MOUSE_MAJOR,"mouse",&mouse_fops))
-		printk("unable to get major %d for mouse devices\n",
-		       MOUSE_MAJOR);
+#endif /* !MODULE */
+	if (register_chrdev(MOUSE_MAJOR,"mouse",&mouse_fops)) {
+	  printk("unable to get major %d for mouse devices\n",
+		 MOUSE_MAJOR);
+#ifdef MODULE
+		return -EIO;
+#endif
+	}
+#ifdef MODULE
+	return 0;
+#else
 	return kmem_start;
+#endif
 }
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+	mouse_data *c = mouse_list, *n;
+	if (MOD_IN_USE) {
+		printk("mouse: in use, remove delayed\n");
+		return;
+	}
+	unregister_chrdev(MOUSE_MAJOR, "mouse");
+	while (c) {
+		n = c->next;
+		kfree(c);
+		c = n;
+	}
+}
+#endif

FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected] with Sam's (original) version
of this