This source file includes following definitions.
- bmouse_setup
- mouse_interrupt
- fasync_mouse
- close_mouse
- open_mouse
- write_mouse
- read_mouse
- mouse_select
- init_module
- 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 #ifdef MODULE
32 #include <linux/module.h>
33 #include <linux/version.h>
34 #else
35 #define MOD_INC_USE_COUNT
36 #define MOD_DEC_USE_COUNT
37 #endif
38
39 #include <linux/kernel.h>
40 #include <linux/sched.h>
41 #include <linux/busmouse.h>
42 #include <linux/signal.h>
43 #include <linux/errno.h>
44 #include <linux/mm.h>
45
46 #include <asm/io.h>
47 #include <asm/segment.h>
48 #include <asm/system.h>
49 #include <asm/irq.h>
50
51 static struct mouse_status mouse;
52 static int mouse_irq = MOUSE_IRQ;
53
54 void bmouse_setup(char *str, int *ints)
55 {
56 if (ints[0] > 0)
57 mouse_irq=ints[1];
58 }
59
60 static void mouse_interrupt(int irq, struct pt_regs *regs)
61 {
62 char dx, dy;
63 unsigned char buttons;
64
65 MSE_INT_OFF();
66 outb(MSE_READ_X_LOW, MSE_CONTROL_PORT);
67 dx = (inb(MSE_DATA_PORT) & 0xf);
68 outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT);
69 dx |= (inb(MSE_DATA_PORT) & 0xf) << 4;
70 outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT );
71 dy = (inb(MSE_DATA_PORT) & 0xf);
72 outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT);
73 buttons = inb(MSE_DATA_PORT);
74 dy |= (buttons & 0xf) << 4;
75 buttons = ((buttons >> 5) & 0x07);
76 if (dx != 0 || dy != 0 || buttons != mouse.buttons) {
77 mouse.buttons = buttons;
78 mouse.dx += dx;
79 mouse.dy -= dy;
80 mouse.ready = 1;
81 wake_up_interruptible(&mouse.wait);
82
83
84
85
86
87
88 if (mouse.dx < -2048)
89 mouse.dx = -2048;
90 if (mouse.dx > 2048)
91 mouse.dx = 2048;
92
93 if (mouse.dy < -2048)
94 mouse.dy = -2048;
95 if (mouse.dy > 2048)
96 mouse.dy = 2048;
97
98 if (mouse.fasyncptr)
99 kill_fasync(mouse.fasyncptr, SIGIO);
100 }
101 MSE_INT_ON();
102 }
103
104 static int fasync_mouse(struct inode *inode, struct file *filp, int on)
105 {
106 int retval;
107
108 retval = fasync_helper(inode, filp, on, &mouse.fasyncptr);
109 if (retval < 0)
110 return retval;
111 return 0;
112 }
113
114
115
116
117
118
119 static void close_mouse(struct inode * inode, struct file * file)
120 {
121 if (--mouse.active == 0) {
122 MSE_INT_OFF();
123 free_irq(mouse_irq);
124 }
125 fasync_mouse(inode, file, 0);
126 }
127
128
129
130
131
132
133 static int open_mouse(struct inode * inode, struct file * file)
134 {
135 if (!mouse.present)
136 return -EINVAL;
137 if (mouse.active)
138 return -EBUSY;
139 mouse.ready = 0;
140 mouse.dx = 0;
141 mouse.dy = 0;
142 mouse.buttons = 0x87;
143 if (request_irq(mouse_irq, mouse_interrupt, 0, "Busmouse"))
144 return -EBUSY;
145 mouse.active = 1;
146 MSE_INT_ON();
147 return 0;
148 }
149
150
151
152
153
154 static int write_mouse(struct inode * inode, struct file * file, const char * buffer, int count)
155 {
156 return -EINVAL;
157 }
158
159
160
161
162
163 static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count)
164 {
165 int r;
166 int dx;
167 int dy;
168 unsigned char buttons;
169
170 if (count < 3)
171 return -EINVAL;
172 if ((r = verify_area(VERIFY_WRITE, buffer, count)))
173 return r;
174 if (!mouse.ready)
175 return -EAGAIN;
176
177
178
179
180
181
182
183
184 MSE_INT_OFF();
185 dx = mouse.dx;
186 dy = mouse.dy;
187 if (dx < -127)
188 dx = -127;
189 if (dx > 127)
190 dx = 127;
191 if (dy < -127)
192 dy = -127;
193 if (dy > 127)
194 dy = 127;
195 buttons = mouse.buttons;
196 mouse.dx -= dx;
197 mouse.dy -= dy;
198 mouse.ready = 0;
199 MSE_INT_ON();
200
201 put_user(buttons | 0x80, buffer);
202 put_user((char)dx, buffer + 1);
203 put_user((char)dy, buffer + 2);
204 for (r = 3; r < count; r++)
205 put_user(0x00, buffer + r);
206 return r;
207 }
208
209
210
211
212
213
214
215
216 static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
217 {
218 int r = 0;
219
220 if (sel_type == SEL_IN) {
221 MSE_INT_OFF();
222 if (mouse.ready) {
223 r = 1;
224 } else {
225 select_wait(&mouse.wait, wait);
226 }
227 MSE_INT_ON();
228 }
229 return(r);
230 }
231
232 struct file_operations bus_mouse_fops = {
233 NULL,
234 read_mouse,
235 write_mouse,
236 NULL,
237 mouse_select,
238 NULL,
239 NULL,
240 open_mouse,
241 close_mouse,
242 NULL,
243 fasync_mouse,
244 };
245
246 static struct mouse bus_mous = {
247 LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops
248 };
249
250 #ifdef MODULE
251 char kernel_version[] = UTS_RELEASE;
252
253 int init_module(void)
254 #else
255 unsigned long bus_mouse_init(unsigned long kmem_start)
256 #endif
257 {
258 int i;
259
260 outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
261 outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
262 for (i = 0; i < 100000; i++)
263 ;
264 if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
265 mouse.present = 0;
266 #ifdef MODULE
267 return -EIO;
268 #else
269 return kmem_start;
270 #endif
271 }
272 outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
273 MSE_INT_OFF();
274 mouse.present = 1;
275 mouse.active = 0;
276 mouse.ready = 0;
277 mouse.buttons = 0x87;
278 mouse.dx = 0;
279 mouse.dy = 0;
280 mouse.wait = NULL;
281 printk("Logitech Bus mouse detected and installed with IRQ %d.\n",
282 mouse_irq);
283 mouse_register(&bus_mouse);
284 #ifdef MODULE
285 return 0;
286 #else
287 return kmem_start;
288 #endif
289 }
290
291 #ifdef MODULE
292 void cleanup_module(void)
293 {
294 if (MOD_IN_USE)
295 printk("busmouse: in use - remove delayed\n");
296 mouse_deregister(&bus_mouse);
297 }
298 #endif