aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2007-08-30 00:22:24 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2007-08-30 00:22:24 -0400
commit464b241575f3700e14492e34f26bcd1794280f55 (patch)
treeacbc48b7b7d440b3224b56edcafb7170a33c42e8 /drivers/input
parent6addb1d6de1968b84852f54561cc9a999909b5a9 (diff)
Input: mousedev - implement proper locking
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/mousedev.c742
1 files changed, 470 insertions, 272 deletions
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 9173916b8be5..715def79390c 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -61,9 +61,11 @@ struct mousedev {
61 int open; 61 int open;
62 int minor; 62 int minor;
63 char name[16]; 63 char name[16];
64 struct input_handle handle;
64 wait_queue_head_t wait; 65 wait_queue_head_t wait;
65 struct list_head client_list; 66 struct list_head client_list;
66 struct input_handle handle; 67 spinlock_t client_lock; /* protects client_list */
68 struct mutex mutex;
67 struct device dev; 69 struct device dev;
68 70
69 struct list_head mixdev_node; 71 struct list_head mixdev_node;
@@ -113,108 +115,137 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
113static struct input_handler mousedev_handler; 115static struct input_handler mousedev_handler;
114 116
115static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; 117static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
118static DEFINE_MUTEX(mousedev_table_mutex);
116static struct mousedev *mousedev_mix; 119static struct mousedev *mousedev_mix;
117static LIST_HEAD(mousedev_mix_list); 120static LIST_HEAD(mousedev_mix_list);
118 121
122static void mixdev_open_devices(void);
123static void mixdev_close_devices(void);
124
119#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) 125#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
120#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) 126#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
121 127
122static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) 128static void mousedev_touchpad_event(struct input_dev *dev,
129 struct mousedev *mousedev,
130 unsigned int code, int value)
123{ 131{
124 int size, tmp; 132 int size, tmp;
125 enum { FRACTION_DENOM = 128 }; 133 enum { FRACTION_DENOM = 128 };
126 134
127 switch (code) { 135 switch (code) {
128 case ABS_X:
129 fx(0) = value;
130 if (mousedev->touch && mousedev->pkt_count >= 2) {
131 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
132 if (size == 0)
133 size = 256 * 2;
134 tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size;
135 tmp += mousedev->frac_dx;
136 mousedev->packet.dx = tmp / FRACTION_DENOM;
137 mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM;
138 }
139 break;
140 136
141 case ABS_Y: 137 case ABS_X:
142 fy(0) = value; 138 fx(0) = value;
143 if (mousedev->touch && mousedev->pkt_count >= 2) { 139 if (mousedev->touch && mousedev->pkt_count >= 2) {
144 /* use X size to keep the same scale */ 140 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
145 size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; 141 if (size == 0)
146 if (size == 0) 142 size = 256 * 2;
147 size = 256 * 2; 143 tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
148 tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; 144 tmp += mousedev->frac_dx;
149 tmp += mousedev->frac_dy; 145 mousedev->packet.dx = tmp / FRACTION_DENOM;
150 mousedev->packet.dy = tmp / FRACTION_DENOM; 146 mousedev->frac_dx =
151 mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; 147 tmp - mousedev->packet.dx * FRACTION_DENOM;
152 } 148 }
153 break; 149 break;
150
151 case ABS_Y:
152 fy(0) = value;
153 if (mousedev->touch && mousedev->pkt_count >= 2) {
154 /* use X size to keep the same scale */
155 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
156 if (size == 0)
157 size = 256 * 2;
158 tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
159 tmp += mousedev->frac_dy;
160 mousedev->packet.dy = tmp / FRACTION_DENOM;
161 mousedev->frac_dy = tmp -
162 mousedev->packet.dy * FRACTION_DENOM;
163 }
164 break;
154 } 165 }
155} 166}
156 167
157static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) 168static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
169 unsigned int code, int value)
158{ 170{
159 int size; 171 int size;
160 172
161 switch (code) { 173 switch (code) {
162 case ABS_X:
163 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
164 if (size == 0)
165 size = xres ? : 1;
166 if (value > dev->absmax[ABS_X])
167 value = dev->absmax[ABS_X];
168 if (value < dev->absmin[ABS_X])
169 value = dev->absmin[ABS_X];
170 mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size;
171 mousedev->packet.abs_event = 1;
172 break;
173 174
174 case ABS_Y: 175 case ABS_X:
175 size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; 176 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
176 if (size == 0) 177 if (size == 0)
177 size = yres ? : 1; 178 size = xres ? : 1;
178 if (value > dev->absmax[ABS_Y]) 179 if (value > dev->absmax[ABS_X])
179 value = dev->absmax[ABS_Y]; 180 value = dev->absmax[ABS_X];
180 if (value < dev->absmin[ABS_Y]) 181 if (value < dev->absmin[ABS_X])
181 value = dev->absmin[ABS_Y]; 182 value = dev->absmin[ABS_X];
182 mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; 183 mousedev->packet.x =
183 mousedev->packet.abs_event = 1; 184 ((value - dev->absmin[ABS_X]) * xres) / size;
184 break; 185 mousedev->packet.abs_event = 1;
186 break;
187
188 case ABS_Y:
189 size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
190 if (size == 0)
191 size = yres ? : 1;
192 if (value > dev->absmax[ABS_Y])
193 value = dev->absmax[ABS_Y];
194 if (value < dev->absmin[ABS_Y])
195 value = dev->absmin[ABS_Y];
196 mousedev->packet.y = yres -
197 ((value - dev->absmin[ABS_Y]) * yres) / size;
198 mousedev->packet.abs_event = 1;
199 break;
185 } 200 }
186} 201}
187 202
188static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value) 203static void mousedev_rel_event(struct mousedev *mousedev,
204 unsigned int code, int value)
189{ 205{
190 switch (code) { 206 switch (code) {
191 case REL_X: mousedev->packet.dx += value; break; 207 case REL_X:
192 case REL_Y: mousedev->packet.dy -= value; break; 208 mousedev->packet.dx += value;
193 case REL_WHEEL: mousedev->packet.dz -= value; break; 209 break;
210
211 case REL_Y:
212 mousedev->packet.dy -= value;
213 break;
214
215 case REL_WHEEL:
216 mousedev->packet.dz -= value;
217 break;
194 } 218 }
195} 219}
196 220
197static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value) 221static void mousedev_key_event(struct mousedev *mousedev,
222 unsigned int code, int value)
198{ 223{
199 int index; 224 int index;
200 225
201 switch (code) { 226 switch (code) {
202 case BTN_TOUCH: 227
203 case BTN_0: 228 case BTN_TOUCH:
204 case BTN_LEFT: index = 0; break; 229 case BTN_0:
205 case BTN_STYLUS: 230 case BTN_LEFT: index = 0; break;
206 case BTN_1: 231
207 case BTN_RIGHT: index = 1; break; 232 case BTN_STYLUS:
208 case BTN_2: 233 case BTN_1:
209 case BTN_FORWARD: 234 case BTN_RIGHT: index = 1; break;
210 case BTN_STYLUS2: 235
211 case BTN_MIDDLE: index = 2; break; 236 case BTN_2:
212 case BTN_3: 237 case BTN_FORWARD:
213 case BTN_BACK: 238 case BTN_STYLUS2:
214 case BTN_SIDE: index = 3; break; 239 case BTN_MIDDLE: index = 2; break;
215 case BTN_4: 240
216 case BTN_EXTRA: index = 4; break; 241 case BTN_3:
217 default: return; 242 case BTN_BACK:
243 case BTN_SIDE: index = 3; break;
244
245 case BTN_4:
246 case BTN_EXTRA: index = 4; break;
247
248 default: return;
218 } 249 }
219 250
220 if (value) { 251 if (value) {
@@ -226,19 +257,22 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int
226 } 257 }
227} 258}
228 259
229static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) 260static void mousedev_notify_readers(struct mousedev *mousedev,
261 struct mousedev_hw_data *packet)
230{ 262{
231 struct mousedev_client *client; 263 struct mousedev_client *client;
232 struct mousedev_motion *p; 264 struct mousedev_motion *p;
233 unsigned long flags; 265 unsigned int new_head;
234 int wake_readers = 0; 266 int wake_readers = 0;
235 267
236 list_for_each_entry(client, &mousedev->client_list, node) { 268 list_for_each_entry_rcu(client, &mousedev->client_list, node) {
237 spin_lock_irqsave(&client->packet_lock, flags); 269
270 /* Just acquire the lock, interrupts already disabled */
271 spin_lock(&client->packet_lock);
238 272
239 p = &client->packets[client->head]; 273 p = &client->packets[client->head];
240 if (client->ready && p->buttons != mousedev->packet.buttons) { 274 if (client->ready && p->buttons != mousedev->packet.buttons) {
241 unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN; 275 new_head = (client->head + 1) % PACKET_QUEUE_LEN;
242 if (new_head != client->tail) { 276 if (new_head != client->tail) {
243 p = &client->packets[client->head = new_head]; 277 p = &client->packets[client->head = new_head];
244 memset(p, 0, sizeof(struct mousedev_motion)); 278 memset(p, 0, sizeof(struct mousedev_motion));
@@ -253,19 +287,22 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h
253 } 287 }
254 288
255 client->pos_x += packet->dx; 289 client->pos_x += packet->dx;
256 client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); 290 client->pos_x = client->pos_x < 0 ?
291 0 : (client->pos_x >= xres ? xres : client->pos_x);
257 client->pos_y += packet->dy; 292 client->pos_y += packet->dy;
258 client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); 293 client->pos_y = client->pos_y < 0 ?
294 0 : (client->pos_y >= yres ? yres : client->pos_y);
259 295
260 p->dx += packet->dx; 296 p->dx += packet->dx;
261 p->dy += packet->dy; 297 p->dy += packet->dy;
262 p->dz += packet->dz; 298 p->dz += packet->dz;
263 p->buttons = mousedev->packet.buttons; 299 p->buttons = mousedev->packet.buttons;
264 300
265 if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) 301 if (p->dx || p->dy || p->dz ||
302 p->buttons != client->last_buttons)
266 client->ready = 1; 303 client->ready = 1;
267 304
268 spin_unlock_irqrestore(&client->packet_lock, flags); 305 spin_unlock(&client->packet_lock);
269 306
270 if (client->ready) { 307 if (client->ready) {
271 kill_fasync(&client->fasync, SIGIO, POLL_IN); 308 kill_fasync(&client->fasync, SIGIO, POLL_IN);
@@ -281,7 +318,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
281{ 318{
282 if (!value) { 319 if (!value) {
283 if (mousedev->touch && 320 if (mousedev->touch &&
284 time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) { 321 time_before(jiffies,
322 mousedev->touch + msecs_to_jiffies(tap_time))) {
285 /* 323 /*
286 * Toggle left button to emulate tap. 324 * Toggle left button to emulate tap.
287 * We rely on the fact that mousedev_mix always has 0 325 * We rely on the fact that mousedev_mix always has 0
@@ -290,7 +328,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
290 set_bit(0, &mousedev->packet.buttons); 328 set_bit(0, &mousedev->packet.buttons);
291 set_bit(0, &mousedev_mix->packet.buttons); 329 set_bit(0, &mousedev_mix->packet.buttons);
292 mousedev_notify_readers(mousedev, &mousedev_mix->packet); 330 mousedev_notify_readers(mousedev, &mousedev_mix->packet);
293 mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet); 331 mousedev_notify_readers(mousedev_mix,
332 &mousedev_mix->packet);
294 clear_bit(0, &mousedev->packet.buttons); 333 clear_bit(0, &mousedev->packet.buttons);
295 clear_bit(0, &mousedev_mix->packet.buttons); 334 clear_bit(0, &mousedev_mix->packet.buttons);
296 } 335 }
@@ -302,54 +341,61 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
302 mousedev->touch = jiffies; 341 mousedev->touch = jiffies;
303} 342}
304 343
305static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 344static void mousedev_event(struct input_handle *handle,
345 unsigned int type, unsigned int code, int value)
306{ 346{
307 struct mousedev *mousedev = handle->private; 347 struct mousedev *mousedev = handle->private;
308 348
309 switch (type) { 349 switch (type) {
310 case EV_ABS:
311 /* Ignore joysticks */
312 if (test_bit(BTN_TRIGGER, handle->dev->keybit))
313 return;
314 350
315 if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) 351 case EV_ABS:
316 mousedev_touchpad_event(handle->dev, mousedev, code, value); 352 /* Ignore joysticks */
317 else 353 if (test_bit(BTN_TRIGGER, handle->dev->keybit))
318 mousedev_abs_event(handle->dev, mousedev, code, value); 354 return;
319 355
320 break; 356 if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
357 mousedev_touchpad_event(handle->dev,
358 mousedev, code, value);
359 else
360 mousedev_abs_event(handle->dev, mousedev, code, value);
321 361
322 case EV_REL: 362 break;
323 mousedev_rel_event(mousedev, code, value);
324 break;
325 363
326 case EV_KEY: 364 case EV_REL:
327 if (value != 2) { 365 mousedev_rel_event(mousedev, code, value);
328 if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) 366 break;
329 mousedev_touchpad_touch(mousedev, value);
330 else
331 mousedev_key_event(mousedev, code, value);
332 }
333 break;
334 367
335 case EV_SYN: 368 case EV_KEY:
336 if (code == SYN_REPORT) { 369 if (value != 2) {
337 if (mousedev->touch) { 370 if (code == BTN_TOUCH &&
338 mousedev->pkt_count++; 371 test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
339 /* Input system eats duplicate events, but we need all of them 372 mousedev_touchpad_touch(mousedev, value);
340 * to do correct averaging so apply present one forward 373 else
341 */ 374 mousedev_key_event(mousedev, code, value);
342 fx(0) = fx(1); 375 }
343 fy(0) = fy(1); 376 break;
344 } 377
345 378 case EV_SYN:
346 mousedev_notify_readers(mousedev, &mousedev->packet); 379 if (code == SYN_REPORT) {
347 mousedev_notify_readers(mousedev_mix, &mousedev->packet); 380 if (mousedev->touch) {
348 381 mousedev->pkt_count++;
349 mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; 382 /*
350 mousedev->packet.abs_event = 0; 383 * Input system eats duplicate events,
384 * but we need all of them to do correct
385 * averaging so apply present one forward
386 */
387 fx(0) = fx(1);
388 fy(0) = fy(1);
351 } 389 }
352 break; 390
391 mousedev_notify_readers(mousedev, &mousedev->packet);
392 mousedev_notify_readers(mousedev_mix, &mousedev->packet);
393
394 mousedev->packet.dx = mousedev->packet.dy =
395 mousedev->packet.dz = 0;
396 mousedev->packet.abs_event = 0;
397 }
398 break;
353 } 399 }
354} 400}
355 401
@@ -367,41 +413,45 @@ static void mousedev_free(struct device *dev)
367{ 413{
368 struct mousedev *mousedev = container_of(dev, struct mousedev, dev); 414 struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
369 415
370 mousedev_table[mousedev->minor] = NULL;
371 kfree(mousedev); 416 kfree(mousedev);
372} 417}
373 418
374static int mixdev_add_device(struct mousedev *mousedev) 419static int mousedev_open_device(struct mousedev *mousedev)
375{ 420{
376 int error; 421 int retval;
377
378 if (mousedev_mix->open) {
379 error = input_open_device(&mousedev->handle);
380 if (error)
381 return error;
382 422
383 mousedev->open++; 423 retval = mutex_lock_interruptible(&mousedev->mutex);
384 mousedev->mixdev_open = 1; 424 if (retval)
385 } 425 return retval;
386 426
387 get_device(&mousedev->dev); 427 if (mousedev->minor == MOUSEDEV_MIX)
388 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); 428 mixdev_open_devices();
429 else if (!mousedev->exist)
430 retval = -ENODEV;
431 else if (!mousedev->open++)
432 retval = input_open_device(&mousedev->handle);
389 433
390 return 0; 434 mutex_unlock(&mousedev->mutex);
435 return retval;
391} 436}
392 437
393static void mixdev_remove_device(struct mousedev *mousedev) 438static void mousedev_close_device(struct mousedev *mousedev)
394{ 439{
395 if (mousedev->mixdev_open) { 440 mutex_lock(&mousedev->mutex);
396 mousedev->mixdev_open = 0;
397 if (!--mousedev->open && mousedev->exist)
398 input_close_device(&mousedev->handle);
399 }
400 441
401 list_del_init(&mousedev->mixdev_node); 442 if (mousedev->minor == MOUSEDEV_MIX)
402 put_device(&mousedev->dev); 443 mixdev_close_devices();
444 else if (mousedev->exist && !--mousedev->open)
445 input_close_device(&mousedev->handle);
446
447 mutex_unlock(&mousedev->mutex);
403} 448}
404 449
450/*
451 * Open all available devices so they can all be multiplexed in one.
452 * stream. Note that this function is called with mousedev_mix->mutex
453 * held.
454 */
405static void mixdev_open_devices(void) 455static void mixdev_open_devices(void)
406{ 456{
407 struct mousedev *mousedev; 457 struct mousedev *mousedev;
@@ -411,16 +461,19 @@ static void mixdev_open_devices(void)
411 461
412 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 462 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
413 if (!mousedev->mixdev_open) { 463 if (!mousedev->mixdev_open) {
414 if (!mousedev->open && mousedev->exist) 464 if (mousedev_open_device(mousedev))
415 if (input_open_device(&mousedev->handle)) 465 continue;
416 continue;
417 466
418 mousedev->open++;
419 mousedev->mixdev_open = 1; 467 mousedev->mixdev_open = 1;
420 } 468 }
421 } 469 }
422} 470}
423 471
472/*
473 * Close all devices that were opened as part of multiplexed
474 * device. Note that this function is called with mousedev_mix->mutex
475 * held.
476 */
424static void mixdev_close_devices(void) 477static void mixdev_close_devices(void)
425{ 478{
426 struct mousedev *mousedev; 479 struct mousedev *mousedev;
@@ -431,33 +484,50 @@ static void mixdev_close_devices(void)
431 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 484 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
432 if (mousedev->mixdev_open) { 485 if (mousedev->mixdev_open) {
433 mousedev->mixdev_open = 0; 486 mousedev->mixdev_open = 0;
434 if (!--mousedev->open && mousedev->exist) 487 mousedev_close_device(mousedev);
435 input_close_device(&mousedev->handle);
436 } 488 }
437 } 489 }
438} 490}
439 491
492
493static void mousedev_attach_client(struct mousedev *mousedev,
494 struct mousedev_client *client)
495{
496 spin_lock(&mousedev->client_lock);
497 list_add_tail_rcu(&client->node, &mousedev->client_list);
498 spin_unlock(&mousedev->client_lock);
499 /*
500 * We don't use synchronize_rcu() here because read-side
501 * critical section is protected by a spinlock (dev->event_lock)
502 * instead of rcu_read_lock().
503 */
504 synchronize_sched();
505}
506
507static void mousedev_detach_client(struct mousedev *mousedev,
508 struct mousedev_client *client)
509{
510 spin_lock(&mousedev->client_lock);
511 list_del_rcu(&client->node);
512 spin_unlock(&mousedev->client_lock);
513 synchronize_sched();
514}
515
440static int mousedev_release(struct inode *inode, struct file *file) 516static int mousedev_release(struct inode *inode, struct file *file)
441{ 517{
442 struct mousedev_client *client = file->private_data; 518 struct mousedev_client *client = file->private_data;
443 struct mousedev *mousedev = client->mousedev; 519 struct mousedev *mousedev = client->mousedev;
444 520
445 mousedev_fasync(-1, file, 0); 521 mousedev_fasync(-1, file, 0);
446 522 mousedev_detach_client(mousedev, client);
447 list_del(&client->node);
448 kfree(client); 523 kfree(client);
449 524
450 if (mousedev->minor == MOUSEDEV_MIX) 525 mousedev_close_device(mousedev);
451 mixdev_close_devices();
452 else if (!--mousedev->open && mousedev->exist)
453 input_close_device(&mousedev->handle);
454
455 put_device(&mousedev->dev); 526 put_device(&mousedev->dev);
456 527
457 return 0; 528 return 0;
458} 529}
459 530
460
461static int mousedev_open(struct inode *inode, struct file *file) 531static int mousedev_open(struct inode *inode, struct file *file)
462{ 532{
463 struct mousedev_client *client; 533 struct mousedev_client *client;
@@ -475,12 +545,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
475 if (i >= MOUSEDEV_MINORS) 545 if (i >= MOUSEDEV_MINORS)
476 return -ENODEV; 546 return -ENODEV;
477 547
548 error = mutex_lock_interruptible(&mousedev_table_mutex);
549 if (error)
550 return error;
478 mousedev = mousedev_table[i]; 551 mousedev = mousedev_table[i];
552 if (mousedev)
553 get_device(&mousedev->dev);
554 mutex_unlock(&mousedev_table_mutex);
555
479 if (!mousedev) 556 if (!mousedev)
480 return -ENODEV; 557 return -ENODEV;
481 558
482 get_device(&mousedev->dev);
483
484 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); 559 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
485 if (!client) { 560 if (!client) {
486 error = -ENOMEM; 561 error = -ENOMEM;
@@ -491,21 +566,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
491 client->pos_x = xres / 2; 566 client->pos_x = xres / 2;
492 client->pos_y = yres / 2; 567 client->pos_y = yres / 2;
493 client->mousedev = mousedev; 568 client->mousedev = mousedev;
494 list_add_tail(&client->node, &mousedev->client_list); 569 mousedev_attach_client(mousedev, client);
495 570
496 if (mousedev->minor == MOUSEDEV_MIX) 571 error = mousedev_open_device(mousedev);
497 mixdev_open_devices(); 572 if (error)
498 else if (!mousedev->open++ && mousedev->exist) { 573 goto err_free_client;
499 error = input_open_device(&mousedev->handle);
500 if (error)
501 goto err_free_client;
502 }
503 574
504 file->private_data = client; 575 file->private_data = client;
505 return 0; 576 return 0;
506 577
507 err_free_client: 578 err_free_client:
508 list_del(&client->node); 579 mousedev_detach_client(mousedev, client);
509 kfree(client); 580 kfree(client);
510 err_put_mousedev: 581 err_put_mousedev:
511 put_device(&mousedev->dev); 582 put_device(&mousedev->dev);
@@ -517,41 +588,41 @@ static inline int mousedev_limit_delta(int delta, int limit)
517 return delta > limit ? limit : (delta < -limit ? -limit : delta); 588 return delta > limit ? limit : (delta < -limit ? -limit : delta);
518} 589}
519 590
520static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) 591static void mousedev_packet(struct mousedev_client *client,
592 signed char *ps2_data)
521{ 593{
522 struct mousedev_motion *p; 594 struct mousedev_motion *p = &client->packets[client->tail];
523 unsigned long flags;
524
525 spin_lock_irqsave(&client->packet_lock, flags);
526 p = &client->packets[client->tail];
527 595
528 ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); 596 ps2_data[0] = 0x08 |
597 ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
529 ps2_data[1] = mousedev_limit_delta(p->dx, 127); 598 ps2_data[1] = mousedev_limit_delta(p->dx, 127);
530 ps2_data[2] = mousedev_limit_delta(p->dy, 127); 599 ps2_data[2] = mousedev_limit_delta(p->dy, 127);
531 p->dx -= ps2_data[1]; 600 p->dx -= ps2_data[1];
532 p->dy -= ps2_data[2]; 601 p->dy -= ps2_data[2];
533 602
534 switch (client->mode) { 603 switch (client->mode) {
535 case MOUSEDEV_EMUL_EXPS: 604 case MOUSEDEV_EMUL_EXPS:
536 ps2_data[3] = mousedev_limit_delta(p->dz, 7); 605 ps2_data[3] = mousedev_limit_delta(p->dz, 7);
537 p->dz -= ps2_data[3]; 606 p->dz -= ps2_data[3];
538 ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); 607 ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
539 client->bufsiz = 4; 608 client->bufsiz = 4;
540 break; 609 break;
541 610
542 case MOUSEDEV_EMUL_IMPS: 611 case MOUSEDEV_EMUL_IMPS:
543 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); 612 ps2_data[0] |=
544 ps2_data[3] = mousedev_limit_delta(p->dz, 127); 613 ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
545 p->dz -= ps2_data[3]; 614 ps2_data[3] = mousedev_limit_delta(p->dz, 127);
546 client->bufsiz = 4; 615 p->dz -= ps2_data[3];
547 break; 616 client->bufsiz = 4;
548 617 break;
549 case MOUSEDEV_EMUL_PS2: 618
550 default: 619 case MOUSEDEV_EMUL_PS2:
551 ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); 620 default:
552 p->dz = 0; 621 ps2_data[0] |=
553 client->bufsiz = 3; 622 ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
554 break; 623 p->dz = 0;
624 client->bufsiz = 3;
625 break;
555 } 626 }
556 627
557 if (!p->dx && !p->dy && !p->dz) { 628 if (!p->dx && !p->dy && !p->dz) {
@@ -561,12 +632,56 @@ static void mousedev_packet(struct mousedev_client *client, signed char *ps2_dat
561 } else 632 } else
562 client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; 633 client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
563 } 634 }
564
565 spin_unlock_irqrestore(&client->packet_lock, flags);
566} 635}
567 636
637static void mousedev_generate_response(struct mousedev_client *client,
638 int command)
639{
640 client->ps2[0] = 0xfa; /* ACK */
568 641
569static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 642 switch (command) {
643
644 case 0xeb: /* Poll */
645 mousedev_packet(client, &client->ps2[1]);
646 client->bufsiz++; /* account for leading ACK */
647 break;
648
649 case 0xf2: /* Get ID */
650 switch (client->mode) {
651 case MOUSEDEV_EMUL_PS2:
652 client->ps2[1] = 0;
653 break;
654 case MOUSEDEV_EMUL_IMPS:
655 client->ps2[1] = 3;
656 break;
657 case MOUSEDEV_EMUL_EXPS:
658 client->ps2[1] = 4;
659 break;
660 }
661 client->bufsiz = 2;
662 break;
663
664 case 0xe9: /* Get info */
665 client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
666 client->bufsiz = 4;
667 break;
668
669 case 0xff: /* Reset */
670 client->impsseq = client->imexseq = 0;
671 client->mode = MOUSEDEV_EMUL_PS2;
672 client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
673 client->bufsiz = 3;
674 break;
675
676 default:
677 client->bufsiz = 1;
678 break;
679 }
680 client->buffer = client->bufsiz;
681}
682
683static ssize_t mousedev_write(struct file *file, const char __user *buffer,
684 size_t count, loff_t *ppos)
570{ 685{
571 struct mousedev_client *client = file->private_data; 686 struct mousedev_client *client = file->private_data;
572 unsigned char c; 687 unsigned char c;
@@ -577,6 +692,8 @@ static ssize_t mousedev_write(struct file *file, const char __user *buffer, size
577 if (get_user(c, buffer + i)) 692 if (get_user(c, buffer + i))
578 return -EFAULT; 693 return -EFAULT;
579 694
695 spin_lock_irq(&client->packet_lock);
696
580 if (c == mousedev_imex_seq[client->imexseq]) { 697 if (c == mousedev_imex_seq[client->imexseq]) {
581 if (++client->imexseq == MOUSEDEV_SEQ_LEN) { 698 if (++client->imexseq == MOUSEDEV_SEQ_LEN) {
582 client->imexseq = 0; 699 client->imexseq = 0;
@@ -593,68 +710,39 @@ static ssize_t mousedev_write(struct file *file, const char __user *buffer, size
593 } else 710 } else
594 client->impsseq = 0; 711 client->impsseq = 0;
595 712
596 client->ps2[0] = 0xfa; 713 mousedev_generate_response(client, c);
597
598 switch (c) {
599
600 case 0xeb: /* Poll */
601 mousedev_packet(client, &client->ps2[1]);
602 client->bufsiz++; /* account for leading ACK */
603 break;
604
605 case 0xf2: /* Get ID */
606 switch (client->mode) {
607 case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break;
608 case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break;
609 case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break;
610 }
611 client->bufsiz = 2;
612 break;
613
614 case 0xe9: /* Get info */
615 client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
616 client->bufsiz = 4;
617 break;
618
619 case 0xff: /* Reset */
620 client->impsseq = client->imexseq = 0;
621 client->mode = MOUSEDEV_EMUL_PS2;
622 client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
623 client->bufsiz = 3;
624 break;
625
626 default:
627 client->bufsiz = 1;
628 break;
629 }
630 714
631 client->buffer = client->bufsiz; 715 spin_unlock_irq(&client->packet_lock);
632 } 716 }
633 717
634 kill_fasync(&client->fasync, SIGIO, POLL_IN); 718 kill_fasync(&client->fasync, SIGIO, POLL_IN);
635
636 wake_up_interruptible(&client->mousedev->wait); 719 wake_up_interruptible(&client->mousedev->wait);
637 720
638 return count; 721 return count;
639} 722}
640 723
641static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 724static ssize_t mousedev_read(struct file *file, char __user *buffer,
725 size_t count, loff_t *ppos)
642{ 726{
643 struct mousedev_client *client = file->private_data; 727 struct mousedev_client *client = file->private_data;
728 struct mousedev *mousedev = client->mousedev;
729 signed char data[sizeof(client->ps2)];
644 int retval = 0; 730 int retval = 0;
645 731
646 if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK)) 732 if (!client->ready && !client->buffer && mousedev->exist &&
733 (file->f_flags & O_NONBLOCK))
647 return -EAGAIN; 734 return -EAGAIN;
648 735
649 retval = wait_event_interruptible(client->mousedev->wait, 736 retval = wait_event_interruptible(mousedev->wait,
650 !client->mousedev->exist || client->ready || client->buffer); 737 !mousedev->exist || client->ready || client->buffer);
651
652 if (retval) 738 if (retval)
653 return retval; 739 return retval;
654 740
655 if (!client->mousedev->exist) 741 if (!mousedev->exist)
656 return -ENODEV; 742 return -ENODEV;
657 743
744 spin_lock_irq(&client->packet_lock);
745
658 if (!client->buffer && client->ready) { 746 if (!client->buffer && client->ready) {
659 mousedev_packet(client, client->ps2); 747 mousedev_packet(client, client->ps2);
660 client->buffer = client->bufsiz; 748 client->buffer = client->bufsiz;
@@ -663,9 +751,12 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t coun
663 if (count > client->buffer) 751 if (count > client->buffer)
664 count = client->buffer; 752 count = client->buffer;
665 753
754 memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
666 client->buffer -= count; 755 client->buffer -= count;
667 756
668 if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count)) 757 spin_unlock_irq(&client->packet_lock);
758
759 if (copy_to_user(buffer, data, count))
669 return -EFAULT; 760 return -EFAULT;
670 761
671 return count; 762 return count;
@@ -692,6 +783,60 @@ static const struct file_operations mousedev_fops = {
692 .fasync = mousedev_fasync, 783 .fasync = mousedev_fasync,
693}; 784};
694 785
786static int mousedev_install_chrdev(struct mousedev *mousedev)
787{
788 mousedev_table[mousedev->minor] = mousedev;
789 return 0;
790}
791
792static void mousedev_remove_chrdev(struct mousedev *mousedev)
793{
794 mutex_lock(&mousedev_table_mutex);
795 mousedev_table[mousedev->minor] = NULL;
796 mutex_unlock(&mousedev_table_mutex);
797}
798
799/*
800 * Mark device non-existent. This disables writes, ioctls and
801 * prevents new users from opening the device. Already posted
802 * blocking reads will stay, however new ones will fail.
803 */
804static void mousedev_mark_dead(struct mousedev *mousedev)
805{
806 mutex_lock(&mousedev->mutex);
807 mousedev->exist = 0;
808 mutex_unlock(&mousedev->mutex);
809}
810
811/*
812 * Wake up users waiting for IO so they can disconnect from
813 * dead device.
814 */
815static void mousedev_hangup(struct mousedev *mousedev)
816{
817 struct mousedev_client *client;
818
819 spin_lock(&mousedev->client_lock);
820 list_for_each_entry(client, &mousedev->client_list, node)
821 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
822 spin_unlock(&mousedev->client_lock);
823
824 wake_up_interruptible(&mousedev->wait);
825}
826
827static void mousedev_cleanup(struct mousedev *mousedev)
828{
829 struct input_handle *handle = &mousedev->handle;
830
831 mousedev_mark_dead(mousedev);
832 mousedev_hangup(mousedev);
833 mousedev_remove_chrdev(mousedev);
834
835 /* mousedev is marked dead so no one else accesses mousedev->open */
836 if (mousedev->open)
837 input_close_device(handle);
838}
839
695static struct mousedev *mousedev_create(struct input_dev *dev, 840static struct mousedev *mousedev_create(struct input_dev *dev,
696 struct input_handler *handler, 841 struct input_handler *handler,
697 int minor) 842 int minor)
@@ -707,6 +852,10 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
707 852
708 INIT_LIST_HEAD(&mousedev->client_list); 853 INIT_LIST_HEAD(&mousedev->client_list);
709 INIT_LIST_HEAD(&mousedev->mixdev_node); 854 INIT_LIST_HEAD(&mousedev->mixdev_node);
855 spin_lock_init(&mousedev->client_lock);
856 mutex_init(&mousedev->mutex);
857 lockdep_set_subclass(&mousedev->mutex,
858 minor == MOUSEDEV_MIX ? MOUSEDEV_MIX : 0);
710 init_waitqueue_head(&mousedev->wait); 859 init_waitqueue_head(&mousedev->wait);
711 860
712 if (minor == MOUSEDEV_MIX) 861 if (minor == MOUSEDEV_MIX)
@@ -731,14 +880,27 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
731 mousedev->dev.release = mousedev_free; 880 mousedev->dev.release = mousedev_free;
732 device_initialize(&mousedev->dev); 881 device_initialize(&mousedev->dev);
733 882
734 mousedev_table[minor] = mousedev; 883 if (minor != MOUSEDEV_MIX) {
884 error = input_register_handle(&mousedev->handle);
885 if (error)
886 goto err_free_mousedev;
887 }
888
889 error = mousedev_install_chrdev(mousedev);
890 if (error)
891 goto err_unregister_handle;
735 892
736 error = device_add(&mousedev->dev); 893 error = device_add(&mousedev->dev);
737 if (error) 894 if (error)
738 goto err_free_mousedev; 895 goto err_cleanup_mousedev;
739 896
740 return mousedev; 897 return mousedev;
741 898
899 err_cleanup_mousedev:
900 mousedev_cleanup(mousedev);
901 err_unregister_handle:
902 if (minor != MOUSEDEV_MIX)
903 input_unregister_handle(&mousedev->handle);
742 err_free_mousedev: 904 err_free_mousedev:
743 put_device(&mousedev->dev); 905 put_device(&mousedev->dev);
744 err_out: 906 err_out:
@@ -747,29 +909,64 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
747 909
748static void mousedev_destroy(struct mousedev *mousedev) 910static void mousedev_destroy(struct mousedev *mousedev)
749{ 911{
750 struct mousedev_client *client;
751
752 device_del(&mousedev->dev); 912 device_del(&mousedev->dev);
753 mousedev->exist = 0; 913 mousedev_cleanup(mousedev);
914 if (mousedev->minor != MOUSEDEV_MIX)
915 input_unregister_handle(&mousedev->handle);
916 put_device(&mousedev->dev);
917}
754 918
755 if (mousedev->open) { 919static int mixdev_add_device(struct mousedev *mousedev)
756 input_close_device(&mousedev->handle); 920{
757 list_for_each_entry(client, &mousedev->client_list, node) 921 int retval;
758 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 922
759 wake_up_interruptible(&mousedev->wait); 923 retval = mutex_lock_interruptible(&mousedev_mix->mutex);
924 if (retval)
925 return retval;
926
927 if (mousedev_mix->open) {
928 retval = mousedev_open_device(mousedev);
929 if (retval)
930 goto out;
931
932 mousedev->mixdev_open = 1;
933 }
934
935 get_device(&mousedev->dev);
936 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
937
938 out:
939 mutex_unlock(&mousedev_mix->mutex);
940 return retval;
941}
942
943static void mixdev_remove_device(struct mousedev *mousedev)
944{
945 mutex_lock(&mousedev_mix->mutex);
946
947 if (mousedev->mixdev_open) {
948 mousedev->mixdev_open = 0;
949 mousedev_close_device(mousedev);
760 } 950 }
761 951
952 list_del_init(&mousedev->mixdev_node);
953 mutex_unlock(&mousedev_mix->mutex);
954
762 put_device(&mousedev->dev); 955 put_device(&mousedev->dev);
763} 956}
764 957
765static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, 958static int mousedev_connect(struct input_handler *handler,
959 struct input_dev *dev,
766 const struct input_device_id *id) 960 const struct input_device_id *id)
767{ 961{
768 struct mousedev *mousedev; 962 struct mousedev *mousedev;
769 int minor; 963 int minor;
770 int error; 964 int error;
771 965
772 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); 966 for (minor = 0; minor < MOUSEDEV_MINORS; minor++)
967 if (!mousedev_table[minor])
968 break;
969
773 if (minor == MOUSEDEV_MINORS) { 970 if (minor == MOUSEDEV_MINORS) {
774 printk(KERN_ERR "mousedev: no more free mousedev devices\n"); 971 printk(KERN_ERR "mousedev: no more free mousedev devices\n");
775 return -ENFILE; 972 return -ENFILE;
@@ -779,21 +976,13 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
779 if (IS_ERR(mousedev)) 976 if (IS_ERR(mousedev))
780 return PTR_ERR(mousedev); 977 return PTR_ERR(mousedev);
781 978
782 error = input_register_handle(&mousedev->handle);
783 if (error)
784 goto err_delete_mousedev;
785
786 error = mixdev_add_device(mousedev); 979 error = mixdev_add_device(mousedev);
787 if (error) 980 if (error) {
788 goto err_unregister_handle; 981 mousedev_destroy(mousedev);
982 return error;
983 }
789 984
790 return 0; 985 return 0;
791
792 err_unregister_handle:
793 input_unregister_handle(&mousedev->handle);
794 err_delete_mousedev:
795 device_unregister(&mousedev->dev);
796 return error;
797} 986}
798 987
799static void mousedev_disconnect(struct input_handle *handle) 988static void mousedev_disconnect(struct input_handle *handle)
@@ -801,33 +990,42 @@ static void mousedev_disconnect(struct input_handle *handle)
801 struct mousedev *mousedev = handle->private; 990 struct mousedev *mousedev = handle->private;
802 991
803 mixdev_remove_device(mousedev); 992 mixdev_remove_device(mousedev);
804 input_unregister_handle(handle);
805 mousedev_destroy(mousedev); 993 mousedev_destroy(mousedev);
806} 994}
807 995
808static const struct input_device_id mousedev_ids[] = { 996static const struct input_device_id mousedev_ids[] = {
809 { 997 {
810 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, 998 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
999 INPUT_DEVICE_ID_MATCH_KEYBIT |
1000 INPUT_DEVICE_ID_MATCH_RELBIT,
811 .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, 1001 .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
812 .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, 1002 .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
813 .relbit = { BIT(REL_X) | BIT(REL_Y) }, 1003 .relbit = { BIT(REL_X) | BIT(REL_Y) },
814 }, /* A mouse like device, at least one button, two relative axes */ 1004 }, /* A mouse like device, at least one button,
1005 two relative axes */
815 { 1006 {
816 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, 1007 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1008 INPUT_DEVICE_ID_MATCH_RELBIT,
817 .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, 1009 .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
818 .relbit = { BIT(REL_WHEEL) }, 1010 .relbit = { BIT(REL_WHEEL) },
819 }, /* A separate scrollwheel */ 1011 }, /* A separate scrollwheel */
820 { 1012 {
821 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 1013 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1014 INPUT_DEVICE_ID_MATCH_KEYBIT |
1015 INPUT_DEVICE_ID_MATCH_ABSBIT,
822 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, 1016 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
823 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, 1017 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
824 .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, 1018 .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
825 }, /* A tablet like device, at least touch detection, two absolute axes */ 1019 }, /* A tablet like device, at least touch detection,
1020 two absolute axes */
826 { 1021 {
827 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, 1022 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1023 INPUT_DEVICE_ID_MATCH_KEYBIT |
1024 INPUT_DEVICE_ID_MATCH_ABSBIT,
828 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, 1025 .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
829 .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) }, 1026 .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
830 .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, 1027 .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
1028 BIT(ABS_TOOL_WIDTH) },
831 }, /* A touchpad */ 1029 }, /* A touchpad */
832 1030
833 { }, /* Terminating entry */ 1031 { }, /* Terminating entry */