Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2 * f_hid.c -- USB HID function driver
  3 *
  4 * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com>
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License as published by
  8 * the Free Software Foundation; either version 2 of the License, or
  9 * (at your option) any later version.
 10 */
 11
 12#include <linux/kernel.h>
 13#include <linux/utsname.h>
 14#include <linux/module.h>
 15#include <linux/hid.h>
 16#include <linux/cdev.h>
 17#include <linux/mutex.h>
 18#include <linux/poll.h>
 19#include <linux/uaccess.h>
 20#include <linux/wait.h>
 21#include <linux/usb/g_hid.h>
 22
 23static int major, minors;
 24static struct class *hidg_class;
 25
 26/*-------------------------------------------------------------------------*/
 27/*                            HID gadget struct                            */
 28
 29struct f_hidg {
 30	/* configuration */
 31	unsigned char			bInterfaceSubClass;
 32	unsigned char			bInterfaceProtocol;
 33	unsigned short			report_desc_length;
 34	char				*report_desc;
 35	unsigned short			report_length;
 36
 37	/* recv report */
 38	char				*set_report_buff;
 39	unsigned short			set_report_length;
 40	spinlock_t			spinlock;
 41	wait_queue_head_t		read_queue;
 42
 43	/* send report */
 44	struct mutex			lock;
 45	bool				write_pending;
 46	wait_queue_head_t		write_queue;
 47	struct usb_request		*req;
 48
 49	int				minor;
 50	struct cdev			cdev;
 51	struct usb_function		func;
 52	struct usb_ep			*in_ep;
 53};
 54
 55static inline struct f_hidg *func_to_hidg(struct usb_function *f)
 56{
 57	return container_of(f, struct f_hidg, func);
 58}
 59
 60/*-------------------------------------------------------------------------*/
 61/*                           Static descriptors                            */
 62
 63static struct usb_interface_descriptor hidg_interface_desc = {
 64	.bLength		= sizeof hidg_interface_desc,
 65	.bDescriptorType	= USB_DT_INTERFACE,
 66	/* .bInterfaceNumber	= DYNAMIC */
 67	.bAlternateSetting	= 0,
 68	.bNumEndpoints		= 1,
 69	.bInterfaceClass	= USB_CLASS_HID,
 70	/* .bInterfaceSubClass	= DYNAMIC */
 71	/* .bInterfaceProtocol	= DYNAMIC */
 72	/* .iInterface		= DYNAMIC */
 73};
 74
 75static struct hid_descriptor hidg_desc = {
 76	.bLength			= sizeof hidg_desc,
 77	.bDescriptorType		= HID_DT_HID,
 78	.bcdHID				= 0x0101,
 79	.bCountryCode			= 0x00,
 80	.bNumDescriptors		= 0x1,
 81	/*.desc[0].bDescriptorType	= DYNAMIC */
 82	/*.desc[0].wDescriptorLenght	= DYNAMIC */
 83};
 84
 85/* High-Speed Support */
 86
 87static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = {
 88	.bLength		= USB_DT_ENDPOINT_SIZE,
 89	.bDescriptorType	= USB_DT_ENDPOINT,
 90	.bEndpointAddress	= USB_DIR_IN,
 91	.bmAttributes		= USB_ENDPOINT_XFER_INT,
 92	/*.wMaxPacketSize	= DYNAMIC */
 93	.bInterval		= 4, /* FIXME: Add this field in the
 94				      * HID gadget configuration?
 95				      * (struct hidg_func_descriptor)
 96				      */
 97};
 98
 99static struct usb_descriptor_header *hidg_hs_descriptors[] = {
100	(struct usb_descriptor_header *)&hidg_interface_desc,
101	(struct usb_descriptor_header *)&hidg_desc,
102	(struct usb_descriptor_header *)&hidg_hs_in_ep_desc,
103	NULL,
104};
105
106/* Full-Speed Support */
107
108static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = {
109	.bLength		= USB_DT_ENDPOINT_SIZE,
110	.bDescriptorType	= USB_DT_ENDPOINT,
111	.bEndpointAddress	= USB_DIR_IN,
112	.bmAttributes		= USB_ENDPOINT_XFER_INT,
113	/*.wMaxPacketSize	= DYNAMIC */
114	.bInterval		= 10, /* FIXME: Add this field in the
115				       * HID gadget configuration?
116				       * (struct hidg_func_descriptor)
117				       */
118};
119
120static struct usb_descriptor_header *hidg_fs_descriptors[] = {
121	(struct usb_descriptor_header *)&hidg_interface_desc,
122	(struct usb_descriptor_header *)&hidg_desc,
123	(struct usb_descriptor_header *)&hidg_fs_in_ep_desc,
124	NULL,
125};
126
127/*-------------------------------------------------------------------------*/
128/*                              Char Device                                */
129
130static ssize_t f_hidg_read(struct file *file, char __user *buffer,
131			size_t count, loff_t *ptr)
132{
133	struct f_hidg	*hidg     = file->private_data;
134	char		*tmp_buff = NULL;
135	unsigned long	flags;
136
137	if (!count)
138		return 0;
139
140	if (!access_ok(VERIFY_WRITE, buffer, count))
141		return -EFAULT;
142
143	spin_lock_irqsave(&hidg->spinlock, flags);
144
145#define READ_COND (hidg->set_report_buff != NULL)
146
147	while (!READ_COND) {
148		spin_unlock_irqrestore(&hidg->spinlock, flags);
149		if (file->f_flags & O_NONBLOCK)
150			return -EAGAIN;
151
152		if (wait_event_interruptible(hidg->read_queue, READ_COND))
153			return -ERESTARTSYS;
154
155		spin_lock_irqsave(&hidg->spinlock, flags);
156	}
157
158
159	count = min_t(unsigned, count, hidg->set_report_length);
160	tmp_buff = hidg->set_report_buff;
161	hidg->set_report_buff = NULL;
162
163	spin_unlock_irqrestore(&hidg->spinlock, flags);
164
165	if (tmp_buff != NULL) {
166		/* copy to user outside spinlock */
167		count -= copy_to_user(buffer, tmp_buff, count);
168		kfree(tmp_buff);
169	} else
170		count = -ENOMEM;
171
172	return count;
173}
174
175static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
176{
177	struct f_hidg *hidg = (struct f_hidg *)ep->driver_data;
178
179	if (req->status != 0) {
180		ERROR(hidg->func.config->cdev,
181			"End Point Request ERROR: %d\n", req->status);
182	}
183
184	hidg->write_pending = 0;
185	wake_up(&hidg->write_queue);
186}
187
188static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
189			    size_t count, loff_t *offp)
190{
191	struct f_hidg *hidg  = file->private_data;
192	ssize_t status = -ENOMEM;
193
194	if (!access_ok(VERIFY_READ, buffer, count))
195		return -EFAULT;
196
197	mutex_lock(&hidg->lock);
198
199#define WRITE_COND (!hidg->write_pending)
200
201	/* write queue */
202	while (!WRITE_COND) {
203		mutex_unlock(&hidg->lock);
204		if (file->f_flags & O_NONBLOCK)
205			return -EAGAIN;
206
207		if (wait_event_interruptible_exclusive(
208				hidg->write_queue, WRITE_COND))
209			return -ERESTARTSYS;
210
211		mutex_lock(&hidg->lock);
212	}
213
214	count  = min_t(unsigned, count, hidg->report_length);
215	status = copy_from_user(hidg->req->buf, buffer, count);
216
217	if (status != 0) {
218		ERROR(hidg->func.config->cdev,
219			"copy_from_user error\n");
220		mutex_unlock(&hidg->lock);
221		return -EINVAL;
222	}
223
224	hidg->req->status   = 0;
225	hidg->req->zero     = 0;
226	hidg->req->length   = count;
227	hidg->req->complete = f_hidg_req_complete;
228	hidg->req->context  = hidg;
229	hidg->write_pending = 1;
230
231	status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
232	if (status < 0) {
233		ERROR(hidg->func.config->cdev,
234			"usb_ep_queue error on int endpoint %zd\n", status);
235		hidg->write_pending = 0;
236		wake_up(&hidg->write_queue);
237	} else {
238		status = count;
239	}
240
241	mutex_unlock(&hidg->lock);
242
243	return status;
244}
245
246static unsigned int f_hidg_poll(struct file *file, poll_table *wait)
247{
248	struct f_hidg	*hidg  = file->private_data;
249	unsigned int	ret = 0;
250
251	poll_wait(file, &hidg->read_queue, wait);
252	poll_wait(file, &hidg->write_queue, wait);
253
254	if (WRITE_COND)
255		ret |= POLLOUT | POLLWRNORM;
256
257	if (READ_COND)
258		ret |= POLLIN | POLLRDNORM;
259
260	return ret;
261}
262
263#undef WRITE_COND
264#undef READ_COND
265
266static int f_hidg_release(struct inode *inode, struct file *fd)
267{
268	fd->private_data = NULL;
269	return 0;
270}
271
272static int f_hidg_open(struct inode *inode, struct file *fd)
273{
274	struct f_hidg *hidg =
275		container_of(inode->i_cdev, struct f_hidg, cdev);
276
277	fd->private_data = hidg;
278
279	return 0;
280}
281
282/*-------------------------------------------------------------------------*/
283/*                                usb_function                             */
284
285static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
286{
287	struct f_hidg *hidg = (struct f_hidg *)req->context;
288
289	if (req->status != 0 || req->buf == NULL || req->actual == 0) {
290		ERROR(hidg->func.config->cdev, "%s FAILED\n", __func__);
291		return;
292	}
293
294	spin_lock(&hidg->spinlock);
295
296	hidg->set_report_buff = krealloc(hidg->set_report_buff,
297					 req->actual, GFP_ATOMIC);
298
299	if (hidg->set_report_buff == NULL) {
300		spin_unlock(&hidg->spinlock);
301		return;
302	}
303	hidg->set_report_length = req->actual;
304	memcpy(hidg->set_report_buff, req->buf, req->actual);
305
306	spin_unlock(&hidg->spinlock);
307
308	wake_up(&hidg->read_queue);
309}
310
311static int hidg_setup(struct usb_function *f,
312		const struct usb_ctrlrequest *ctrl)
313{
314	struct f_hidg			*hidg = func_to_hidg(f);
315	struct usb_composite_dev	*cdev = f->config->cdev;
316	struct usb_request		*req  = cdev->req;
317	int status = 0;
318	__u16 value, length;
319
320	value	= __le16_to_cpu(ctrl->wValue);
321	length	= __le16_to_cpu(ctrl->wLength);
322
323	VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x "
324		"Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value);
325
326	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
327	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
328		  | HID_REQ_GET_REPORT):
329		VDBG(cdev, "get_report\n");
330
331		/* send an empty report */
332		length = min_t(unsigned, length, hidg->report_length);
333		memset(req->buf, 0x0, length);
334
335		goto respond;
336		break;
337
338	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
339		  | HID_REQ_GET_PROTOCOL):
340		VDBG(cdev, "get_protocol\n");
341		goto stall;
342		break;
343
344	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
345		  | HID_REQ_SET_REPORT):
346		VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength);
347		req->context  = hidg;
348		req->complete = hidg_set_report_complete;
349		goto respond;
350		break;
351
352	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
353		  | HID_REQ_SET_PROTOCOL):
354		VDBG(cdev, "set_protocol\n");
355		goto stall;
356		break;
357
358	case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
359		  | USB_REQ_GET_DESCRIPTOR):
360		switch (value >> 8) {
361		case HID_DT_HID:
362			VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
363			length = min_t(unsigned short, length,
364						   hidg_desc.bLength);
365			memcpy(req->buf, &hidg_desc, length);
366			goto respond;
367			break;
368		case HID_DT_REPORT:
369			VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n");
370			length = min_t(unsigned short, length,
371						   hidg->report_desc_length);
372			memcpy(req->buf, hidg->report_desc, length);
373			goto respond;
374			break;
375
376		default:
377			VDBG(cdev, "Unknown descriptor request 0x%x\n",
378				 value >> 8);
379			goto stall;
380			break;
381		}
382		break;
383
384	default:
385		VDBG(cdev, "Unknown request 0x%x\n",
386			 ctrl->bRequest);
387		goto stall;
388		break;
389	}
390
391stall:
392	return -EOPNOTSUPP;
393
394respond:
395	req->zero = 0;
396	req->length = length;
397	status = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
398	if (status < 0)
399		ERROR(cdev, "usb_ep_queue error on ep0 %d\n", value);
400	return status;
401}
402
403static void hidg_disable(struct usb_function *f)
404{
405	struct f_hidg *hidg = func_to_hidg(f);
406
407	usb_ep_disable(hidg->in_ep);
408	hidg->in_ep->driver_data = NULL;
409}
410
411static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
412{
413	struct usb_composite_dev		*cdev = f->config->cdev;
414	struct f_hidg				*hidg = func_to_hidg(f);
415	int status = 0;
416
417	VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
418
419	if (hidg->in_ep != NULL) {
420		/* restart endpoint */
421		if (hidg->in_ep->driver_data != NULL)
422			usb_ep_disable(hidg->in_ep);
423
424		status = config_ep_by_speed(f->config->cdev->gadget, f,
425					    hidg->in_ep);
426		if (status) {
427			ERROR(cdev, "config_ep_by_speed FAILED!\n");
428			goto fail;
429		}
430		status = usb_ep_enable(hidg->in_ep);
431		if (status < 0) {
432			ERROR(cdev, "Enable endpoint FAILED!\n");
433			goto fail;
434		}
435		hidg->in_ep->driver_data = hidg;
436	}
437fail:
438	return status;
439}
440
441const struct file_operations f_hidg_fops = {
442	.owner		= THIS_MODULE,
443	.open		= f_hidg_open,
444	.release	= f_hidg_release,
445	.write		= f_hidg_write,
446	.read		= f_hidg_read,
447	.poll		= f_hidg_poll,
448	.llseek		= noop_llseek,
449};
450
451static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
452{
453	struct usb_ep		*ep;
454	struct f_hidg		*hidg = func_to_hidg(f);
455	int			status;
456	dev_t			dev;
457
458	/* allocate instance-specific interface IDs, and patch descriptors */
459	status = usb_interface_id(c, f);
460	if (status < 0)
461		goto fail;
462	hidg_interface_desc.bInterfaceNumber = status;
463
464
465	/* allocate instance-specific endpoints */
466	status = -ENODEV;
467	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
468	if (!ep)
469		goto fail;
470	ep->driver_data = c->cdev;	/* claim */
471	hidg->in_ep = ep;
472
473	/* preallocate request and buffer */
474	status = -ENOMEM;
475	hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL);
476	if (!hidg->req)
477		goto fail;
478
479
480	hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL);
481	if (!hidg->req->buf)
482		goto fail;
483
484	/* set descriptor dynamic values */
485	hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
486	hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
487	hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
488	hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
489	hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
490	hidg_desc.desc[0].wDescriptorLength =
491		cpu_to_le16(hidg->report_desc_length);
492
493	hidg->set_report_buff = NULL;
494
495	/* copy descriptors */
496	f->descriptors = usb_copy_descriptors(hidg_fs_descriptors);
497	if (!f->descriptors)
498		goto fail;
499
500	if (gadget_is_dualspeed(c->cdev->gadget)) {
501		hidg_hs_in_ep_desc.bEndpointAddress =
502			hidg_fs_in_ep_desc.bEndpointAddress;
503		f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
504		if (!f->hs_descriptors)
505			goto fail;
506	}
507
508	mutex_init(&hidg->lock);
509	spin_lock_init(&hidg->spinlock);
510	init_waitqueue_head(&hidg->write_queue);
511	init_waitqueue_head(&hidg->read_queue);
512
513	/* create char device */
514	cdev_init(&hidg->cdev, &f_hidg_fops);
515	dev = MKDEV(major, hidg->minor);
516	status = cdev_add(&hidg->cdev, dev, 1);
517	if (status)
518		goto fail;
519
520	device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor);
521
522	return 0;
523
524fail:
525	ERROR(f->config->cdev, "hidg_bind FAILED\n");
526	if (hidg->req != NULL) {
527		kfree(hidg->req->buf);
528		if (hidg->in_ep != NULL)
529			usb_ep_free_request(hidg->in_ep, hidg->req);
530	}
531
532	usb_free_descriptors(f->hs_descriptors);
533	usb_free_descriptors(f->descriptors);
534
535	return status;
536}
537
538static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
539{
540	struct f_hidg *hidg = func_to_hidg(f);
541
542	device_destroy(hidg_class, MKDEV(major, hidg->minor));
543	cdev_del(&hidg->cdev);
544
545	/* disable/free request and end point */
546	usb_ep_disable(hidg->in_ep);
547	usb_ep_dequeue(hidg->in_ep, hidg->req);
548	kfree(hidg->req->buf);
549	usb_ep_free_request(hidg->in_ep, hidg->req);
550
551	/* free descriptors copies */
552	usb_free_descriptors(f->hs_descriptors);
553	usb_free_descriptors(f->descriptors);
554
555	kfree(hidg->report_desc);
556	kfree(hidg->set_report_buff);
557	kfree(hidg);
558}
559
560/*-------------------------------------------------------------------------*/
561/*                                 Strings                                 */
562
563#define CT_FUNC_HID_IDX	0
564
565static struct usb_string ct_func_string_defs[] = {
566	[CT_FUNC_HID_IDX].s	= "HID Interface",
567	{},			/* end of list */
568};
569
570static struct usb_gadget_strings ct_func_string_table = {
571	.language	= 0x0409,	/* en-US */
572	.strings	= ct_func_string_defs,
573};
574
575static struct usb_gadget_strings *ct_func_strings[] = {
576	&ct_func_string_table,
577	NULL,
578};
579
580/*-------------------------------------------------------------------------*/
581/*                             usb_configuration                           */
582
583int __init hidg_bind_config(struct usb_configuration *c,
584			    struct hidg_func_descriptor *fdesc, int index)
585{
586	struct f_hidg *hidg;
587	int status;
588
589	if (index >= minors)
590		return -ENOENT;
591
592	/* maybe allocate device-global string IDs, and patch descriptors */
593	if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) {
594		status = usb_string_id(c->cdev);
595		if (status < 0)
596			return status;
597		ct_func_string_defs[CT_FUNC_HID_IDX].id = status;
598		hidg_interface_desc.iInterface = status;
599	}
600
601	/* allocate and initialize one new instance */
602	hidg = kzalloc(sizeof *hidg, GFP_KERNEL);
603	if (!hidg)
604		return -ENOMEM;
605
606	hidg->minor = index;
607	hidg->bInterfaceSubClass = fdesc->subclass;
608	hidg->bInterfaceProtocol = fdesc->protocol;
609	hidg->report_length = fdesc->report_length;
610	hidg->report_desc_length = fdesc->report_desc_length;
611	hidg->report_desc = kmemdup(fdesc->report_desc,
612				    fdesc->report_desc_length,
613				    GFP_KERNEL);
614	if (!hidg->report_desc) {
615		kfree(hidg);
616		return -ENOMEM;
617	}
618
619	hidg->func.name    = "hid";
620	hidg->func.strings = ct_func_strings;
621	hidg->func.bind    = hidg_bind;
622	hidg->func.unbind  = hidg_unbind;
623	hidg->func.set_alt = hidg_set_alt;
624	hidg->func.disable = hidg_disable;
625	hidg->func.setup   = hidg_setup;
626
627	status = usb_add_function(c, &hidg->func);
628	if (status)
629		kfree(hidg);
630
631	return status;
632}
633
634int __init ghid_setup(struct usb_gadget *g, int count)
635{
636	int status;
637	dev_t dev;
638
639	hidg_class = class_create(THIS_MODULE, "hidg");
640
641	status = alloc_chrdev_region(&dev, 0, count, "hidg");
642	if (!status) {
643		major = MAJOR(dev);
644		minors = count;
645	}
646
647	return status;
648}
649
650void ghid_cleanup(void)
651{
652	if (major) {
653		unregister_chrdev_region(MKDEV(major, 0), minors);
654		major = minors = 0;
655	}
656
657	class_destroy(hidg_class);
658	hidg_class = NULL;
659}