Lines Matching refs:uhid
70 struct uhid_device *uhid = container_of(work, struct uhid_device, worker); in uhid_device_add_worker() local
73 ret = hid_add_device(uhid->hid); in uhid_device_add_worker()
75 hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret); in uhid_device_add_worker()
87 WRITE_ONCE(uhid->running, false); in uhid_device_add_worker()
88 wake_up_interruptible(&uhid->report_wait); in uhid_device_add_worker()
92 static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev) in uhid_queue() argument
96 newhead = (uhid->head + 1) % UHID_BUFSIZE; in uhid_queue()
98 if (newhead != uhid->tail) { in uhid_queue()
99 uhid->outq[uhid->head] = ev; in uhid_queue()
100 uhid->head = newhead; in uhid_queue()
101 wake_up_interruptible(&uhid->waitq); in uhid_queue()
103 hid_warn(uhid->hid, "Output queue is full\n"); in uhid_queue()
108 static int uhid_queue_event(struct uhid_device *uhid, __u32 event) in uhid_queue_event() argument
119 spin_lock_irqsave(&uhid->qlock, flags); in uhid_queue_event()
120 uhid_queue(uhid, ev); in uhid_queue_event()
121 spin_unlock_irqrestore(&uhid->qlock, flags); in uhid_queue_event()
128 struct uhid_device *uhid = hid->driver_data; in uhid_hid_start() local
145 spin_lock_irqsave(&uhid->qlock, flags); in uhid_hid_start()
146 uhid_queue(uhid, ev); in uhid_hid_start()
147 spin_unlock_irqrestore(&uhid->qlock, flags); in uhid_hid_start()
154 struct uhid_device *uhid = hid->driver_data; in uhid_hid_stop() local
157 uhid_queue_event(uhid, UHID_STOP); in uhid_hid_stop()
162 struct uhid_device *uhid = hid->driver_data; in uhid_hid_open() local
164 return uhid_queue_event(uhid, UHID_OPEN); in uhid_hid_open()
169 struct uhid_device *uhid = hid->driver_data; in uhid_hid_close() local
171 uhid_queue_event(uhid, UHID_CLOSE); in uhid_hid_close()
176 struct uhid_device *uhid = hid->driver_data; in uhid_hid_parse() local
178 return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); in uhid_hid_parse()
182 static int __uhid_report_queue_and_wait(struct uhid_device *uhid, in __uhid_report_queue_and_wait() argument
189 spin_lock_irqsave(&uhid->qlock, flags); in __uhid_report_queue_and_wait()
190 *report_id = ++uhid->report_id; in __uhid_report_queue_and_wait()
191 uhid->report_type = ev->type + 1; in __uhid_report_queue_and_wait()
192 uhid->report_running = true; in __uhid_report_queue_and_wait()
193 uhid_queue(uhid, ev); in __uhid_report_queue_and_wait()
194 spin_unlock_irqrestore(&uhid->qlock, flags); in __uhid_report_queue_and_wait()
196 ret = wait_event_interruptible_timeout(uhid->report_wait, in __uhid_report_queue_and_wait()
197 !uhid->report_running || !READ_ONCE(uhid->running), in __uhid_report_queue_and_wait()
199 if (!ret || !READ_ONCE(uhid->running) || uhid->report_running) in __uhid_report_queue_and_wait()
206 uhid->report_running = false; in __uhid_report_queue_and_wait()
211 static void uhid_report_wake_up(struct uhid_device *uhid, u32 id, in uhid_report_wake_up() argument
216 spin_lock_irqsave(&uhid->qlock, flags); in uhid_report_wake_up()
219 if (uhid->report_type != ev->type || uhid->report_id != id) in uhid_report_wake_up()
221 if (!uhid->report_running) in uhid_report_wake_up()
224 memcpy(&uhid->report_buf, ev, sizeof(*ev)); in uhid_report_wake_up()
225 uhid->report_running = false; in uhid_report_wake_up()
226 wake_up_interruptible(&uhid->report_wait); in uhid_report_wake_up()
229 spin_unlock_irqrestore(&uhid->qlock, flags); in uhid_report_wake_up()
235 struct uhid_device *uhid = hid->driver_data; in uhid_hid_get_report() local
240 if (!READ_ONCE(uhid->running)) in uhid_hid_get_report()
251 ret = mutex_lock_interruptible(&uhid->report_lock); in uhid_hid_get_report()
258 ret = __uhid_report_queue_and_wait(uhid, ev, &ev->u.get_report.id); in uhid_hid_get_report()
262 req = &uhid->report_buf.u.get_report_reply; in uhid_hid_get_report()
271 mutex_unlock(&uhid->report_lock); in uhid_hid_get_report()
278 struct uhid_device *uhid = hid->driver_data; in uhid_hid_set_report() local
282 if (!READ_ONCE(uhid->running) || count > UHID_DATA_MAX) in uhid_hid_set_report()
295 ret = mutex_lock_interruptible(&uhid->report_lock); in uhid_hid_set_report()
302 ret = __uhid_report_queue_and_wait(uhid, ev, &ev->u.set_report.id); in uhid_hid_set_report()
306 if (uhid->report_buf.u.set_report_reply.err) in uhid_hid_set_report()
312 mutex_unlock(&uhid->report_lock); in uhid_hid_set_report()
349 struct uhid_device *uhid = hid->driver_data; in uhid_hid_output_raw() local
377 spin_lock_irqsave(&uhid->qlock, flags); in uhid_hid_output_raw()
378 uhid_queue(uhid, ev); in uhid_hid_output_raw()
379 spin_unlock_irqrestore(&uhid->qlock, flags); in uhid_hid_output_raw()
489 static int uhid_dev_create2(struct uhid_device *uhid, in uhid_dev_create2() argument
497 if (uhid->hid) in uhid_dev_create2()
508 uhid->rd_size = rd_size; in uhid_dev_create2()
509 uhid->rd_data = rd_data; in uhid_dev_create2()
531 hid->driver_data = uhid; in uhid_dev_create2()
534 uhid->hid = hid; in uhid_dev_create2()
535 uhid->running = true; in uhid_dev_create2()
541 schedule_work(&uhid->worker); in uhid_dev_create2()
546 kfree(uhid->rd_data); in uhid_dev_create2()
547 uhid->rd_data = NULL; in uhid_dev_create2()
548 uhid->rd_size = 0; in uhid_dev_create2()
552 static int uhid_dev_create(struct uhid_device *uhid, in uhid_dev_create() argument
574 return uhid_dev_create2(uhid, ev); in uhid_dev_create()
577 static int uhid_dev_destroy(struct uhid_device *uhid) in uhid_dev_destroy() argument
579 if (!uhid->hid) in uhid_dev_destroy()
582 WRITE_ONCE(uhid->running, false); in uhid_dev_destroy()
583 wake_up_interruptible(&uhid->report_wait); in uhid_dev_destroy()
585 cancel_work_sync(&uhid->worker); in uhid_dev_destroy()
587 hid_destroy_device(uhid->hid); in uhid_dev_destroy()
588 uhid->hid = NULL; in uhid_dev_destroy()
589 kfree(uhid->rd_data); in uhid_dev_destroy()
594 static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev) in uhid_dev_input() argument
596 if (!READ_ONCE(uhid->running)) in uhid_dev_input()
599 hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, in uhid_dev_input()
605 static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev) in uhid_dev_input2() argument
607 if (!READ_ONCE(uhid->running)) in uhid_dev_input2()
610 hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data, in uhid_dev_input2()
616 static int uhid_dev_get_report_reply(struct uhid_device *uhid, in uhid_dev_get_report_reply() argument
619 if (!READ_ONCE(uhid->running)) in uhid_dev_get_report_reply()
622 uhid_report_wake_up(uhid, ev->u.get_report_reply.id, ev); in uhid_dev_get_report_reply()
626 static int uhid_dev_set_report_reply(struct uhid_device *uhid, in uhid_dev_set_report_reply() argument
629 if (!READ_ONCE(uhid->running)) in uhid_dev_set_report_reply()
632 uhid_report_wake_up(uhid, ev->u.set_report_reply.id, ev); in uhid_dev_set_report_reply()
638 struct uhid_device *uhid; in uhid_char_open() local
640 uhid = kzalloc(sizeof(*uhid), GFP_KERNEL); in uhid_char_open()
641 if (!uhid) in uhid_char_open()
644 mutex_init(&uhid->devlock); in uhid_char_open()
645 mutex_init(&uhid->report_lock); in uhid_char_open()
646 spin_lock_init(&uhid->qlock); in uhid_char_open()
647 init_waitqueue_head(&uhid->waitq); in uhid_char_open()
648 init_waitqueue_head(&uhid->report_wait); in uhid_char_open()
649 uhid->running = false; in uhid_char_open()
650 INIT_WORK(&uhid->worker, uhid_device_add_worker); in uhid_char_open()
652 file->private_data = uhid; in uhid_char_open()
660 struct uhid_device *uhid = file->private_data; in uhid_char_release() local
663 uhid_dev_destroy(uhid); in uhid_char_release()
666 kfree(uhid->outq[i]); in uhid_char_release()
668 kfree(uhid); in uhid_char_release()
676 struct uhid_device *uhid = file->private_data; in uhid_char_read() local
687 if (uhid->head == uhid->tail) in uhid_char_read()
690 ret = wait_event_interruptible(uhid->waitq, in uhid_char_read()
691 uhid->head != uhid->tail); in uhid_char_read()
696 ret = mutex_lock_interruptible(&uhid->devlock); in uhid_char_read()
700 if (uhid->head == uhid->tail) { in uhid_char_read()
701 mutex_unlock(&uhid->devlock); in uhid_char_read()
704 len = min(count, sizeof(**uhid->outq)); in uhid_char_read()
705 if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) { in uhid_char_read()
708 kfree(uhid->outq[uhid->tail]); in uhid_char_read()
709 uhid->outq[uhid->tail] = NULL; in uhid_char_read()
711 spin_lock_irqsave(&uhid->qlock, flags); in uhid_char_read()
712 uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE; in uhid_char_read()
713 spin_unlock_irqrestore(&uhid->qlock, flags); in uhid_char_read()
717 mutex_unlock(&uhid->devlock); in uhid_char_read()
724 struct uhid_device *uhid = file->private_data; in uhid_char_write() local
732 ret = mutex_lock_interruptible(&uhid->devlock); in uhid_char_write()
736 memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); in uhid_char_write()
737 len = min(count, sizeof(uhid->input_buf)); in uhid_char_write()
739 ret = uhid_event_from_user(buffer, len, &uhid->input_buf); in uhid_char_write()
743 switch (uhid->input_buf.type) { in uhid_char_write()
756 ret = uhid_dev_create(uhid, &uhid->input_buf); in uhid_char_write()
759 ret = uhid_dev_create2(uhid, &uhid->input_buf); in uhid_char_write()
762 ret = uhid_dev_destroy(uhid); in uhid_char_write()
765 ret = uhid_dev_input(uhid, &uhid->input_buf); in uhid_char_write()
768 ret = uhid_dev_input2(uhid, &uhid->input_buf); in uhid_char_write()
771 ret = uhid_dev_get_report_reply(uhid, &uhid->input_buf); in uhid_char_write()
774 ret = uhid_dev_set_report_reply(uhid, &uhid->input_buf); in uhid_char_write()
781 mutex_unlock(&uhid->devlock); in uhid_char_write()
789 struct uhid_device *uhid = file->private_data; in uhid_char_poll() local
792 poll_wait(file, &uhid->waitq, wait); in uhid_char_poll()
794 if (uhid->head != uhid->tail) in uhid_char_poll()