Lines Matching +full:abs +full:- +full:range
1 // SPDX-License-Identifier: GPL-2.0-or-later
11 * - add UI_GET_SYSNAME ioctl
13 * - updated ff support for the changes in kernel interface
14 * - added MODULE_VERSION
16 * - added force feedback support
17 * - added UI_SET_PHYS
19 * - first public version
33 #include "../input-compat.h"
81 lockdep_assert_held(&dev->event_lock); in uinput_dev_event()
85 udev->buff[udev->head] = (struct input_event) { in uinput_dev_event()
93 udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; in uinput_dev_event()
95 wake_up_interruptible(&udev->waitq); in uinput_dev_event()
107 spin_lock(&udev->requests_lock); in uinput_request_alloc_id()
110 if (!udev->requests[id]) { in uinput_request_alloc_id()
111 request->id = id; in uinput_request_alloc_id()
112 udev->requests[id] = request; in uinput_request_alloc_id()
118 spin_unlock(&udev->requests_lock); in uinput_request_alloc_id()
129 return udev->requests[id]; in uinput_request_find()
136 return wait_event_interruptible(udev->requests_waitq, in uinput_request_reserve_slot()
144 spin_lock(&udev->requests_lock); in uinput_request_release_slot()
145 udev->requests[id] = NULL; in uinput_request_release_slot()
146 spin_unlock(&udev->requests_lock); in uinput_request_release_slot()
148 wake_up(&udev->requests_waitq); in uinput_request_release_slot()
157 spin_lock(&udev->state_lock); in uinput_request_send()
159 if (udev->state != UIST_CREATED) { in uinput_request_send()
160 retval = -ENODEV; in uinput_request_send()
168 spin_lock_irqsave(&udev->dev->event_lock, flags); in uinput_request_send()
169 uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); in uinput_request_send()
170 spin_unlock_irqrestore(&udev->dev->event_lock, flags); in uinput_request_send()
173 spin_unlock(&udev->state_lock); in uinput_request_send()
187 init_completion(&request->done); in uinput_request_submit()
197 if (!wait_for_completion_timeout(&request->done, 30 * HZ)) { in uinput_request_submit()
198 retval = -ETIMEDOUT; in uinput_request_submit()
202 retval = request->retval; in uinput_request_submit()
205 uinput_request_release_slot(udev, request->id); in uinput_request_submit()
218 spin_lock(&udev->requests_lock); in uinput_flush_requests()
221 request = udev->requests[i]; in uinput_flush_requests()
223 request->retval = -ENODEV; in uinput_flush_requests()
224 complete(&request->done); in uinput_flush_requests()
228 spin_unlock(&udev->requests_lock); in uinput_flush_requests()
260 if (effect->type == FF_PERIODIC && in uinput_dev_upload_effect()
261 effect->u.periodic.waveform == FF_CUSTOM) in uinput_dev_upload_effect()
262 return -EINVAL; in uinput_dev_upload_effect()
276 if (!test_bit(EV_FF, dev->evbit)) in uinput_dev_erase_effect()
277 return -ENOSYS; in uinput_dev_erase_effect()
291 * the udev->mutex), or the file descriptor is closed and there is in uinput_dev_flush()
300 struct input_dev *dev = udev->dev; in uinput_destroy_device()
301 enum uinput_state old_state = udev->state; in uinput_destroy_device()
308 spin_lock(&udev->state_lock); in uinput_destroy_device()
309 udev->state = UIST_NEW_DEVICE; in uinput_destroy_device()
310 spin_unlock(&udev->state_lock); in uinput_destroy_device()
313 name = dev->name; in uinput_destroy_device()
314 phys = dev->phys; in uinput_destroy_device()
323 udev->dev = NULL; in uinput_destroy_device()
329 struct input_dev *dev = udev->dev; in uinput_create_device()
332 if (udev->state != UIST_SETUP_COMPLETE) { in uinput_create_device()
334 return -EINVAL; in uinput_create_device()
337 if (test_bit(EV_ABS, dev->evbit)) { in uinput_create_device()
339 if (!dev->absinfo) { in uinput_create_device()
340 error = -EINVAL; in uinput_create_device()
344 if (test_bit(ABS_MT_SLOT, dev->absbit)) { in uinput_create_device()
349 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { in uinput_create_device()
354 if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) { in uinput_create_device()
355 printk(KERN_DEBUG "%s: ff_effects_max should be non-zero when FF_BIT is set\n", in uinput_create_device()
357 error = -EINVAL; in uinput_create_device()
361 if (udev->ff_effects_max) { in uinput_create_device()
362 error = input_ff_create(dev, udev->ff_effects_max); in uinput_create_device()
366 dev->ff->upload = uinput_dev_upload_effect; in uinput_create_device()
367 dev->ff->erase = uinput_dev_erase_effect; in uinput_create_device()
368 dev->ff->playback = uinput_dev_playback; in uinput_create_device()
369 dev->ff->set_gain = uinput_dev_set_gain; in uinput_create_device()
370 dev->ff->set_autocenter = uinput_dev_set_autocenter; in uinput_create_device()
376 dev->flush = uinput_dev_flush; in uinput_create_device()
379 dev->event = uinput_dev_event; in uinput_create_device()
381 input_set_drvdata(udev->dev, udev); in uinput_create_device()
383 error = input_register_device(udev->dev); in uinput_create_device()
387 spin_lock(&udev->state_lock); in uinput_create_device()
388 udev->state = UIST_CREATED; in uinput_create_device()
389 spin_unlock(&udev->state_lock); in uinput_create_device()
404 return -ENOMEM; in uinput_open()
406 mutex_init(&newdev->mutex); in uinput_open()
407 spin_lock_init(&newdev->state_lock); in uinput_open()
408 spin_lock_init(&newdev->requests_lock); in uinput_open()
409 init_waitqueue_head(&newdev->requests_waitq); in uinput_open()
410 init_waitqueue_head(&newdev->waitq); in uinput_open()
411 newdev->state = UIST_NEW_DEVICE; in uinput_open()
413 file->private_data = newdev; in uinput_open()
420 const struct input_absinfo *abs) in uinput_validate_absinfo() argument
422 int min, max, range; in uinput_validate_absinfo() local
424 min = abs->minimum; in uinput_validate_absinfo()
425 max = abs->maximum; in uinput_validate_absinfo()
429 "%s: invalid abs[%02x] min:%d max:%d\n", in uinput_validate_absinfo()
431 return -EINVAL; in uinput_validate_absinfo()
434 if (!check_sub_overflow(max, min, &range) && abs->flat > range) { in uinput_validate_absinfo()
436 "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n", in uinput_validate_absinfo()
437 UINPUT_NAME, code, abs->flat, min, max); in uinput_validate_absinfo()
438 return -EINVAL; in uinput_validate_absinfo()
444 * (we are not using in-kernel slot assignment so not going to in uinput_validate_absinfo()
452 return -EINVAL; in uinput_validate_absinfo()
463 if (!test_bit(EV_ABS, dev->evbit)) in uinput_validate_absbits()
470 for_each_set_bit(cnt, dev->absbit, ABS_CNT) { in uinput_validate_absbits()
471 if (!dev->absinfo) in uinput_validate_absbits()
472 return -EINVAL; in uinput_validate_absbits()
474 error = uinput_validate_absinfo(dev, cnt, &dev->absinfo[cnt]); in uinput_validate_absbits()
488 if (udev->state == UIST_CREATED) in uinput_dev_setup()
489 return -EINVAL; in uinput_dev_setup()
492 return -EFAULT; in uinput_dev_setup()
495 return -EINVAL; in uinput_dev_setup()
497 dev = udev->dev; in uinput_dev_setup()
498 dev->id = setup.id; in uinput_dev_setup()
499 udev->ff_effects_max = setup.ff_effects_max; in uinput_dev_setup()
501 kfree(dev->name); in uinput_dev_setup()
502 dev->name = kstrndup(setup.name, UINPUT_MAX_NAME_SIZE, GFP_KERNEL); in uinput_dev_setup()
503 if (!dev->name) in uinput_dev_setup()
504 return -ENOMEM; in uinput_dev_setup()
506 udev->state = UIST_SETUP_COMPLETE; in uinput_dev_setup()
518 return -E2BIG; in uinput_abs_setup()
520 if (udev->state == UIST_CREATED) in uinput_abs_setup()
521 return -EINVAL; in uinput_abs_setup()
524 return -EFAULT; in uinput_abs_setup()
527 return -ERANGE; in uinput_abs_setup()
529 dev = udev->dev; in uinput_abs_setup()
536 if (!dev->absinfo) in uinput_abs_setup()
537 return -ENOMEM; in uinput_abs_setup()
539 set_bit(setup.code, dev->absbit); in uinput_abs_setup()
540 dev->absinfo[setup.code] = setup.absinfo; in uinput_abs_setup()
554 return -EINVAL; in uinput_setup_device_legacy()
556 if (!udev->dev) { in uinput_setup_device_legacy()
557 udev->dev = input_allocate_device(); in uinput_setup_device_legacy()
558 if (!udev->dev) in uinput_setup_device_legacy()
559 return -ENOMEM; in uinput_setup_device_legacy()
562 dev = udev->dev; in uinput_setup_device_legacy()
568 udev->ff_effects_max = user_dev->ff_effects_max; in uinput_setup_device_legacy()
571 if (!user_dev->name[0]) { in uinput_setup_device_legacy()
572 retval = -EINVAL; in uinput_setup_device_legacy()
576 kfree(dev->name); in uinput_setup_device_legacy()
577 dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE, in uinput_setup_device_legacy()
579 if (!dev->name) { in uinput_setup_device_legacy()
580 retval = -ENOMEM; in uinput_setup_device_legacy()
584 dev->id.bustype = user_dev->id.bustype; in uinput_setup_device_legacy()
585 dev->id.vendor = user_dev->id.vendor; in uinput_setup_device_legacy()
586 dev->id.product = user_dev->id.product; in uinput_setup_device_legacy()
587 dev->id.version = user_dev->id.version; in uinput_setup_device_legacy()
590 input_abs_set_max(dev, i, user_dev->absmax[i]); in uinput_setup_device_legacy()
591 input_abs_set_min(dev, i, user_dev->absmin[i]); in uinput_setup_device_legacy()
592 input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]); in uinput_setup_device_legacy()
593 input_abs_set_flat(dev, i, user_dev->absflat[i]); in uinput_setup_device_legacy()
600 udev->state = UIST_SETUP_COMPLETE; in uinput_setup_device_legacy()
644 return -EINVAL; in uinput_inject_events()
654 return -EFAULT; in uinput_inject_events()
658 input_set_timestamp(udev->dev, timestamp); in uinput_inject_events()
660 input_event(udev->dev, ev.type, ev.code, ev.value); in uinput_inject_events()
671 struct uinput_device *udev = file->private_data; in uinput_write()
677 retval = mutex_lock_interruptible(&udev->mutex); in uinput_write()
681 retval = udev->state == UIST_CREATED ? in uinput_write()
685 mutex_unlock(&udev->mutex); in uinput_write()
695 spin_lock_irq(&udev->dev->event_lock); in uinput_fetch_next_event()
697 have_event = udev->head != udev->tail; in uinput_fetch_next_event()
699 *event = udev->buff[udev->tail]; in uinput_fetch_next_event()
700 udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; in uinput_fetch_next_event()
703 spin_unlock_irq(&udev->dev->event_lock); in uinput_fetch_next_event()
718 return -EFAULT; in uinput_events_to_user()
729 struct uinput_device *udev = file->private_data; in uinput_read()
733 return -EINVAL; in uinput_read()
736 retval = mutex_lock_interruptible(&udev->mutex); in uinput_read()
740 if (udev->state != UIST_CREATED) in uinput_read()
741 retval = -ENODEV; in uinput_read()
742 else if (udev->head == udev->tail && in uinput_read()
743 (file->f_flags & O_NONBLOCK)) in uinput_read()
744 retval = -EAGAIN; in uinput_read()
748 mutex_unlock(&udev->mutex); in uinput_read()
753 if (!(file->f_flags & O_NONBLOCK)) in uinput_read()
754 retval = wait_event_interruptible(udev->waitq, in uinput_read()
755 udev->head != udev->tail || in uinput_read()
756 udev->state != UIST_CREATED); in uinput_read()
764 struct uinput_device *udev = file->private_data; in uinput_poll()
767 poll_wait(file, &udev->waitq, wait); in uinput_poll()
769 if (udev->head != udev->tail) in uinput_poll()
777 struct uinput_device *udev = file->private_data; in uinput_release()
800 ff_up_compat.request_id = ff_up->request_id; in uinput_ff_upload_to_user()
801 ff_up_compat.retval = ff_up->retval; in uinput_ff_upload_to_user()
808 memcpy(&ff_up_compat.effect, &ff_up->effect, in uinput_ff_upload_to_user()
810 memcpy(&ff_up_compat.old, &ff_up->old, in uinput_ff_upload_to_user()
815 return -EFAULT; in uinput_ff_upload_to_user()
819 return -EFAULT; in uinput_ff_upload_to_user()
833 return -EFAULT; in uinput_ff_upload_from_user()
835 ff_up->request_id = ff_up_compat.request_id; in uinput_ff_upload_from_user()
836 ff_up->retval = ff_up_compat.retval; in uinput_ff_upload_from_user()
837 memcpy(&ff_up->effect, &ff_up_compat.effect, in uinput_ff_upload_from_user()
839 memcpy(&ff_up->old, &ff_up_compat.old, in uinput_ff_upload_from_user()
845 return -EFAULT; in uinput_ff_upload_from_user()
857 return -EFAULT; in uinput_ff_upload_to_user()
866 return -EFAULT; in uinput_ff_upload_from_user()
876 if (udev->state == UIST_CREATED) \
877 __ret = -EINVAL; \
879 __ret = -EINVAL; \
880 else set_bit((_arg), udev->dev->_bit); \
891 return -ENOENT; in uinput_str_to_user()
894 return -EINVAL; in uinput_str_to_user()
902 return -EFAULT; in uinput_str_to_user()
905 ret = put_user(0, p + len - 1); in uinput_str_to_user()
906 return ret ? -EFAULT : len; in uinput_str_to_user()
913 struct uinput_device *udev = file->private_data; in uinput_ioctl_handler()
921 retval = mutex_lock_interruptible(&udev->mutex); in uinput_ioctl_handler()
925 if (!udev->dev) { in uinput_ioctl_handler()
926 udev->dev = input_allocate_device(); in uinput_ioctl_handler()
927 if (!udev->dev) { in uinput_ioctl_handler()
928 retval = -ENOMEM; in uinput_ioctl_handler()
936 retval = -EFAULT; in uinput_ioctl_handler()
994 if (udev->state == UIST_CREATED) { in uinput_ioctl_handler()
995 retval = -EINVAL; in uinput_ioctl_handler()
1005 kfree(udev->dev->phys); in uinput_ioctl_handler()
1006 udev->dev->phys = phys; in uinput_ioctl_handler()
1015 if (!req || req->code != UI_FF_UPLOAD || in uinput_ioctl_handler()
1016 !req->u.upload.effect) { in uinput_ioctl_handler()
1017 retval = -EINVAL; in uinput_ioctl_handler()
1022 ff_up.effect = *req->u.upload.effect; in uinput_ioctl_handler()
1023 if (req->u.upload.old) in uinput_ioctl_handler()
1024 ff_up.old = *req->u.upload.old; in uinput_ioctl_handler()
1033 retval = -EFAULT; in uinput_ioctl_handler()
1038 if (!req || req->code != UI_FF_ERASE) { in uinput_ioctl_handler()
1039 retval = -EINVAL; in uinput_ioctl_handler()
1044 ff_erase.effect_id = req->u.effect_id; in uinput_ioctl_handler()
1046 retval = -EFAULT; in uinput_ioctl_handler()
1058 if (!req || req->code != UI_FF_UPLOAD || in uinput_ioctl_handler()
1059 !req->u.upload.effect) { in uinput_ioctl_handler()
1060 retval = -EINVAL; in uinput_ioctl_handler()
1064 req->retval = ff_up.retval; in uinput_ioctl_handler()
1065 complete(&req->done); in uinput_ioctl_handler()
1070 retval = -EFAULT; in uinput_ioctl_handler()
1075 if (!req || req->code != UI_FF_ERASE) { in uinput_ioctl_handler()
1076 retval = -EINVAL; in uinput_ioctl_handler()
1080 req->retval = ff_erase.retval; in uinput_ioctl_handler()
1081 complete(&req->done); in uinput_ioctl_handler()
1087 /* Now check variable-length commands */ in uinput_ioctl_handler()
1090 if (udev->state != UIST_CREATED) { in uinput_ioctl_handler()
1091 retval = -ENOENT; in uinput_ioctl_handler()
1094 name = dev_name(&udev->dev->dev); in uinput_ioctl_handler()
1103 retval = -EINVAL; in uinput_ioctl_handler()
1105 mutex_unlock(&udev->mutex); in uinput_ioctl_handler()