This source file includes following definitions.
- ms_mouse_interrupt
- fasync_mouse
- release_mouse
- open_mouse
- write_mouse
- read_mouse
- mouse_select
- ms_bus_mouse_init
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifdef MODULE
34 #include <linux/module.h>
35 #include <linux/version.h>
36
37 char kernel_version[] = UTS_RELEASE;
38 #define ms_bus_mouse_init init_module
39 #else
40 #define MOD_INC_USE_COUNT
41 #define MOD_DEC_USE_COUNT
42 #endif
43
44 #include <linux/kernel.h>
45 #include <linux/ioport.h>
46 #include <linux/sched.h>
47 #include <linux/busmouse.h>
48 #include <linux/signal.h>
49 #include <linux/errno.h>
50 #include <linux/mouse.h>
51 #include <linux/random.h>
52
53 #include <asm/io.h>
54 #include <asm/segment.h>
55 #include <asm/system.h>
56 #include <asm/irq.h>
57
58 static struct mouse_status mouse;
59
60 static void ms_mouse_interrupt(int irq, struct pt_regs * regs)
61 {
62 char dx, dy;
63 unsigned char buttons;
64
65 outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
66 outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
67
68 outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
69 dx = inb(MS_MSE_DATA_PORT);
70
71 outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
72 dy = inb(MS_MSE_DATA_PORT);
73
74 outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
75 buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
76
77 outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
78 outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
79
80 if (dx != 0 || dy != 0 || buttons != mouse.buttons || ((~buttons) & 0x07)) {
81 add_mouse_randomness((buttons << 16) + (dy << 8) + dx);
82 mouse.buttons = buttons;
83 mouse.dx += dx;
84 mouse.dy += dy;
85 mouse.ready = 1;
86 wake_up_interruptible(&mouse.wait);
87 if (mouse.fasyncptr)
88 kill_fasync(mouse.fasyncptr, SIGIO);
89 }
90 }
91
92 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
93 {
94 int retval;
95
96 retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
97 if (retval < 0)
98 return retval;
99 return 0;
100 }
101
102 static void release_mouse(struct inode * inode, struct file * file)
103 {
104 fasync_mouse(inode, file, 0);
105 if (--mouse.active)
106 return;
107 MS_MSE_INT_OFF();
108 mouse.ready = 0;
109 free_irq(MOUSE_IRQ);
110 MOD_DEC_USE_COUNT;
111 }
112
113 static int open_mouse(struct inode * inode, struct file * file)
114 {
115 if (!mouse.present)
116 return -EINVAL;
117 if (mouse.active++)
118 return 0;
119 if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse")) {
120 mouse.active--;
121 return -EBUSY;
122 }
123 mouse.ready = mouse.dx = mouse.dy = 0;
124 mouse.buttons = 0x80;
125 outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
126 MOD_INC_USE_COUNT;
127 MS_MSE_INT_ON();
128 return 0;
129 }
130
131
132 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
133 {
134 return -EINVAL;
135 }
136
137 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
138 {
139 int i, dx, dy;
140
141 if (count < 3)
142 return -EINVAL;
143 if (!mouse.ready)
144 return -EAGAIN;
145 put_user(mouse.buttons | 0x80, buffer);
146 dx = mouse.dx < -127 ? -127 : mouse.dx > 127 ? 127 : mouse.dx;
147 dy = mouse.dy < -127 ? 127 : mouse.dy > 127 ? -127 : -mouse.dy;
148 put_user((char)dx, buffer + 1);
149 put_user((char)dy, buffer + 2);
150 for (i = 3; i < count; i++)
151 put_user(0x00, buffer + i);
152 mouse.dx -= dx;
153 mouse.dy += dy;
154 mouse.ready = 0;
155 return i;
156 }
157
158 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
159 {
160 if (sel_type != SEL_IN)
161 return 0;
162 if (mouse.ready)
163 return 1;
164 select_wait(&mouse.wait,wait);
165 return 0;
166 }
167
168 struct file_operations ms_bus_mouse_fops = {
169 NULL,
170 read_mouse,
171 write_mouse,
172 NULL,
173 mouse_select,
174 NULL,
175 NULL,
176 open_mouse,
177 release_mouse,
178 NULL,
179 fasync_mouse,
180 };
181
182 static struct mouse ms_bus_mouse = {
183 MICROSOFT_BUSMOUSE, "msbusmouse", &ms_bus_mouse_fops
184 };
185
186 int ms_bus_mouse_init(void)
187 {
188 int mse_byte, i;
189
190 mouse.present = mouse.active = mouse.ready = 0;
191 mouse.buttons = 0x80;
192 mouse.dx = mouse.dy = 0;
193 mouse.wait = NULL;
194
195 if (check_region(MS_MSE_CONTROL_PORT, 0x04))
196 return -ENODEV;
197
198 if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
199
200 mse_byte = inb_p(MS_MSE_SIGNATURE_PORT);
201
202 for (i = 0; i < 4; i++) {
203 if (inb_p(MS_MSE_SIGNATURE_PORT) == 0xde) {
204 if (inb_p(MS_MSE_SIGNATURE_PORT) == mse_byte)
205 mouse.present = 1;
206 else
207 mouse.present = 0;
208 } else
209 mouse.present = 0;
210 }
211 }
212 if (mouse.present == 0)
213 return -EIO;
214 MS_MSE_INT_OFF();
215 request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse");
216 printk("Microsoft BusMouse detected and installed.\n");
217 mouse_register(&ms_bus_mouse);
218 return 0;
219 }
220
221 #ifdef MODULE
222 void cleanup_module(void)
223 {
224 if (MOD_IN_USE) {
225 printk("msbusmouse: in use, remove delayed\n");
226 return;
227 }
228 mouse_deregister(&ms_bus_mouse);
229 release_region(MS_MSE_CONTROL_PORT, 0x04);
230 }
231 #endif
232