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