Modularised mouse support (patch)

Philip Blundell (pjb27@cam.ac.uk)
Fri, 8 Sep 1995 16:04:18 +0100 (BST)


The attached diff (against 1.3.24) modifies the mouse drivers so that
they can be loaded as kernel modules.

I have changed all four drivers (busmouse.c, psaux.c, msbusmouse.c,
atixlmouse.c), but I have only tested busmouse at all. All four compile,
but they may have stupid mistakes. Perhaps somebody with the right
hardware could check them out.

For each driver, you can opt to have it compiled in or loaded as a
module. If you have *any* of the drivers compiled in, you must have
mouse.c compiled in. If all your drivers are modules, you can have
mouse.c as a module. The makefile should deal with this automatically.

--- linux/arch/i386/config.in Fri Sep 8 12:49:45 1995
+++ linux/arch/i386/config.in Fri Sep 8 11:32:51 1995
@@ -264,13 +264,13 @@

bool 'Cyclades async mux support' CONFIG_CYCLADES n
tristate 'Parallel printer support' CONFIG_PRINTER n
-bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
-bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
+tristate 'Logitech busmouse support' CONFIG_BUSMOUSE n
+tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
if [ "$CONFIG_PSMOUSE" = "y" ]; then
bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y
fi
-bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
-bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
+tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
+tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n


bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n
--- linux/drivers/char/Makefile Fri Sep 8 12:49:50 1995
+++ linux/drivers/char/Makefile Fri Sep 8 11:32:07 1995
@@ -24,14 +24,24 @@
L_OBJS += cyclades.o
endif

-ifdef CONFIG_ATIXL_BUSMOUSE
+ifeq ($(CONFIG_ATIXL_BUSMOUSE),y)
M = y
L_OBJS += atixlmouse.o
+else
+ ifeq ($(CONFIG_ATIXL_BUSMOUSE),m)
+ M_OBJS += atixlmouse.o
+ MM = m
+ endif
endif

-ifdef CONFIG_BUSMOUSE
+ifeq ($(CONFIG_BUSMOUSE),y)
M = y
L_OBJS += busmouse.o
+else
+ ifeq ($(CONFIG_BUSMOUSE),m)
+ M_OBJS += busmouse.o
+ MM = m
+ endif
endif

ifeq ($(CONFIG_PRINTER),y)
@@ -42,18 +52,28 @@
endif
endif

-ifdef CONFIG_MS_BUSMOUSE
+ifeq ($(CONFIG_MS_BUSMOUSE),y)
M = y
L_OBJS += msbusmouse.o
+else
+ ifeq ($(CONFIG_MS_BUSMOUSE),m)
+ M_OBJS += msbusmouse.o
+ MM = m
+ endif
endif

ifdef CONFIG_82C710_MOUSE
CONFIG_PSMOUSE = CONFIG_PSMOUSE
endif

-ifdef CONFIG_PSMOUSE
+ifeq ($(CONFIG_PSMOUSE),y)
M = y
L_OBJS += psaux.o
+else
+ ifeq ($(CONFIG_PSMOUSE),m)
+ M_OBJS += psaux.o
+ MM = m
+ endif
endif

ifdef CONFIG_QIC02_TAPE
@@ -62,6 +82,10 @@

ifdef M
L_OBJS += mouse.o
+else
+ ifdef MM
+ M_OBJS += mouse.o
+ endif
endif

ifdef CONFIG_SCC
--- linux/drivers/char/mouse.c Thu Oct 13 13:07:06 1994
+++ linux/drivers/char/mouse.c Fri Sep 8 12:05:00 1995
@@ -12,57 +12,57 @@
*
* 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 <pjb27@cam.ac.uk>
*/

+#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>

-/*
- * note that you can remove any or all of the drivers by undefining
- * the minor values in <linux/mouse.h>
- */
-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;
+typedef struct mouse {
+ struct file_operations *fops;
+ int minor;
+ struct mouse *next;
+} mouse_data;
+
+mouse_data *mouse_list = NULL;

+#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);
+ mouse_data *c = mouse_list;
+ 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) {
+ 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 +78,24 @@
NULL /* release */
};

+void mouse_register(int minor, struct file_operations *fops)
+{
+ mouse_data *new = kmalloc(sizeof(struct mouse), GFP_KERNEL);
+ new->next = mouse_list;
+ new->fops = fops;
+ new->minor = minor;
+ mouse_list = new;
+}
+
+#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 +108,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
--- linux/drivers/char/busmouse.c Tue Aug 1 08:02:32 1995
+++ linux/drivers/char/busmouse.c Fri Sep 8 12:00:28 1995
@@ -21,8 +21,18 @@
* removed assignment chr_fops[10] = &mouse_fops; see mouse.c
* renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
* renamed this file mouse.c => busmouse.c
+ *
+ * Modularised 6-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
*/

+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/busmouse.h>
@@ -214,7 +224,13 @@
close_mouse,
};

+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+
+int init_module(void)
+#else
unsigned long bus_mouse_init(unsigned long kmem_start)
+#endif
{
int i;

@@ -224,7 +240,11 @@
/* busy loop */;
if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
mouse.present = 0;
+#ifdef MODULE
+ return -EIO;
+#else
return kmem_start;
+#endif
}
outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
MSE_INT_OFF();
@@ -237,5 +257,18 @@
mouse.wait = NULL;
printk("Logitech Bus mouse detected and installed with IRQ %d.\n",
mouse_irq);
+ mouse_register(LOGITECH_BUSMOUSE, &bus_mouse_fops);
+#ifdef MODULE
+ return 0;
+#else
return kmem_start;
+#endif
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+ if (MOD_IN_USE)
+ printk("busmouse: in use - remove delayed\n");
}
+#endif
--- linux/drivers/char/psaux.c Fri Sep 8 12:49:50 1995
+++ linux/drivers/char/psaux.c Fri Sep 8 12:05:24 1995
@@ -21,12 +21,22 @@
* & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
*
* Added support for SIGIO. 28Jul95 jem@pandora.pp.fi
+ *
+ * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
*/

/* Uncomment the following line if your mouse needs initialization. */

/* #define INITIALIZE_DEVICE */

+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
@@ -40,6 +50,10 @@

#include <linux/config.h>

+#define PSMOUSE_MINOR 1 /* minor device # for this mouse */
+
+extern void mouse_register(int, struct file_operations *);
+
/* aux controller ports */
#define AUX_INPUT_PORT 0x60 /* Aux device output buffer */
#define AUX_OUTPUT_PORT 0x60 /* Aux device input buffer */
@@ -510,8 +524,13 @@
printk("PS/2 auxiliary pointing device detected -- driver installed.\n");
aux_present = 1;
kbd_read_mask = AUX_OBUF_FULL;
+ mouse_register(PSMOUSE_MINOR, &psaux_fops);
} else {
+#ifdef MODULE
+ return -EIO;
+#else
return kmem_start; /* No mouse at all */
+#endif
}
queue = (struct aux_queue *) kmem_start;
kmem_start += sizeof (struct aux_queue);
@@ -534,8 +553,20 @@
poll_aux_status_nosleep(); /* Disable interrupts */
outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /* on the controller */
}
+#ifdef MODULE
+ return 0;
+#else
return kmem_start;
+#endif
}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+ if (MOD_IN_USE)
+ printk("psaux: in use, remove delayed\n");
+}
+#endif

static int poll_aux_status(void)
{
--- linux/drivers/char/msbusmouse.c Tue Aug 1 08:02:33 1995
+++ linux/drivers/char/msbusmouse.c Fri Sep 8 11:36:57 1995
@@ -25,9 +25,19 @@
* Changed detection code to use inb_p() instead of doing empty
* loops to delay i/o.
*
- * version 0.3a
+ * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
+ *
+ * version 0.3b
*/

+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/busmouse.h>
@@ -144,7 +154,13 @@
release_mouse,
};

+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+
+int init_module(void)
+#else
unsigned long ms_bus_mouse_init(unsigned long kmem_start)
+#endif
{
int mse_byte, i;

@@ -167,9 +183,27 @@
}
}
if (mouse.present == 0) {
+#ifdef MODULE
+ return -EIO;
+#else
return kmem_start;
+#endif
}
MS_MSE_INT_OFF();
printk("Microsoft BusMouse detected and installed.\n");
+ mouse_register(MICROSOFT_BUSMOUSE, &ms_bus_mouse_fops);
+#ifdef MODULE
+ return 0;
+#else
return kmem_start;
+#endif
}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+ if (MOD_IN_USE)
+ printk("msbusmouse: in use, remove delayed\n");
+}
+#endif
+
--- linux/drivers/char/atixlmouse.c Tue Aug 1 08:02:32 1995
+++ linux/drivers/char/atixlmouse.c Fri Sep 8 12:05:46 1995
@@ -5,10 +5,19 @@
* Uses VFS interface for linux 0.98 (01OCT92)
*
* Modified by Chris Colohan (colohan@eecg.toronto.edu)
+ * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
*
- * version 0.3
+ * version 0.3a
*/

+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
@@ -22,6 +31,8 @@
#define ATIXL_MOUSE_IRQ 5 /* H/W interrupt # set up on ATIXL board */
#define ATIXL_BUSMOUSE 3 /* Minor device # (mknod c 10 3 /dev/bm) */

+extern void mouse_register(int, struct file_operations *);
+
/* ATI XL Inport Busmouse Definitions */

#define ATIXL_MSE_DATA_PORT 0x23d
@@ -171,7 +182,13 @@
release_mouse,
};

+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+
+int init_module(void)
+#else
unsigned long atixl_busmouse_init(unsigned long kmem_start)
+#endif
{
unsigned char a,b,c;

@@ -182,7 +199,11 @@
printk("\nATI Inport ");
else{
mouse.present = 0;
+#ifdef MODULE
+ return -EIO;
+#else
return kmem_start;
+#endif
}
outb(0x80, ATIXL_MSE_CONTROL_PORT); /* Reset the Inport device */
outb(0x07, ATIXL_MSE_CONTROL_PORT); /* Select Internal Register 7 */
@@ -194,5 +215,18 @@
mouse.dx = mouse.dy = 0;
mouse.wait = NULL;
printk("Bus mouse detected and installed.\n");
+ mouse_register(ATIXL_BUSMOUSE, &atixl_busmouse_fops);
+#ifdef MODULE
+ return 0;
+#else
return kmem_start;
+#endif
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+ if (MOD_IN_USE)
+ printk("atixlmouse: in use, remove delayed\n");
}
+#endif
--- linux/include/linux/busmouse.h Wed Dec 1 13:44:15 1993
+++ linux/include/linux/busmouse.h Thu Sep 7 19:36:55 1995
@@ -95,6 +95,7 @@

/* Function Prototypes */
extern long mouse_init(long);
+extern void mouse_register(int, struct file_operations *);

#endif

--