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
31 #include "../input-compat.h"
79 udev->buff[udev->head] = (struct input_event) { in uinput_dev_event()
87 udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; in uinput_dev_event()
89 wake_up_interruptible(&udev->waitq); in uinput_dev_event()
101 spin_lock(&udev->requests_lock); in uinput_request_alloc_id()
104 if (!udev->requests[id]) { in uinput_request_alloc_id()
105 request->id = id; in uinput_request_alloc_id()
106 udev->requests[id] = request; in uinput_request_alloc_id()
112 spin_unlock(&udev->requests_lock); in uinput_request_alloc_id()
123 return udev->requests[id]; in uinput_request_find()
130 return wait_event_interruptible(udev->requests_waitq, in uinput_request_reserve_slot()
138 spin_lock(&udev->requests_lock); in uinput_request_release_slot()
139 udev->requests[id] = NULL; in uinput_request_release_slot()
140 spin_unlock(&udev->requests_lock); in uinput_request_release_slot()
142 wake_up(&udev->requests_waitq); in uinput_request_release_slot()
150 retval = mutex_lock_interruptible(&udev->mutex); in uinput_request_send()
154 if (udev->state != UIST_CREATED) { in uinput_request_send()
155 retval = -ENODEV; in uinput_request_send()
159 init_completion(&request->done); in uinput_request_send()
165 uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); in uinput_request_send()
168 mutex_unlock(&udev->mutex); in uinput_request_send()
185 if (!wait_for_completion_timeout(&request->done, 30 * HZ)) { in uinput_request_submit()
186 retval = -ETIMEDOUT; in uinput_request_submit()
190 retval = request->retval; in uinput_request_submit()
193 uinput_request_release_slot(udev, request->id); in uinput_request_submit()
206 spin_lock(&udev->requests_lock); in uinput_flush_requests()
209 request = udev->requests[i]; in uinput_flush_requests()
211 request->retval = -ENODEV; in uinput_flush_requests()
212 complete(&request->done); in uinput_flush_requests()
216 spin_unlock(&udev->requests_lock); in uinput_flush_requests()
248 if (effect->type == FF_PERIODIC && in uinput_dev_upload_effect()
249 effect->u.periodic.waveform == FF_CUSTOM) in uinput_dev_upload_effect()
250 return -EINVAL; in uinput_dev_upload_effect()
264 if (!test_bit(EV_FF, dev->evbit)) in uinput_dev_erase_effect()
265 return -ENOSYS; in uinput_dev_erase_effect()
279 * the udev->mutex), or the file descriptor is closed and there is in uinput_dev_flush()
288 struct input_dev *dev = udev->dev; in uinput_destroy_device()
289 enum uinput_state old_state = udev->state; in uinput_destroy_device()
291 udev->state = UIST_NEW_DEVICE; in uinput_destroy_device()
294 name = dev->name; in uinput_destroy_device()
295 phys = dev->phys; in uinput_destroy_device()
304 udev->dev = NULL; in uinput_destroy_device()
310 struct input_dev *dev = udev->dev; in uinput_create_device()
313 if (udev->state != UIST_SETUP_COMPLETE) { in uinput_create_device()
315 return -EINVAL; in uinput_create_device()
318 if (test_bit(EV_ABS, dev->evbit)) { in uinput_create_device()
320 if (!dev->absinfo) { in uinput_create_device()
321 error = -EINVAL; in uinput_create_device()
325 if (test_bit(ABS_MT_SLOT, dev->absbit)) { in uinput_create_device()
330 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { in uinput_create_device()
335 if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) { in uinput_create_device()
336 printk(KERN_DEBUG "%s: ff_effects_max should be non-zero when FF_BIT is set\n", in uinput_create_device()
338 error = -EINVAL; in uinput_create_device()
342 if (udev->ff_effects_max) { in uinput_create_device()
343 error = input_ff_create(dev, udev->ff_effects_max); in uinput_create_device()
347 dev->ff->upload = uinput_dev_upload_effect; in uinput_create_device()
348 dev->ff->erase = uinput_dev_erase_effect; in uinput_create_device()
349 dev->ff->playback = uinput_dev_playback; in uinput_create_device()
350 dev->ff->set_gain = uinput_dev_set_gain; in uinput_create_device()
351 dev->ff->set_autocenter = uinput_dev_set_autocenter; in uinput_create_device()
357 dev->flush = uinput_dev_flush; in uinput_create_device()
360 dev->event = uinput_dev_event; in uinput_create_device()
362 input_set_drvdata(udev->dev, udev); in uinput_create_device()
364 error = input_register_device(udev->dev); in uinput_create_device()
368 udev->state = UIST_CREATED; in uinput_create_device()
383 return -ENOMEM; in uinput_open()
385 mutex_init(&newdev->mutex); in uinput_open()
386 spin_lock_init(&newdev->requests_lock); in uinput_open()
387 init_waitqueue_head(&newdev->requests_waitq); in uinput_open()
388 init_waitqueue_head(&newdev->waitq); in uinput_open()
389 newdev->state = UIST_NEW_DEVICE; in uinput_open()
391 file->private_data = newdev; in uinput_open()
398 const struct input_absinfo *abs) in uinput_validate_absinfo() argument
400 int min, max, range; in uinput_validate_absinfo() local
402 min = abs->minimum; in uinput_validate_absinfo()
403 max = abs->maximum; in uinput_validate_absinfo()
407 "%s: invalid abs[%02x] min:%d max:%d\n", in uinput_validate_absinfo()
409 return -EINVAL; in uinput_validate_absinfo()
412 if (!check_sub_overflow(max, min, &range) && abs->flat > range) { in uinput_validate_absinfo()
414 "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n", in uinput_validate_absinfo()
415 UINPUT_NAME, code, abs->flat, min, max); in uinput_validate_absinfo()
416 return -EINVAL; in uinput_validate_absinfo()
427 if (!test_bit(EV_ABS, dev->evbit)) in uinput_validate_absbits()
434 for_each_set_bit(cnt, dev->absbit, ABS_CNT) { in uinput_validate_absbits()
435 if (!dev->absinfo) in uinput_validate_absbits()
436 return -EINVAL; in uinput_validate_absbits()
438 error = uinput_validate_absinfo(dev, cnt, &dev->absinfo[cnt]); in uinput_validate_absbits()
452 if (udev->state == UIST_CREATED) in uinput_dev_setup()
453 return -EINVAL; in uinput_dev_setup()
456 return -EFAULT; in uinput_dev_setup()
459 return -EINVAL; in uinput_dev_setup()
461 dev = udev->dev; in uinput_dev_setup()
462 dev->id = setup.id; in uinput_dev_setup()
463 udev->ff_effects_max = setup.ff_effects_max; in uinput_dev_setup()
465 kfree(dev->name); in uinput_dev_setup()
466 dev->name = kstrndup(setup.name, UINPUT_MAX_NAME_SIZE, GFP_KERNEL); in uinput_dev_setup()
467 if (!dev->name) in uinput_dev_setup()
468 return -ENOMEM; in uinput_dev_setup()
470 udev->state = UIST_SETUP_COMPLETE; in uinput_dev_setup()
482 return -E2BIG; in uinput_abs_setup()
484 if (udev->state == UIST_CREATED) in uinput_abs_setup()
485 return -EINVAL; in uinput_abs_setup()
488 return -EFAULT; in uinput_abs_setup()
491 return -ERANGE; in uinput_abs_setup()
493 dev = udev->dev; in uinput_abs_setup()
500 if (!dev->absinfo) in uinput_abs_setup()
501 return -ENOMEM; in uinput_abs_setup()
503 set_bit(setup.code, dev->absbit); in uinput_abs_setup()
504 dev->absinfo[setup.code] = setup.absinfo; in uinput_abs_setup()
518 return -EINVAL; in uinput_setup_device_legacy()
520 if (!udev->dev) { in uinput_setup_device_legacy()
521 udev->dev = input_allocate_device(); in uinput_setup_device_legacy()
522 if (!udev->dev) in uinput_setup_device_legacy()
523 return -ENOMEM; in uinput_setup_device_legacy()
526 dev = udev->dev; in uinput_setup_device_legacy()
532 udev->ff_effects_max = user_dev->ff_effects_max; in uinput_setup_device_legacy()
535 if (!user_dev->name[0]) { in uinput_setup_device_legacy()
536 retval = -EINVAL; in uinput_setup_device_legacy()
540 kfree(dev->name); in uinput_setup_device_legacy()
541 dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE, in uinput_setup_device_legacy()
543 if (!dev->name) { in uinput_setup_device_legacy()
544 retval = -ENOMEM; in uinput_setup_device_legacy()
548 dev->id.bustype = user_dev->id.bustype; in uinput_setup_device_legacy()
549 dev->id.vendor = user_dev->id.vendor; in uinput_setup_device_legacy()
550 dev->id.product = user_dev->id.product; in uinput_setup_device_legacy()
551 dev->id.version = user_dev->id.version; in uinput_setup_device_legacy()
554 input_abs_set_max(dev, i, user_dev->absmax[i]); in uinput_setup_device_legacy()
555 input_abs_set_min(dev, i, user_dev->absmin[i]); in uinput_setup_device_legacy()
556 input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]); in uinput_setup_device_legacy()
557 input_abs_set_flat(dev, i, user_dev->absflat[i]); in uinput_setup_device_legacy()
564 udev->state = UIST_SETUP_COMPLETE; in uinput_setup_device_legacy()
579 return -EINVAL; in uinput_inject_events()
589 return -EFAULT; in uinput_inject_events()
591 input_event(udev->dev, ev.type, ev.code, ev.value); in uinput_inject_events()
602 struct uinput_device *udev = file->private_data; in uinput_write()
608 retval = mutex_lock_interruptible(&udev->mutex); in uinput_write()
612 retval = udev->state == UIST_CREATED ? in uinput_write()
616 mutex_unlock(&udev->mutex); in uinput_write()
626 spin_lock_irq(&udev->dev->event_lock); in uinput_fetch_next_event()
628 have_event = udev->head != udev->tail; in uinput_fetch_next_event()
630 *event = udev->buff[udev->tail]; in uinput_fetch_next_event()
631 udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; in uinput_fetch_next_event()
634 spin_unlock_irq(&udev->dev->event_lock); in uinput_fetch_next_event()
649 return -EFAULT; in uinput_events_to_user()
660 struct uinput_device *udev = file->private_data; in uinput_read()
664 return -EINVAL; in uinput_read()
667 retval = mutex_lock_interruptible(&udev->mutex); in uinput_read()
671 if (udev->state != UIST_CREATED) in uinput_read()
672 retval = -ENODEV; in uinput_read()
673 else if (udev->head == udev->tail && in uinput_read()
674 (file->f_flags & O_NONBLOCK)) in uinput_read()
675 retval = -EAGAIN; in uinput_read()
679 mutex_unlock(&udev->mutex); in uinput_read()
684 if (!(file->f_flags & O_NONBLOCK)) in uinput_read()
685 retval = wait_event_interruptible(udev->waitq, in uinput_read()
686 udev->head != udev->tail || in uinput_read()
687 udev->state != UIST_CREATED); in uinput_read()
695 struct uinput_device *udev = file->private_data; in uinput_poll()
698 poll_wait(file, &udev->waitq, wait); in uinput_poll()
700 if (udev->head != udev->tail) in uinput_poll()
708 struct uinput_device *udev = file->private_data; in uinput_release()
730 ff_up_compat.request_id = ff_up->request_id; in uinput_ff_upload_to_user()
731 ff_up_compat.retval = ff_up->retval; in uinput_ff_upload_to_user()
738 memcpy(&ff_up_compat.effect, &ff_up->effect, in uinput_ff_upload_to_user()
740 memcpy(&ff_up_compat.old, &ff_up->old, in uinput_ff_upload_to_user()
745 return -EFAULT; in uinput_ff_upload_to_user()
749 return -EFAULT; in uinput_ff_upload_to_user()
763 return -EFAULT; in uinput_ff_upload_from_user()
765 ff_up->request_id = ff_up_compat.request_id; in uinput_ff_upload_from_user()
766 ff_up->retval = ff_up_compat.retval; in uinput_ff_upload_from_user()
767 memcpy(&ff_up->effect, &ff_up_compat.effect, in uinput_ff_upload_from_user()
769 memcpy(&ff_up->old, &ff_up_compat.old, in uinput_ff_upload_from_user()
775 return -EFAULT; in uinput_ff_upload_from_user()
787 return -EFAULT; in uinput_ff_upload_to_user()
796 return -EFAULT; in uinput_ff_upload_from_user()
806 if (udev->state == UIST_CREATED) \
807 __ret = -EINVAL; \
809 __ret = -EINVAL; \
810 else set_bit((_arg), udev->dev->_bit); \
821 return -ENOENT; in uinput_str_to_user()
824 return -EINVAL; in uinput_str_to_user()
832 return -EFAULT; in uinput_str_to_user()
835 ret = put_user(0, p + len - 1); in uinput_str_to_user()
836 return ret ? -EFAULT : len; in uinput_str_to_user()
843 struct uinput_device *udev = file->private_data; in uinput_ioctl_handler()
851 retval = mutex_lock_interruptible(&udev->mutex); in uinput_ioctl_handler()
855 if (!udev->dev) { in uinput_ioctl_handler()
856 udev->dev = input_allocate_device(); in uinput_ioctl_handler()
857 if (!udev->dev) { in uinput_ioctl_handler()
858 retval = -ENOMEM; in uinput_ioctl_handler()
866 retval = -EFAULT; in uinput_ioctl_handler()
924 if (udev->state == UIST_CREATED) { in uinput_ioctl_handler()
925 retval = -EINVAL; in uinput_ioctl_handler()
935 kfree(udev->dev->phys); in uinput_ioctl_handler()
936 udev->dev->phys = phys; in uinput_ioctl_handler()
945 if (!req || req->code != UI_FF_UPLOAD || in uinput_ioctl_handler()
946 !req->u.upload.effect) { in uinput_ioctl_handler()
947 retval = -EINVAL; in uinput_ioctl_handler()
952 ff_up.effect = *req->u.upload.effect; in uinput_ioctl_handler()
953 if (req->u.upload.old) in uinput_ioctl_handler()
954 ff_up.old = *req->u.upload.old; in uinput_ioctl_handler()
963 retval = -EFAULT; in uinput_ioctl_handler()
968 if (!req || req->code != UI_FF_ERASE) { in uinput_ioctl_handler()
969 retval = -EINVAL; in uinput_ioctl_handler()
974 ff_erase.effect_id = req->u.effect_id; in uinput_ioctl_handler()
976 retval = -EFAULT; in uinput_ioctl_handler()
988 if (!req || req->code != UI_FF_UPLOAD || in uinput_ioctl_handler()
989 !req->u.upload.effect) { in uinput_ioctl_handler()
990 retval = -EINVAL; in uinput_ioctl_handler()
994 req->retval = ff_up.retval; in uinput_ioctl_handler()
995 complete(&req->done); in uinput_ioctl_handler()
1000 retval = -EFAULT; in uinput_ioctl_handler()
1005 if (!req || req->code != UI_FF_ERASE) { in uinput_ioctl_handler()
1006 retval = -EINVAL; in uinput_ioctl_handler()
1010 req->retval = ff_erase.retval; in uinput_ioctl_handler()
1011 complete(&req->done); in uinput_ioctl_handler()
1017 /* Now check variable-length commands */ in uinput_ioctl_handler()
1020 if (udev->state != UIST_CREATED) { in uinput_ioctl_handler()
1021 retval = -ENOENT; in uinput_ioctl_handler()
1024 name = dev_name(&udev->dev->dev); in uinput_ioctl_handler()
1033 retval = -EINVAL; in uinput_ioctl_handler()
1035 mutex_unlock(&udev->mutex); in uinput_ioctl_handler()