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