aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joydev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joydev.c')
-rw-r--r--drivers/input/joydev.c69
1 files changed, 45 insertions, 24 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 949bdcef8c2b..d67157513bf7 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -81,10 +81,7 @@ static int joydev_correct(int value, struct js_corr *corr)
81 return 0; 81 return 0;
82 } 82 }
83 83
84 if (value < -32767) return -32767; 84 return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
85 if (value > 32767) return 32767;
86
87 return value;
88} 85}
89 86
90static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 87static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
@@ -96,7 +93,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
96 switch (type) { 93 switch (type) {
97 94
98 case EV_KEY: 95 case EV_KEY:
99 if (code < BTN_MISC || value == 2) return; 96 if (code < BTN_MISC || value == 2)
97 return;
100 event.type = JS_EVENT_BUTTON; 98 event.type = JS_EVENT_BUTTON;
101 event.number = joydev->keymap[code - BTN_MISC]; 99 event.number = joydev->keymap[code - BTN_MISC];
102 event.value = value; 100 event.value = value;
@@ -106,7 +104,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
106 event.type = JS_EVENT_AXIS; 104 event.type = JS_EVENT_AXIS;
107 event.number = joydev->absmap[code]; 105 event.number = joydev->absmap[code];
108 event.value = joydev_correct(value, joydev->corr + event.number); 106 event.value = joydev_correct(value, joydev->corr + event.number);
109 if (event.value == joydev->abs[event.number]) return; 107 if (event.value == joydev->abs[event.number])
108 return;
110 joydev->abs[event.number] = event.value; 109 joydev->abs[event.number] = event.value;
111 break; 110 break;
112 111
@@ -134,7 +133,9 @@ static int joydev_fasync(int fd, struct file *file, int on)
134{ 133{
135 int retval; 134 int retval;
136 struct joydev_list *list = file->private_data; 135 struct joydev_list *list = file->private_data;
136
137 retval = fasync_helper(fd, file, on, &list->fasync); 137 retval = fasync_helper(fd, file, on, &list->fasync);
138
138 return retval < 0 ? retval : 0; 139 return retval < 0 ? retval : 0;
139} 140}
140 141
@@ -222,12 +223,12 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo
222 return sizeof(struct JS_DATA_TYPE); 223 return sizeof(struct JS_DATA_TYPE);
223 } 224 }
224 225
225 if (list->startup == joydev->nabs + joydev->nkey 226 if (list->startup == joydev->nabs + joydev->nkey &&
226 && list->head == list->tail && (file->f_flags & O_NONBLOCK)) 227 list->head == list->tail && (file->f_flags & O_NONBLOCK))
227 return -EAGAIN; 228 return -EAGAIN;
228 229
229 retval = wait_event_interruptible(list->joydev->wait, 230 retval = wait_event_interruptible(list->joydev->wait,
230 !list->joydev->exist || 231 !list->joydev->exist ||
231 list->startup < joydev->nabs + joydev->nkey || 232 list->startup < joydev->nabs + joydev->nkey ||
232 list->head != list->tail); 233 list->head != list->tail);
233 234
@@ -276,8 +277,9 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo
276static unsigned int joydev_poll(struct file *file, poll_table *wait) 277static unsigned int joydev_poll(struct file *file, poll_table *wait)
277{ 278{
278 struct joydev_list *list = file->private_data; 279 struct joydev_list *list = file->private_data;
280
279 poll_wait(file, &list->joydev->wait, wait); 281 poll_wait(file, &list->joydev->wait, wait);
280 return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? 282 return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ?
281 (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); 283 (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR));
282} 284}
283 285
@@ -291,20 +293,26 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u
291 case JS_SET_CAL: 293 case JS_SET_CAL:
292 return copy_from_user(&joydev->glue.JS_CORR, argp, 294 return copy_from_user(&joydev->glue.JS_CORR, argp,
293 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; 295 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
296
294 case JS_GET_CAL: 297 case JS_GET_CAL:
295 return copy_to_user(argp, &joydev->glue.JS_CORR, 298 return copy_to_user(argp, &joydev->glue.JS_CORR,
296 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; 299 sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
300
297 case JS_SET_TIMEOUT: 301 case JS_SET_TIMEOUT:
298 return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); 302 return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
303
299 case JS_GET_TIMEOUT: 304 case JS_GET_TIMEOUT:
300 return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); 305 return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
301 306
302 case JSIOCGVERSION: 307 case JSIOCGVERSION:
303 return put_user(JS_VERSION, (__u32 __user *) argp); 308 return put_user(JS_VERSION, (__u32 __user *) argp);
309
304 case JSIOCGAXES: 310 case JSIOCGAXES:
305 return put_user(joydev->nabs, (__u8 __user *) argp); 311 return put_user(joydev->nabs, (__u8 __user *) argp);
312
306 case JSIOCGBUTTONS: 313 case JSIOCGBUTTONS:
307 return put_user(joydev->nkey, (__u8 __user *) argp); 314 return put_user(joydev->nkey, (__u8 __user *) argp);
315
308 case JSIOCSCORR: 316 case JSIOCSCORR:
309 if (copy_from_user(joydev->corr, argp, 317 if (copy_from_user(joydev->corr, argp,
310 sizeof(joydev->corr[0]) * joydev->nabs)) 318 sizeof(joydev->corr[0]) * joydev->nabs))
@@ -314,38 +322,49 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u
314 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); 322 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
315 } 323 }
316 return 0; 324 return 0;
325
317 case JSIOCGCORR: 326 case JSIOCGCORR:
318 return copy_to_user(argp, joydev->corr, 327 return copy_to_user(argp, joydev->corr,
319 sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; 328 sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
329
320 case JSIOCSAXMAP: 330 case JSIOCSAXMAP:
321 if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) 331 if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
322 return -EFAULT; 332 return -EFAULT;
323 for (i = 0; i < joydev->nabs; i++) { 333 for (i = 0; i < joydev->nabs; i++) {
324 if (joydev->abspam[i] > ABS_MAX) return -EINVAL; 334 if (joydev->abspam[i] > ABS_MAX)
335 return -EINVAL;
325 joydev->absmap[joydev->abspam[i]] = i; 336 joydev->absmap[joydev->abspam[i]] = i;
326 } 337 }
327 return 0; 338 return 0;
339
328 case JSIOCGAXMAP: 340 case JSIOCGAXMAP:
329 return copy_to_user(argp, joydev->abspam, 341 return copy_to_user(argp, joydev->abspam,
330 sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; 342 sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
343
331 case JSIOCSBTNMAP: 344 case JSIOCSBTNMAP:
332 if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) 345 if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
333 return -EFAULT; 346 return -EFAULT;
334 for (i = 0; i < joydev->nkey; i++) { 347 for (i = 0; i < joydev->nkey; i++) {
335 if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; 348 if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC)
349 return -EINVAL;
336 joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; 350 joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
337 } 351 }
338 return 0; 352 return 0;
353
339 case JSIOCGBTNMAP: 354 case JSIOCGBTNMAP:
340 return copy_to_user(argp, joydev->keypam, 355 return copy_to_user(argp, joydev->keypam,
341 sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; 356 sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
357
342 default: 358 default:
343 if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { 359 if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
344 int len; 360 int len;
345 if (!dev->name) return 0; 361 if (!dev->name)
362 return 0;
346 len = strlen(dev->name) + 1; 363 len = strlen(dev->name) + 1;
347 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); 364 if (len > _IOC_SIZE(cmd))
348 if (copy_to_user(argp, dev->name, len)) return -EFAULT; 365 len = _IOC_SIZE(cmd);
366 if (copy_to_user(argp, dev->name, len))
367 return -EFAULT;
349 return len; 368 return len;
350 } 369 }
351 } 370 }
@@ -362,7 +381,9 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
362 struct JS_DATA_SAVE_TYPE_32 ds32; 381 struct JS_DATA_SAVE_TYPE_32 ds32;
363 int err; 382 int err;
364 383
365 if (!joydev->exist) return -ENODEV; 384 if (!joydev->exist)
385 return -ENODEV;
386
366 switch(cmd) { 387 switch(cmd) {
367 case JS_SET_TIMELIMIT: 388 case JS_SET_TIMELIMIT:
368 err = get_user(tmp32, (s32 __user *) arg); 389 err = get_user(tmp32, (s32 __user *) arg);
@@ -395,8 +416,7 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
395 ds32.JS_SAVE = joydev->glue.JS_SAVE; 416 ds32.JS_SAVE = joydev->glue.JS_SAVE;
396 ds32.JS_CORR = joydev->glue.JS_CORR; 417 ds32.JS_CORR = joydev->glue.JS_CORR;
397 418
398 err = copy_to_user(argp, &ds32, 419 err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
399 sizeof(ds32)) ? -EFAULT : 0;
400 break; 420 break;
401 421
402 default: 422 default:
@@ -412,7 +432,8 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
412 struct joydev *joydev = list->joydev; 432 struct joydev *joydev = list->joydev;
413 void __user *argp = (void __user *)arg; 433 void __user *argp = (void __user *)arg;
414 434
415 if (!joydev->exist) return -ENODEV; 435 if (!joydev->exist)
436 return -ENODEV;
416 437
417 switch(cmd) { 438 switch(cmd) {
418 case JS_SET_TIMELIMIT: 439 case JS_SET_TIMELIMIT:
@@ -546,8 +567,8 @@ static struct input_device_id joydev_blacklist[] = {
546 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, 567 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
547 .evbit = { BIT(EV_KEY) }, 568 .evbit = { BIT(EV_KEY) },
548 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, 569 .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
549 }, /* Avoid itouchpads, touchscreens and tablets */ 570 }, /* Avoid itouchpads, touchscreens and tablets */
550 { }, /* Terminating entry */ 571 { } /* Terminating entry */
551}; 572};
552 573
553static struct input_device_id joydev_ids[] = { 574static struct input_device_id joydev_ids[] = {
@@ -566,7 +587,7 @@ static struct input_device_id joydev_ids[] = {
566 .evbit = { BIT(EV_ABS) }, 587 .evbit = { BIT(EV_ABS) },
567 .absbit = { BIT(ABS_THROTTLE) }, 588 .absbit = { BIT(ABS_THROTTLE) },
568 }, 589 },
569 { }, /* Terminating entry */ 590 { } /* Terminating entry */
570}; 591};
571 592
572MODULE_DEVICE_TABLE(input, joydev_ids); 593MODULE_DEVICE_TABLE(input, joydev_ids);
@@ -579,7 +600,7 @@ static struct input_handler joydev_handler = {
579 .minor = JOYDEV_MINOR_BASE, 600 .minor = JOYDEV_MINOR_BASE,
580 .name = "joydev", 601 .name = "joydev",
581 .id_table = joydev_ids, 602 .id_table = joydev_ids,
582 .blacklist = joydev_blacklist, 603 .blacklist = joydev_blacklist,
583}; 604};
584 605
585static int __init joydev_init(void) 606static int __init joydev_init(void)