xref: /linux/drivers/usb/gadget/function/f_loopback.c (revision 5fd54ace4721fc5ce2bb5aef6318fcf17f421460)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * f_loopback.c - USB peripheral loopback configuration driver
4  *
5  * Copyright (C) 2003-2008 David Brownell
6  * Copyright (C) 2008 by Nokia Corporation
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 /* #define VERBOSE_DEBUG */
15 
16 #include <linux/slab.h>
17 #include <linux/kernel.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include <linux/err.h>
21 #include <linux/usb/composite.h>
22 
23 #include "g_zero.h"
24 #include "u_f.h"
25 
26 /*
27  * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals,
28  *
29  * This takes messages of various sizes written OUT to a device, and loops
30  * them back so they can be read IN from it.  It has been used by certain
31  * test applications.  It supports limited testing of data queueing logic.
32  */
33 struct f_loopback {
34 	struct usb_function	function;
35 
36 	struct usb_ep		*in_ep;
37 	struct usb_ep		*out_ep;
38 
39 	unsigned                qlen;
40 	unsigned                buflen;
41 };
42 
43 static inline struct f_loopback *func_to_loop(struct usb_function *f)
44 {
45 	return container_of(f, struct f_loopback, function);
46 }
47 
48 /*-------------------------------------------------------------------------*/
49 
50 static struct usb_interface_descriptor loopback_intf = {
51 	.bLength =		sizeof(loopback_intf),
52 	.bDescriptorType =	USB_DT_INTERFACE,
53 
54 	.bNumEndpoints =	2,
55 	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
56 	/* .iInterface = DYNAMIC */
57 };
58 
59 /* full speed support: */
60 
61 static struct usb_endpoint_descriptor fs_loop_source_desc = {
62 	.bLength =		USB_DT_ENDPOINT_SIZE,
63 	.bDescriptorType =	USB_DT_ENDPOINT,
64 
65 	.bEndpointAddress =	USB_DIR_IN,
66 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
67 };
68 
69 static struct usb_endpoint_descriptor fs_loop_sink_desc = {
70 	.bLength =		USB_DT_ENDPOINT_SIZE,
71 	.bDescriptorType =	USB_DT_ENDPOINT,
72 
73 	.bEndpointAddress =	USB_DIR_OUT,
74 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
75 };
76 
77 static struct usb_descriptor_header *fs_loopback_descs[] = {
78 	(struct usb_descriptor_header *) &loopback_intf,
79 	(struct usb_descriptor_header *) &fs_loop_sink_desc,
80 	(struct usb_descriptor_header *) &fs_loop_source_desc,
81 	NULL,
82 };
83 
84 /* high speed support: */
85 
86 static struct usb_endpoint_descriptor hs_loop_source_desc = {
87 	.bLength =		USB_DT_ENDPOINT_SIZE,
88 	.bDescriptorType =	USB_DT_ENDPOINT,
89 
90 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
91 	.wMaxPacketSize =	cpu_to_le16(512),
92 };
93 
94 static struct usb_endpoint_descriptor hs_loop_sink_desc = {
95 	.bLength =		USB_DT_ENDPOINT_SIZE,
96 	.bDescriptorType =	USB_DT_ENDPOINT,
97 
98 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
99 	.wMaxPacketSize =	cpu_to_le16(512),
100 };
101 
102 static struct usb_descriptor_header *hs_loopback_descs[] = {
103 	(struct usb_descriptor_header *) &loopback_intf,
104 	(struct usb_descriptor_header *) &hs_loop_source_desc,
105 	(struct usb_descriptor_header *) &hs_loop_sink_desc,
106 	NULL,
107 };
108 
109 /* super speed support: */
110 
111 static struct usb_endpoint_descriptor ss_loop_source_desc = {
112 	.bLength =		USB_DT_ENDPOINT_SIZE,
113 	.bDescriptorType =	USB_DT_ENDPOINT,
114 
115 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
116 	.wMaxPacketSize =	cpu_to_le16(1024),
117 };
118 
119 static struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = {
120 	.bLength =		USB_DT_SS_EP_COMP_SIZE,
121 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
122 	.bMaxBurst =		0,
123 	.bmAttributes =		0,
124 	.wBytesPerInterval =	0,
125 };
126 
127 static struct usb_endpoint_descriptor ss_loop_sink_desc = {
128 	.bLength =		USB_DT_ENDPOINT_SIZE,
129 	.bDescriptorType =	USB_DT_ENDPOINT,
130 
131 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
132 	.wMaxPacketSize =	cpu_to_le16(1024),
133 };
134 
135 static struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = {
136 	.bLength =		USB_DT_SS_EP_COMP_SIZE,
137 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
138 	.bMaxBurst =		0,
139 	.bmAttributes =		0,
140 	.wBytesPerInterval =	0,
141 };
142 
143 static struct usb_descriptor_header *ss_loopback_descs[] = {
144 	(struct usb_descriptor_header *) &loopback_intf,
145 	(struct usb_descriptor_header *) &ss_loop_source_desc,
146 	(struct usb_descriptor_header *) &ss_loop_source_comp_desc,
147 	(struct usb_descriptor_header *) &ss_loop_sink_desc,
148 	(struct usb_descriptor_header *) &ss_loop_sink_comp_desc,
149 	NULL,
150 };
151 
152 /* function-specific strings: */
153 
154 static struct usb_string strings_loopback[] = {
155 	[0].s = "loop input to output",
156 	{  }			/* end of list */
157 };
158 
159 static struct usb_gadget_strings stringtab_loop = {
160 	.language	= 0x0409,	/* en-us */
161 	.strings	= strings_loopback,
162 };
163 
164 static struct usb_gadget_strings *loopback_strings[] = {
165 	&stringtab_loop,
166 	NULL,
167 };
168 
169 /*-------------------------------------------------------------------------*/
170 
171 static int loopback_bind(struct usb_configuration *c, struct usb_function *f)
172 {
173 	struct usb_composite_dev *cdev = c->cdev;
174 	struct f_loopback	*loop = func_to_loop(f);
175 	int			id;
176 	int ret;
177 
178 	/* allocate interface ID(s) */
179 	id = usb_interface_id(c, f);
180 	if (id < 0)
181 		return id;
182 	loopback_intf.bInterfaceNumber = id;
183 
184 	id = usb_string_id(cdev);
185 	if (id < 0)
186 		return id;
187 	strings_loopback[0].id = id;
188 	loopback_intf.iInterface = id;
189 
190 	/* allocate endpoints */
191 
192 	loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc);
193 	if (!loop->in_ep) {
194 autoconf_fail:
195 		ERROR(cdev, "%s: can't autoconfigure on %s\n",
196 			f->name, cdev->gadget->name);
197 		return -ENODEV;
198 	}
199 
200 	loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
201 	if (!loop->out_ep)
202 		goto autoconf_fail;
203 
204 	/* support high speed hardware */
205 	hs_loop_source_desc.bEndpointAddress =
206 		fs_loop_source_desc.bEndpointAddress;
207 	hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
208 
209 	/* support super speed hardware */
210 	ss_loop_source_desc.bEndpointAddress =
211 		fs_loop_source_desc.bEndpointAddress;
212 	ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress;
213 
214 	ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs,
215 			ss_loopback_descs, NULL);
216 	if (ret)
217 		return ret;
218 
219 	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
220 	    (gadget_is_superspeed(c->cdev->gadget) ? "super" :
221 	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
222 			f->name, loop->in_ep->name, loop->out_ep->name);
223 	return 0;
224 }
225 
226 static void lb_free_func(struct usb_function *f)
227 {
228 	struct f_lb_opts *opts;
229 
230 	opts = container_of(f->fi, struct f_lb_opts, func_inst);
231 
232 	mutex_lock(&opts->lock);
233 	opts->refcnt--;
234 	mutex_unlock(&opts->lock);
235 
236 	usb_free_all_descriptors(f);
237 	kfree(func_to_loop(f));
238 }
239 
240 static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
241 {
242 	struct f_loopback	*loop = ep->driver_data;
243 	struct usb_composite_dev *cdev = loop->function.config->cdev;
244 	int			status = req->status;
245 
246 	switch (status) {
247 	case 0:				/* normal completion? */
248 		if (ep == loop->out_ep) {
249 			/*
250 			 * We received some data from the host so let's
251 			 * queue it so host can read the from our in ep
252 			 */
253 			struct usb_request *in_req = req->context;
254 
255 			in_req->zero = (req->actual < req->length);
256 			in_req->length = req->actual;
257 			ep = loop->in_ep;
258 			req = in_req;
259 		} else {
260 			/*
261 			 * We have just looped back a bunch of data
262 			 * to host. Now let's wait for some more data.
263 			 */
264 			req = req->context;
265 			ep = loop->out_ep;
266 		}
267 
268 		/* queue the buffer back to host or for next bunch of data */
269 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
270 		if (status == 0) {
271 			return;
272 		} else {
273 			ERROR(cdev, "Unable to loop back buffer to %s: %d\n",
274 			      ep->name, status);
275 			goto free_req;
276 		}
277 
278 		/* "should never get here" */
279 	default:
280 		ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
281 				status, req->actual, req->length);
282 		/* FALLTHROUGH */
283 
284 	/* NOTE:  since this driver doesn't maintain an explicit record
285 	 * of requests it submitted (just maintains qlen count), we
286 	 * rely on the hardware driver to clean up on disconnect or
287 	 * endpoint disable.
288 	 */
289 	case -ECONNABORTED:		/* hardware forced ep reset */
290 	case -ECONNRESET:		/* request dequeued */
291 	case -ESHUTDOWN:		/* disconnect from host */
292 free_req:
293 		usb_ep_free_request(ep == loop->in_ep ?
294 				    loop->out_ep : loop->in_ep,
295 				    req->context);
296 		free_ep_req(ep, req);
297 		return;
298 	}
299 }
300 
301 static void disable_loopback(struct f_loopback *loop)
302 {
303 	struct usb_composite_dev	*cdev;
304 
305 	cdev = loop->function.config->cdev;
306 	disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
307 	VDBG(cdev, "%s disabled\n", loop->function.name);
308 }
309 
310 static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
311 {
312 	return alloc_ep_req(ep, len);
313 }
314 
315 static int alloc_requests(struct usb_composite_dev *cdev,
316 			  struct f_loopback *loop)
317 {
318 	struct usb_request *in_req, *out_req;
319 	int i;
320 	int result = 0;
321 
322 	/*
323 	 * allocate a bunch of read buffers and queue them all at once.
324 	 * we buffer at most 'qlen' transfers; We allocate buffers only
325 	 * for out transfer and reuse them in IN transfers to implement
326 	 * our loopback functionality
327 	 */
328 	for (i = 0; i < loop->qlen && result == 0; i++) {
329 		result = -ENOMEM;
330 
331 		in_req = usb_ep_alloc_request(loop->in_ep, GFP_ATOMIC);
332 		if (!in_req)
333 			goto fail;
334 
335 		out_req = lb_alloc_ep_req(loop->out_ep, loop->buflen);
336 		if (!out_req)
337 			goto fail_in;
338 
339 		in_req->complete = loopback_complete;
340 		out_req->complete = loopback_complete;
341 
342 		in_req->buf = out_req->buf;
343 		/* length will be set in complete routine */
344 		in_req->context = out_req;
345 		out_req->context = in_req;
346 
347 		result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC);
348 		if (result) {
349 			ERROR(cdev, "%s queue req --> %d\n",
350 					loop->out_ep->name, result);
351 			goto fail_out;
352 		}
353 	}
354 
355 	return 0;
356 
357 fail_out:
358 	free_ep_req(loop->out_ep, out_req);
359 fail_in:
360 	usb_ep_free_request(loop->in_ep, in_req);
361 fail:
362 	return result;
363 }
364 
365 static int enable_endpoint(struct usb_composite_dev *cdev,
366 			   struct f_loopback *loop, struct usb_ep *ep)
367 {
368 	int					result;
369 
370 	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
371 	if (result)
372 		goto out;
373 
374 	result = usb_ep_enable(ep);
375 	if (result < 0)
376 		goto out;
377 	ep->driver_data = loop;
378 	result = 0;
379 
380 out:
381 	return result;
382 }
383 
384 static int
385 enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
386 {
387 	int					result = 0;
388 
389 	result = enable_endpoint(cdev, loop, loop->in_ep);
390 	if (result)
391 		goto out;
392 
393 	result = enable_endpoint(cdev, loop, loop->out_ep);
394 	if (result)
395 		goto disable_in;
396 
397 	result = alloc_requests(cdev, loop);
398 	if (result)
399 		goto disable_out;
400 
401 	DBG(cdev, "%s enabled\n", loop->function.name);
402 	return 0;
403 
404 disable_out:
405 	usb_ep_disable(loop->out_ep);
406 disable_in:
407 	usb_ep_disable(loop->in_ep);
408 out:
409 	return result;
410 }
411 
412 static int loopback_set_alt(struct usb_function *f,
413 		unsigned intf, unsigned alt)
414 {
415 	struct f_loopback	*loop = func_to_loop(f);
416 	struct usb_composite_dev *cdev = f->config->cdev;
417 
418 	/* we know alt is zero */
419 	disable_loopback(loop);
420 	return enable_loopback(cdev, loop);
421 }
422 
423 static void loopback_disable(struct usb_function *f)
424 {
425 	struct f_loopback	*loop = func_to_loop(f);
426 
427 	disable_loopback(loop);
428 }
429 
430 static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
431 {
432 	struct f_loopback	*loop;
433 	struct f_lb_opts	*lb_opts;
434 
435 	loop = kzalloc(sizeof *loop, GFP_KERNEL);
436 	if (!loop)
437 		return ERR_PTR(-ENOMEM);
438 
439 	lb_opts = container_of(fi, struct f_lb_opts, func_inst);
440 
441 	mutex_lock(&lb_opts->lock);
442 	lb_opts->refcnt++;
443 	mutex_unlock(&lb_opts->lock);
444 
445 	loop->buflen = lb_opts->bulk_buflen;
446 	loop->qlen = lb_opts->qlen;
447 	if (!loop->qlen)
448 		loop->qlen = 32;
449 
450 	loop->function.name = "loopback";
451 	loop->function.bind = loopback_bind;
452 	loop->function.set_alt = loopback_set_alt;
453 	loop->function.disable = loopback_disable;
454 	loop->function.strings = loopback_strings;
455 
456 	loop->function.free_func = lb_free_func;
457 
458 	return &loop->function;
459 }
460 
461 static inline struct f_lb_opts *to_f_lb_opts(struct config_item *item)
462 {
463 	return container_of(to_config_group(item), struct f_lb_opts,
464 			    func_inst.group);
465 }
466 
467 static void lb_attr_release(struct config_item *item)
468 {
469 	struct f_lb_opts *lb_opts = to_f_lb_opts(item);
470 
471 	usb_put_function_instance(&lb_opts->func_inst);
472 }
473 
474 static struct configfs_item_operations lb_item_ops = {
475 	.release		= lb_attr_release,
476 };
477 
478 static ssize_t f_lb_opts_qlen_show(struct config_item *item, char *page)
479 {
480 	struct f_lb_opts *opts = to_f_lb_opts(item);
481 	int result;
482 
483 	mutex_lock(&opts->lock);
484 	result = sprintf(page, "%d\n", opts->qlen);
485 	mutex_unlock(&opts->lock);
486 
487 	return result;
488 }
489 
490 static ssize_t f_lb_opts_qlen_store(struct config_item *item,
491 				    const char *page, size_t len)
492 {
493 	struct f_lb_opts *opts = to_f_lb_opts(item);
494 	int ret;
495 	u32 num;
496 
497 	mutex_lock(&opts->lock);
498 	if (opts->refcnt) {
499 		ret = -EBUSY;
500 		goto end;
501 	}
502 
503 	ret = kstrtou32(page, 0, &num);
504 	if (ret)
505 		goto end;
506 
507 	opts->qlen = num;
508 	ret = len;
509 end:
510 	mutex_unlock(&opts->lock);
511 	return ret;
512 }
513 
514 CONFIGFS_ATTR(f_lb_opts_, qlen);
515 
516 static ssize_t f_lb_opts_bulk_buflen_show(struct config_item *item, char *page)
517 {
518 	struct f_lb_opts *opts = to_f_lb_opts(item);
519 	int result;
520 
521 	mutex_lock(&opts->lock);
522 	result = sprintf(page, "%d\n", opts->bulk_buflen);
523 	mutex_unlock(&opts->lock);
524 
525 	return result;
526 }
527 
528 static ssize_t f_lb_opts_bulk_buflen_store(struct config_item *item,
529 				    const char *page, size_t len)
530 {
531 	struct f_lb_opts *opts = to_f_lb_opts(item);
532 	int ret;
533 	u32 num;
534 
535 	mutex_lock(&opts->lock);
536 	if (opts->refcnt) {
537 		ret = -EBUSY;
538 		goto end;
539 	}
540 
541 	ret = kstrtou32(page, 0, &num);
542 	if (ret)
543 		goto end;
544 
545 	opts->bulk_buflen = num;
546 	ret = len;
547 end:
548 	mutex_unlock(&opts->lock);
549 	return ret;
550 }
551 
552 CONFIGFS_ATTR(f_lb_opts_, bulk_buflen);
553 
554 static struct configfs_attribute *lb_attrs[] = {
555 	&f_lb_opts_attr_qlen,
556 	&f_lb_opts_attr_bulk_buflen,
557 	NULL,
558 };
559 
560 static struct config_item_type lb_func_type = {
561 	.ct_item_ops    = &lb_item_ops,
562 	.ct_attrs	= lb_attrs,
563 	.ct_owner       = THIS_MODULE,
564 };
565 
566 static void lb_free_instance(struct usb_function_instance *fi)
567 {
568 	struct f_lb_opts *lb_opts;
569 
570 	lb_opts = container_of(fi, struct f_lb_opts, func_inst);
571 	kfree(lb_opts);
572 }
573 
574 static struct usb_function_instance *loopback_alloc_instance(void)
575 {
576 	struct f_lb_opts *lb_opts;
577 
578 	lb_opts = kzalloc(sizeof(*lb_opts), GFP_KERNEL);
579 	if (!lb_opts)
580 		return ERR_PTR(-ENOMEM);
581 	mutex_init(&lb_opts->lock);
582 	lb_opts->func_inst.free_func_inst = lb_free_instance;
583 	lb_opts->bulk_buflen = GZERO_BULK_BUFLEN;
584 	lb_opts->qlen = GZERO_QLEN;
585 
586 	config_group_init_type_name(&lb_opts->func_inst.group, "",
587 				    &lb_func_type);
588 
589 	return  &lb_opts->func_inst;
590 }
591 DECLARE_USB_FUNCTION(Loopback, loopback_alloc_instance, loopback_alloc);
592 
593 int __init lb_modinit(void)
594 {
595 	return usb_function_register(&Loopbackusb_func);
596 }
597 
598 void __exit lb_modexit(void)
599 {
600 	usb_function_unregister(&Loopbackusb_func);
601 }
602 
603 MODULE_LICENSE("GPL");
604