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