cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

f_sourcesink.c (31772B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * f_sourcesink.c - USB peripheral source/sink configuration driver
      4 *
      5 * Copyright (C) 2003-2008 David Brownell
      6 * Copyright (C) 2008 by Nokia Corporation
      7 */
      8
      9/* #define VERBOSE_DEBUG */
     10
     11#include <linux/slab.h>
     12#include <linux/kernel.h>
     13#include <linux/device.h>
     14#include <linux/module.h>
     15#include <linux/usb/composite.h>
     16#include <linux/err.h>
     17
     18#include "g_zero.h"
     19#include "u_f.h"
     20
     21/*
     22 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
     23 * controller drivers.
     24 *
     25 * This just sinks bulk packets OUT to the peripheral and sources them IN
     26 * to the host, optionally with specific data patterns for integrity tests.
     27 * As such it supports basic functionality and load tests.
     28 *
     29 * In terms of control messaging, this supports all the standard requests
     30 * plus two that support control-OUT tests.  If the optional "autoresume"
     31 * mode is enabled, it provides good functional coverage for the "USBCV"
     32 * test harness from USB-IF.
     33 */
     34struct f_sourcesink {
     35	struct usb_function	function;
     36
     37	struct usb_ep		*in_ep;
     38	struct usb_ep		*out_ep;
     39	struct usb_ep		*iso_in_ep;
     40	struct usb_ep		*iso_out_ep;
     41	int			cur_alt;
     42
     43	unsigned pattern;
     44	unsigned isoc_interval;
     45	unsigned isoc_maxpacket;
     46	unsigned isoc_mult;
     47	unsigned isoc_maxburst;
     48	unsigned buflen;
     49	unsigned bulk_qlen;
     50	unsigned iso_qlen;
     51};
     52
     53static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
     54{
     55	return container_of(f, struct f_sourcesink, function);
     56}
     57
     58/*-------------------------------------------------------------------------*/
     59
     60static struct usb_interface_descriptor source_sink_intf_alt0 = {
     61	.bLength =		USB_DT_INTERFACE_SIZE,
     62	.bDescriptorType =	USB_DT_INTERFACE,
     63
     64	.bAlternateSetting =	0,
     65	.bNumEndpoints =	2,
     66	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
     67	/* .iInterface		= DYNAMIC */
     68};
     69
     70static struct usb_interface_descriptor source_sink_intf_alt1 = {
     71	.bLength =		USB_DT_INTERFACE_SIZE,
     72	.bDescriptorType =	USB_DT_INTERFACE,
     73
     74	.bAlternateSetting =	1,
     75	.bNumEndpoints =	4,
     76	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
     77	/* .iInterface		= DYNAMIC */
     78};
     79
     80/* full speed support: */
     81
     82static struct usb_endpoint_descriptor fs_source_desc = {
     83	.bLength =		USB_DT_ENDPOINT_SIZE,
     84	.bDescriptorType =	USB_DT_ENDPOINT,
     85
     86	.bEndpointAddress =	USB_DIR_IN,
     87	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
     88};
     89
     90static struct usb_endpoint_descriptor fs_sink_desc = {
     91	.bLength =		USB_DT_ENDPOINT_SIZE,
     92	.bDescriptorType =	USB_DT_ENDPOINT,
     93
     94	.bEndpointAddress =	USB_DIR_OUT,
     95	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
     96};
     97
     98static struct usb_endpoint_descriptor fs_iso_source_desc = {
     99	.bLength =		USB_DT_ENDPOINT_SIZE,
    100	.bDescriptorType =	USB_DT_ENDPOINT,
    101
    102	.bEndpointAddress =	USB_DIR_IN,
    103	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    104	.wMaxPacketSize =	cpu_to_le16(1023),
    105	.bInterval =		4,
    106};
    107
    108static struct usb_endpoint_descriptor fs_iso_sink_desc = {
    109	.bLength =		USB_DT_ENDPOINT_SIZE,
    110	.bDescriptorType =	USB_DT_ENDPOINT,
    111
    112	.bEndpointAddress =	USB_DIR_OUT,
    113	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    114	.wMaxPacketSize =	cpu_to_le16(1023),
    115	.bInterval =		4,
    116};
    117
    118static struct usb_descriptor_header *fs_source_sink_descs[] = {
    119	(struct usb_descriptor_header *) &source_sink_intf_alt0,
    120	(struct usb_descriptor_header *) &fs_sink_desc,
    121	(struct usb_descriptor_header *) &fs_source_desc,
    122	(struct usb_descriptor_header *) &source_sink_intf_alt1,
    123#define FS_ALT_IFC_1_OFFSET	3
    124	(struct usb_descriptor_header *) &fs_sink_desc,
    125	(struct usb_descriptor_header *) &fs_source_desc,
    126	(struct usb_descriptor_header *) &fs_iso_sink_desc,
    127	(struct usb_descriptor_header *) &fs_iso_source_desc,
    128	NULL,
    129};
    130
    131/* high speed support: */
    132
    133static struct usb_endpoint_descriptor hs_source_desc = {
    134	.bLength =		USB_DT_ENDPOINT_SIZE,
    135	.bDescriptorType =	USB_DT_ENDPOINT,
    136
    137	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
    138	.wMaxPacketSize =	cpu_to_le16(512),
    139};
    140
    141static struct usb_endpoint_descriptor hs_sink_desc = {
    142	.bLength =		USB_DT_ENDPOINT_SIZE,
    143	.bDescriptorType =	USB_DT_ENDPOINT,
    144
    145	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
    146	.wMaxPacketSize =	cpu_to_le16(512),
    147};
    148
    149static struct usb_endpoint_descriptor hs_iso_source_desc = {
    150	.bLength =		USB_DT_ENDPOINT_SIZE,
    151	.bDescriptorType =	USB_DT_ENDPOINT,
    152
    153	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    154	.wMaxPacketSize =	cpu_to_le16(1024),
    155	.bInterval =		4,
    156};
    157
    158static struct usb_endpoint_descriptor hs_iso_sink_desc = {
    159	.bLength =		USB_DT_ENDPOINT_SIZE,
    160	.bDescriptorType =	USB_DT_ENDPOINT,
    161
    162	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    163	.wMaxPacketSize =	cpu_to_le16(1024),
    164	.bInterval =		4,
    165};
    166
    167static struct usb_descriptor_header *hs_source_sink_descs[] = {
    168	(struct usb_descriptor_header *) &source_sink_intf_alt0,
    169	(struct usb_descriptor_header *) &hs_source_desc,
    170	(struct usb_descriptor_header *) &hs_sink_desc,
    171	(struct usb_descriptor_header *) &source_sink_intf_alt1,
    172#define HS_ALT_IFC_1_OFFSET	3
    173	(struct usb_descriptor_header *) &hs_source_desc,
    174	(struct usb_descriptor_header *) &hs_sink_desc,
    175	(struct usb_descriptor_header *) &hs_iso_source_desc,
    176	(struct usb_descriptor_header *) &hs_iso_sink_desc,
    177	NULL,
    178};
    179
    180/* super speed support: */
    181
    182static struct usb_endpoint_descriptor ss_source_desc = {
    183	.bLength =		USB_DT_ENDPOINT_SIZE,
    184	.bDescriptorType =	USB_DT_ENDPOINT,
    185
    186	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
    187	.wMaxPacketSize =	cpu_to_le16(1024),
    188};
    189
    190static struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
    191	.bLength =		USB_DT_SS_EP_COMP_SIZE,
    192	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
    193
    194	.bMaxBurst =		0,
    195	.bmAttributes =		0,
    196	.wBytesPerInterval =	0,
    197};
    198
    199static struct usb_endpoint_descriptor ss_sink_desc = {
    200	.bLength =		USB_DT_ENDPOINT_SIZE,
    201	.bDescriptorType =	USB_DT_ENDPOINT,
    202
    203	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
    204	.wMaxPacketSize =	cpu_to_le16(1024),
    205};
    206
    207static struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
    208	.bLength =		USB_DT_SS_EP_COMP_SIZE,
    209	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
    210
    211	.bMaxBurst =		0,
    212	.bmAttributes =		0,
    213	.wBytesPerInterval =	0,
    214};
    215
    216static struct usb_endpoint_descriptor ss_iso_source_desc = {
    217	.bLength =		USB_DT_ENDPOINT_SIZE,
    218	.bDescriptorType =	USB_DT_ENDPOINT,
    219
    220	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    221	.wMaxPacketSize =	cpu_to_le16(1024),
    222	.bInterval =		4,
    223};
    224
    225static struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
    226	.bLength =		USB_DT_SS_EP_COMP_SIZE,
    227	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
    228
    229	.bMaxBurst =		0,
    230	.bmAttributes =		0,
    231	.wBytesPerInterval =	cpu_to_le16(1024),
    232};
    233
    234static struct usb_endpoint_descriptor ss_iso_sink_desc = {
    235	.bLength =		USB_DT_ENDPOINT_SIZE,
    236	.bDescriptorType =	USB_DT_ENDPOINT,
    237
    238	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
    239	.wMaxPacketSize =	cpu_to_le16(1024),
    240	.bInterval =		4,
    241};
    242
    243static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
    244	.bLength =		USB_DT_SS_EP_COMP_SIZE,
    245	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
    246
    247	.bMaxBurst =		0,
    248	.bmAttributes =		0,
    249	.wBytesPerInterval =	cpu_to_le16(1024),
    250};
    251
    252static struct usb_descriptor_header *ss_source_sink_descs[] = {
    253	(struct usb_descriptor_header *) &source_sink_intf_alt0,
    254	(struct usb_descriptor_header *) &ss_source_desc,
    255	(struct usb_descriptor_header *) &ss_source_comp_desc,
    256	(struct usb_descriptor_header *) &ss_sink_desc,
    257	(struct usb_descriptor_header *) &ss_sink_comp_desc,
    258	(struct usb_descriptor_header *) &source_sink_intf_alt1,
    259#define SS_ALT_IFC_1_OFFSET	5
    260	(struct usb_descriptor_header *) &ss_source_desc,
    261	(struct usb_descriptor_header *) &ss_source_comp_desc,
    262	(struct usb_descriptor_header *) &ss_sink_desc,
    263	(struct usb_descriptor_header *) &ss_sink_comp_desc,
    264	(struct usb_descriptor_header *) &ss_iso_source_desc,
    265	(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
    266	(struct usb_descriptor_header *) &ss_iso_sink_desc,
    267	(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
    268	NULL,
    269};
    270
    271/* function-specific strings: */
    272
    273static struct usb_string strings_sourcesink[] = {
    274	[0].s = "source and sink data",
    275	{  }			/* end of list */
    276};
    277
    278static struct usb_gadget_strings stringtab_sourcesink = {
    279	.language	= 0x0409,	/* en-us */
    280	.strings	= strings_sourcesink,
    281};
    282
    283static struct usb_gadget_strings *sourcesink_strings[] = {
    284	&stringtab_sourcesink,
    285	NULL,
    286};
    287
    288/*-------------------------------------------------------------------------*/
    289
    290static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
    291{
    292	return alloc_ep_req(ep, len);
    293}
    294
    295static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
    296{
    297	int			value;
    298
    299	value = usb_ep_disable(ep);
    300	if (value < 0)
    301		DBG(cdev, "disable %s --> %d\n", ep->name, value);
    302}
    303
    304void disable_endpoints(struct usb_composite_dev *cdev,
    305		struct usb_ep *in, struct usb_ep *out,
    306		struct usb_ep *iso_in, struct usb_ep *iso_out)
    307{
    308	disable_ep(cdev, in);
    309	disable_ep(cdev, out);
    310	if (iso_in)
    311		disable_ep(cdev, iso_in);
    312	if (iso_out)
    313		disable_ep(cdev, iso_out);
    314}
    315
    316static int
    317sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
    318{
    319	struct usb_composite_dev *cdev = c->cdev;
    320	struct f_sourcesink	*ss = func_to_ss(f);
    321	int	id;
    322	int ret;
    323
    324	/* allocate interface ID(s) */
    325	id = usb_interface_id(c, f);
    326	if (id < 0)
    327		return id;
    328	source_sink_intf_alt0.bInterfaceNumber = id;
    329	source_sink_intf_alt1.bInterfaceNumber = id;
    330
    331	/* allocate bulk endpoints */
    332	ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
    333	if (!ss->in_ep) {
    334autoconf_fail:
    335		ERROR(cdev, "%s: can't autoconfigure on %s\n",
    336			f->name, cdev->gadget->name);
    337		return -ENODEV;
    338	}
    339
    340	ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
    341	if (!ss->out_ep)
    342		goto autoconf_fail;
    343
    344	/* sanity check the isoc module parameters */
    345	if (ss->isoc_interval < 1)
    346		ss->isoc_interval = 1;
    347	if (ss->isoc_interval > 16)
    348		ss->isoc_interval = 16;
    349	if (ss->isoc_mult > 2)
    350		ss->isoc_mult = 2;
    351	if (ss->isoc_maxburst > 15)
    352		ss->isoc_maxburst = 15;
    353
    354	/* fill in the FS isoc descriptors from the module parameters */
    355	fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
    356						1023 : ss->isoc_maxpacket;
    357	fs_iso_source_desc.bInterval = ss->isoc_interval;
    358	fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
    359						1023 : ss->isoc_maxpacket;
    360	fs_iso_sink_desc.bInterval = ss->isoc_interval;
    361
    362	/* allocate iso endpoints */
    363	ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
    364	if (!ss->iso_in_ep)
    365		goto no_iso;
    366
    367	ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
    368	if (!ss->iso_out_ep) {
    369		usb_ep_autoconfig_release(ss->iso_in_ep);
    370		ss->iso_in_ep = NULL;
    371no_iso:
    372		/*
    373		 * We still want to work even if the UDC doesn't have isoc
    374		 * endpoints, so null out the alt interface that contains
    375		 * them and continue.
    376		 */
    377		fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
    378		hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
    379		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
    380	}
    381
    382	if (ss->isoc_maxpacket > 1024)
    383		ss->isoc_maxpacket = 1024;
    384
    385	/* support high speed hardware */
    386	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
    387	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
    388
    389	/*
    390	 * Fill in the HS isoc descriptors from the module parameters.
    391	 * We assume that the user knows what they are doing and won't
    392	 * give parameters that their UDC doesn't support.
    393	 */
    394	hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
    395	hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11;
    396	hs_iso_source_desc.bInterval = ss->isoc_interval;
    397	hs_iso_source_desc.bEndpointAddress =
    398		fs_iso_source_desc.bEndpointAddress;
    399
    400	hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
    401	hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11;
    402	hs_iso_sink_desc.bInterval = ss->isoc_interval;
    403	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
    404
    405	/* support super speed hardware */
    406	ss_source_desc.bEndpointAddress =
    407		fs_source_desc.bEndpointAddress;
    408	ss_sink_desc.bEndpointAddress =
    409		fs_sink_desc.bEndpointAddress;
    410
    411	/*
    412	 * Fill in the SS isoc descriptors from the module parameters.
    413	 * We assume that the user knows what they are doing and won't
    414	 * give parameters that their UDC doesn't support.
    415	 */
    416	ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
    417	ss_iso_source_desc.bInterval = ss->isoc_interval;
    418	ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult;
    419	ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst;
    420	ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
    421		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
    422	ss_iso_source_desc.bEndpointAddress =
    423		fs_iso_source_desc.bEndpointAddress;
    424
    425	ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
    426	ss_iso_sink_desc.bInterval = ss->isoc_interval;
    427	ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult;
    428	ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst;
    429	ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
    430		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
    431	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
    432
    433	ret = usb_assign_descriptors(f, fs_source_sink_descs,
    434			hs_source_sink_descs, ss_source_sink_descs,
    435			ss_source_sink_descs);
    436	if (ret)
    437		return ret;
    438
    439	DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
    440	    (gadget_is_superspeed(c->cdev->gadget) ? "super" :
    441	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
    442			f->name, ss->in_ep->name, ss->out_ep->name,
    443			ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
    444			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
    445	return 0;
    446}
    447
    448static void
    449sourcesink_free_func(struct usb_function *f)
    450{
    451	struct f_ss_opts *opts;
    452
    453	opts = container_of(f->fi, struct f_ss_opts, func_inst);
    454
    455	mutex_lock(&opts->lock);
    456	opts->refcnt--;
    457	mutex_unlock(&opts->lock);
    458
    459	usb_free_all_descriptors(f);
    460	kfree(func_to_ss(f));
    461}
    462
    463/* optionally require specific source/sink data patterns  */
    464static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
    465{
    466	unsigned		i;
    467	u8			*buf = req->buf;
    468	struct usb_composite_dev *cdev = ss->function.config->cdev;
    469	int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
    470
    471	if (ss->pattern == 2)
    472		return 0;
    473
    474	for (i = 0; i < req->actual; i++, buf++) {
    475		switch (ss->pattern) {
    476
    477		/* all-zeroes has no synchronization issues */
    478		case 0:
    479			if (*buf == 0)
    480				continue;
    481			break;
    482
    483		/* "mod63" stays in sync with short-terminated transfers,
    484		 * OR otherwise when host and gadget agree on how large
    485		 * each usb transfer request should be.  Resync is done
    486		 * with set_interface or set_config.  (We *WANT* it to
    487		 * get quickly out of sync if controllers or their drivers
    488		 * stutter for any reason, including buffer duplication...)
    489		 */
    490		case 1:
    491			if (*buf == (u8)((i % max_packet_size) % 63))
    492				continue;
    493			break;
    494		}
    495		ERROR(cdev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
    496		usb_ep_set_halt(ss->out_ep);
    497		return -EINVAL;
    498	}
    499	return 0;
    500}
    501
    502static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
    503{
    504	unsigned	i;
    505	u8		*buf = req->buf;
    506	int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
    507	struct f_sourcesink *ss = ep->driver_data;
    508
    509	switch (ss->pattern) {
    510	case 0:
    511		memset(req->buf, 0, req->length);
    512		break;
    513	case 1:
    514		for  (i = 0; i < req->length; i++)
    515			*buf++ = (u8) ((i % max_packet_size) % 63);
    516		break;
    517	case 2:
    518		break;
    519	}
    520}
    521
    522static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
    523{
    524	struct usb_composite_dev	*cdev;
    525	struct f_sourcesink		*ss = ep->driver_data;
    526	int				status = req->status;
    527
    528	/* driver_data will be null if ep has been disabled */
    529	if (!ss)
    530		return;
    531
    532	cdev = ss->function.config->cdev;
    533
    534	switch (status) {
    535
    536	case 0:				/* normal completion? */
    537		if (ep == ss->out_ep) {
    538			check_read_data(ss, req);
    539			if (ss->pattern != 2)
    540				memset(req->buf, 0x55, req->length);
    541		}
    542		break;
    543
    544	/* this endpoint is normally active while we're configured */
    545	case -ECONNABORTED:		/* hardware forced ep reset */
    546	case -ECONNRESET:		/* request dequeued */
    547	case -ESHUTDOWN:		/* disconnect from host */
    548		VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status,
    549				req->actual, req->length);
    550		if (ep == ss->out_ep)
    551			check_read_data(ss, req);
    552		free_ep_req(ep, req);
    553		return;
    554
    555	case -EOVERFLOW:		/* buffer overrun on read means that
    556					 * we didn't provide a big enough
    557					 * buffer.
    558					 */
    559	default:
    560#if 1
    561		DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name,
    562				status, req->actual, req->length);
    563		break;
    564#endif
    565	case -EREMOTEIO:		/* short read */
    566		break;
    567	}
    568
    569	status = usb_ep_queue(ep, req, GFP_ATOMIC);
    570	if (status) {
    571		ERROR(cdev, "kill %s:  resubmit %d bytes --> %d\n",
    572				ep->name, req->length, status);
    573		usb_ep_set_halt(ep);
    574		/* FIXME recover later ... somehow */
    575	}
    576}
    577
    578static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
    579		bool is_iso, int speed)
    580{
    581	struct usb_ep		*ep;
    582	struct usb_request	*req;
    583	int			i, size, qlen, status = 0;
    584
    585	if (is_iso) {
    586		switch (speed) {
    587		case USB_SPEED_SUPER_PLUS:
    588		case USB_SPEED_SUPER:
    589			size = ss->isoc_maxpacket *
    590					(ss->isoc_mult + 1) *
    591					(ss->isoc_maxburst + 1);
    592			break;
    593		case USB_SPEED_HIGH:
    594			size = ss->isoc_maxpacket * (ss->isoc_mult + 1);
    595			break;
    596		default:
    597			size = ss->isoc_maxpacket > 1023 ?
    598					1023 : ss->isoc_maxpacket;
    599			break;
    600		}
    601		ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
    602		qlen = ss->iso_qlen;
    603	} else {
    604		ep = is_in ? ss->in_ep : ss->out_ep;
    605		qlen = ss->bulk_qlen;
    606		size = ss->buflen;
    607	}
    608
    609	for (i = 0; i < qlen; i++) {
    610		req = ss_alloc_ep_req(ep, size);
    611		if (!req)
    612			return -ENOMEM;
    613
    614		req->complete = source_sink_complete;
    615		if (is_in)
    616			reinit_write_data(ep, req);
    617		else if (ss->pattern != 2)
    618			memset(req->buf, 0x55, req->length);
    619
    620		status = usb_ep_queue(ep, req, GFP_ATOMIC);
    621		if (status) {
    622			struct usb_composite_dev	*cdev;
    623
    624			cdev = ss->function.config->cdev;
    625			ERROR(cdev, "start %s%s %s --> %d\n",
    626			      is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
    627			      ep->name, status);
    628			free_ep_req(ep, req);
    629			return status;
    630		}
    631	}
    632
    633	return status;
    634}
    635
    636static void disable_source_sink(struct f_sourcesink *ss)
    637{
    638	struct usb_composite_dev	*cdev;
    639
    640	cdev = ss->function.config->cdev;
    641	disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
    642			ss->iso_out_ep);
    643	VDBG(cdev, "%s disabled\n", ss->function.name);
    644}
    645
    646static int
    647enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
    648		int alt)
    649{
    650	int					result = 0;
    651	int					speed = cdev->gadget->speed;
    652	struct usb_ep				*ep;
    653
    654	/* one bulk endpoint writes (sources) zeroes IN (to the host) */
    655	ep = ss->in_ep;
    656	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
    657	if (result)
    658		return result;
    659	result = usb_ep_enable(ep);
    660	if (result < 0)
    661		return result;
    662	ep->driver_data = ss;
    663
    664	result = source_sink_start_ep(ss, true, false, speed);
    665	if (result < 0) {
    666fail:
    667		ep = ss->in_ep;
    668		usb_ep_disable(ep);
    669		return result;
    670	}
    671
    672	/* one bulk endpoint reads (sinks) anything OUT (from the host) */
    673	ep = ss->out_ep;
    674	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
    675	if (result)
    676		goto fail;
    677	result = usb_ep_enable(ep);
    678	if (result < 0)
    679		goto fail;
    680	ep->driver_data = ss;
    681
    682	result = source_sink_start_ep(ss, false, false, speed);
    683	if (result < 0) {
    684fail2:
    685		ep = ss->out_ep;
    686		usb_ep_disable(ep);
    687		goto fail;
    688	}
    689
    690	if (alt == 0)
    691		goto out;
    692
    693	/* one iso endpoint writes (sources) zeroes IN (to the host) */
    694	ep = ss->iso_in_ep;
    695	if (ep) {
    696		result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
    697		if (result)
    698			goto fail2;
    699		result = usb_ep_enable(ep);
    700		if (result < 0)
    701			goto fail2;
    702		ep->driver_data = ss;
    703
    704		result = source_sink_start_ep(ss, true, true, speed);
    705		if (result < 0) {
    706fail3:
    707			ep = ss->iso_in_ep;
    708			if (ep)
    709				usb_ep_disable(ep);
    710			goto fail2;
    711		}
    712	}
    713
    714	/* one iso endpoint reads (sinks) anything OUT (from the host) */
    715	ep = ss->iso_out_ep;
    716	if (ep) {
    717		result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
    718		if (result)
    719			goto fail3;
    720		result = usb_ep_enable(ep);
    721		if (result < 0)
    722			goto fail3;
    723		ep->driver_data = ss;
    724
    725		result = source_sink_start_ep(ss, false, true, speed);
    726		if (result < 0) {
    727			usb_ep_disable(ep);
    728			goto fail3;
    729		}
    730	}
    731out:
    732	ss->cur_alt = alt;
    733
    734	DBG(cdev, "%s enabled, alt intf %d\n", ss->function.name, alt);
    735	return result;
    736}
    737
    738static int sourcesink_set_alt(struct usb_function *f,
    739		unsigned intf, unsigned alt)
    740{
    741	struct f_sourcesink		*ss = func_to_ss(f);
    742	struct usb_composite_dev	*cdev = f->config->cdev;
    743
    744	disable_source_sink(ss);
    745	return enable_source_sink(cdev, ss, alt);
    746}
    747
    748static int sourcesink_get_alt(struct usb_function *f, unsigned intf)
    749{
    750	struct f_sourcesink		*ss = func_to_ss(f);
    751
    752	return ss->cur_alt;
    753}
    754
    755static void sourcesink_disable(struct usb_function *f)
    756{
    757	struct f_sourcesink	*ss = func_to_ss(f);
    758
    759	disable_source_sink(ss);
    760}
    761
    762/*-------------------------------------------------------------------------*/
    763
    764static int sourcesink_setup(struct usb_function *f,
    765		const struct usb_ctrlrequest *ctrl)
    766{
    767	struct usb_configuration        *c = f->config;
    768	struct usb_request	*req = c->cdev->req;
    769	int			value = -EOPNOTSUPP;
    770	u16			w_index = le16_to_cpu(ctrl->wIndex);
    771	u16			w_value = le16_to_cpu(ctrl->wValue);
    772	u16			w_length = le16_to_cpu(ctrl->wLength);
    773
    774	req->length = USB_COMP_EP0_BUFSIZ;
    775
    776	/* composite driver infrastructure handles everything except
    777	 * the two control test requests.
    778	 */
    779	switch (ctrl->bRequest) {
    780
    781	/*
    782	 * These are the same vendor-specific requests supported by
    783	 * Intel's USB 2.0 compliance test devices.  We exceed that
    784	 * device spec by allowing multiple-packet requests.
    785	 *
    786	 * NOTE:  the Control-OUT data stays in req->buf ... better
    787	 * would be copying it into a scratch buffer, so that other
    788	 * requests may safely intervene.
    789	 */
    790	case 0x5b:	/* control WRITE test -- fill the buffer */
    791		if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
    792			goto unknown;
    793		if (w_value || w_index)
    794			break;
    795		/* just read that many bytes into the buffer */
    796		if (w_length > req->length)
    797			break;
    798		value = w_length;
    799		break;
    800	case 0x5c:	/* control READ test -- return the buffer */
    801		if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
    802			goto unknown;
    803		if (w_value || w_index)
    804			break;
    805		/* expect those bytes are still in the buffer; send back */
    806		if (w_length > req->length)
    807			break;
    808		value = w_length;
    809		break;
    810
    811	default:
    812unknown:
    813		VDBG(c->cdev,
    814			"unknown control req%02x.%02x v%04x i%04x l%d\n",
    815			ctrl->bRequestType, ctrl->bRequest,
    816			w_value, w_index, w_length);
    817	}
    818
    819	/* respond with data transfer or status phase? */
    820	if (value >= 0) {
    821		VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
    822			ctrl->bRequestType, ctrl->bRequest,
    823			w_value, w_index, w_length);
    824		req->zero = 0;
    825		req->length = value;
    826		value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
    827		if (value < 0)
    828			ERROR(c->cdev, "source/sink response, err %d\n",
    829					value);
    830	}
    831
    832	/* device either stalls (value < 0) or reports success */
    833	return value;
    834}
    835
    836static struct usb_function *source_sink_alloc_func(
    837		struct usb_function_instance *fi)
    838{
    839	struct f_sourcesink     *ss;
    840	struct f_ss_opts	*ss_opts;
    841
    842	ss = kzalloc(sizeof(*ss), GFP_KERNEL);
    843	if (!ss)
    844		return ERR_PTR(-ENOMEM);
    845
    846	ss_opts =  container_of(fi, struct f_ss_opts, func_inst);
    847
    848	mutex_lock(&ss_opts->lock);
    849	ss_opts->refcnt++;
    850	mutex_unlock(&ss_opts->lock);
    851
    852	ss->pattern = ss_opts->pattern;
    853	ss->isoc_interval = ss_opts->isoc_interval;
    854	ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
    855	ss->isoc_mult = ss_opts->isoc_mult;
    856	ss->isoc_maxburst = ss_opts->isoc_maxburst;
    857	ss->buflen = ss_opts->bulk_buflen;
    858	ss->bulk_qlen = ss_opts->bulk_qlen;
    859	ss->iso_qlen = ss_opts->iso_qlen;
    860
    861	ss->function.name = "source/sink";
    862	ss->function.bind = sourcesink_bind;
    863	ss->function.set_alt = sourcesink_set_alt;
    864	ss->function.get_alt = sourcesink_get_alt;
    865	ss->function.disable = sourcesink_disable;
    866	ss->function.setup = sourcesink_setup;
    867	ss->function.strings = sourcesink_strings;
    868
    869	ss->function.free_func = sourcesink_free_func;
    870
    871	return &ss->function;
    872}
    873
    874static inline struct f_ss_opts *to_f_ss_opts(struct config_item *item)
    875{
    876	return container_of(to_config_group(item), struct f_ss_opts,
    877			    func_inst.group);
    878}
    879
    880static void ss_attr_release(struct config_item *item)
    881{
    882	struct f_ss_opts *ss_opts = to_f_ss_opts(item);
    883
    884	usb_put_function_instance(&ss_opts->func_inst);
    885}
    886
    887static struct configfs_item_operations ss_item_ops = {
    888	.release		= ss_attr_release,
    889};
    890
    891static ssize_t f_ss_opts_pattern_show(struct config_item *item, char *page)
    892{
    893	struct f_ss_opts *opts = to_f_ss_opts(item);
    894	int result;
    895
    896	mutex_lock(&opts->lock);
    897	result = sprintf(page, "%u\n", opts->pattern);
    898	mutex_unlock(&opts->lock);
    899
    900	return result;
    901}
    902
    903static ssize_t f_ss_opts_pattern_store(struct config_item *item,
    904				       const char *page, size_t len)
    905{
    906	struct f_ss_opts *opts = to_f_ss_opts(item);
    907	int ret;
    908	u8 num;
    909
    910	mutex_lock(&opts->lock);
    911	if (opts->refcnt) {
    912		ret = -EBUSY;
    913		goto end;
    914	}
    915
    916	ret = kstrtou8(page, 0, &num);
    917	if (ret)
    918		goto end;
    919
    920	if (num != 0 && num != 1 && num != 2) {
    921		ret = -EINVAL;
    922		goto end;
    923	}
    924
    925	opts->pattern = num;
    926	ret = len;
    927end:
    928	mutex_unlock(&opts->lock);
    929	return ret;
    930}
    931
    932CONFIGFS_ATTR(f_ss_opts_, pattern);
    933
    934static ssize_t f_ss_opts_isoc_interval_show(struct config_item *item, char *page)
    935{
    936	struct f_ss_opts *opts = to_f_ss_opts(item);
    937	int result;
    938
    939	mutex_lock(&opts->lock);
    940	result = sprintf(page, "%u\n", opts->isoc_interval);
    941	mutex_unlock(&opts->lock);
    942
    943	return result;
    944}
    945
    946static ssize_t f_ss_opts_isoc_interval_store(struct config_item *item,
    947				       const char *page, size_t len)
    948{
    949	struct f_ss_opts *opts = to_f_ss_opts(item);
    950	int ret;
    951	u8 num;
    952
    953	mutex_lock(&opts->lock);
    954	if (opts->refcnt) {
    955		ret = -EBUSY;
    956		goto end;
    957	}
    958
    959	ret = kstrtou8(page, 0, &num);
    960	if (ret)
    961		goto end;
    962
    963	if (num > 16) {
    964		ret = -EINVAL;
    965		goto end;
    966	}
    967
    968	opts->isoc_interval = num;
    969	ret = len;
    970end:
    971	mutex_unlock(&opts->lock);
    972	return ret;
    973}
    974
    975CONFIGFS_ATTR(f_ss_opts_, isoc_interval);
    976
    977static ssize_t f_ss_opts_isoc_maxpacket_show(struct config_item *item, char *page)
    978{
    979	struct f_ss_opts *opts = to_f_ss_opts(item);
    980	int result;
    981
    982	mutex_lock(&opts->lock);
    983	result = sprintf(page, "%u\n", opts->isoc_maxpacket);
    984	mutex_unlock(&opts->lock);
    985
    986	return result;
    987}
    988
    989static ssize_t f_ss_opts_isoc_maxpacket_store(struct config_item *item,
    990				       const char *page, size_t len)
    991{
    992	struct f_ss_opts *opts = to_f_ss_opts(item);
    993	int ret;
    994	u16 num;
    995
    996	mutex_lock(&opts->lock);
    997	if (opts->refcnt) {
    998		ret = -EBUSY;
    999		goto end;
   1000	}
   1001
   1002	ret = kstrtou16(page, 0, &num);
   1003	if (ret)
   1004		goto end;
   1005
   1006	if (num > 1024) {
   1007		ret = -EINVAL;
   1008		goto end;
   1009	}
   1010
   1011	opts->isoc_maxpacket = num;
   1012	ret = len;
   1013end:
   1014	mutex_unlock(&opts->lock);
   1015	return ret;
   1016}
   1017
   1018CONFIGFS_ATTR(f_ss_opts_, isoc_maxpacket);
   1019
   1020static ssize_t f_ss_opts_isoc_mult_show(struct config_item *item, char *page)
   1021{
   1022	struct f_ss_opts *opts = to_f_ss_opts(item);
   1023	int result;
   1024
   1025	mutex_lock(&opts->lock);
   1026	result = sprintf(page, "%u\n", opts->isoc_mult);
   1027	mutex_unlock(&opts->lock);
   1028
   1029	return result;
   1030}
   1031
   1032static ssize_t f_ss_opts_isoc_mult_store(struct config_item *item,
   1033				       const char *page, size_t len)
   1034{
   1035	struct f_ss_opts *opts = to_f_ss_opts(item);
   1036	int ret;
   1037	u8 num;
   1038
   1039	mutex_lock(&opts->lock);
   1040	if (opts->refcnt) {
   1041		ret = -EBUSY;
   1042		goto end;
   1043	}
   1044
   1045	ret = kstrtou8(page, 0, &num);
   1046	if (ret)
   1047		goto end;
   1048
   1049	if (num > 2) {
   1050		ret = -EINVAL;
   1051		goto end;
   1052	}
   1053
   1054	opts->isoc_mult = num;
   1055	ret = len;
   1056end:
   1057	mutex_unlock(&opts->lock);
   1058	return ret;
   1059}
   1060
   1061CONFIGFS_ATTR(f_ss_opts_, isoc_mult);
   1062
   1063static ssize_t f_ss_opts_isoc_maxburst_show(struct config_item *item, char *page)
   1064{
   1065	struct f_ss_opts *opts = to_f_ss_opts(item);
   1066	int result;
   1067
   1068	mutex_lock(&opts->lock);
   1069	result = sprintf(page, "%u\n", opts->isoc_maxburst);
   1070	mutex_unlock(&opts->lock);
   1071
   1072	return result;
   1073}
   1074
   1075static ssize_t f_ss_opts_isoc_maxburst_store(struct config_item *item,
   1076				       const char *page, size_t len)
   1077{
   1078	struct f_ss_opts *opts = to_f_ss_opts(item);
   1079	int ret;
   1080	u8 num;
   1081
   1082	mutex_lock(&opts->lock);
   1083	if (opts->refcnt) {
   1084		ret = -EBUSY;
   1085		goto end;
   1086	}
   1087
   1088	ret = kstrtou8(page, 0, &num);
   1089	if (ret)
   1090		goto end;
   1091
   1092	if (num > 15) {
   1093		ret = -EINVAL;
   1094		goto end;
   1095	}
   1096
   1097	opts->isoc_maxburst = num;
   1098	ret = len;
   1099end:
   1100	mutex_unlock(&opts->lock);
   1101	return ret;
   1102}
   1103
   1104CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst);
   1105
   1106static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page)
   1107{
   1108	struct f_ss_opts *opts = to_f_ss_opts(item);
   1109	int result;
   1110
   1111	mutex_lock(&opts->lock);
   1112	result = sprintf(page, "%u\n", opts->bulk_buflen);
   1113	mutex_unlock(&opts->lock);
   1114
   1115	return result;
   1116}
   1117
   1118static ssize_t f_ss_opts_bulk_buflen_store(struct config_item *item,
   1119					   const char *page, size_t len)
   1120{
   1121	struct f_ss_opts *opts = to_f_ss_opts(item);
   1122	int ret;
   1123	u32 num;
   1124
   1125	mutex_lock(&opts->lock);
   1126	if (opts->refcnt) {
   1127		ret = -EBUSY;
   1128		goto end;
   1129	}
   1130
   1131	ret = kstrtou32(page, 0, &num);
   1132	if (ret)
   1133		goto end;
   1134
   1135	opts->bulk_buflen = num;
   1136	ret = len;
   1137end:
   1138	mutex_unlock(&opts->lock);
   1139	return ret;
   1140}
   1141
   1142CONFIGFS_ATTR(f_ss_opts_, bulk_buflen);
   1143
   1144static ssize_t f_ss_opts_bulk_qlen_show(struct config_item *item, char *page)
   1145{
   1146	struct f_ss_opts *opts = to_f_ss_opts(item);
   1147	int result;
   1148
   1149	mutex_lock(&opts->lock);
   1150	result = sprintf(page, "%u\n", opts->bulk_qlen);
   1151	mutex_unlock(&opts->lock);
   1152
   1153	return result;
   1154}
   1155
   1156static ssize_t f_ss_opts_bulk_qlen_store(struct config_item *item,
   1157					   const char *page, size_t len)
   1158{
   1159	struct f_ss_opts *opts = to_f_ss_opts(item);
   1160	int ret;
   1161	u32 num;
   1162
   1163	mutex_lock(&opts->lock);
   1164	if (opts->refcnt) {
   1165		ret = -EBUSY;
   1166		goto end;
   1167	}
   1168
   1169	ret = kstrtou32(page, 0, &num);
   1170	if (ret)
   1171		goto end;
   1172
   1173	opts->bulk_qlen = num;
   1174	ret = len;
   1175end:
   1176	mutex_unlock(&opts->lock);
   1177	return ret;
   1178}
   1179
   1180CONFIGFS_ATTR(f_ss_opts_, bulk_qlen);
   1181
   1182static ssize_t f_ss_opts_iso_qlen_show(struct config_item *item, char *page)
   1183{
   1184	struct f_ss_opts *opts = to_f_ss_opts(item);
   1185	int result;
   1186
   1187	mutex_lock(&opts->lock);
   1188	result = sprintf(page, "%u\n", opts->iso_qlen);
   1189	mutex_unlock(&opts->lock);
   1190
   1191	return result;
   1192}
   1193
   1194static ssize_t f_ss_opts_iso_qlen_store(struct config_item *item,
   1195					   const char *page, size_t len)
   1196{
   1197	struct f_ss_opts *opts = to_f_ss_opts(item);
   1198	int ret;
   1199	u32 num;
   1200
   1201	mutex_lock(&opts->lock);
   1202	if (opts->refcnt) {
   1203		ret = -EBUSY;
   1204		goto end;
   1205	}
   1206
   1207	ret = kstrtou32(page, 0, &num);
   1208	if (ret)
   1209		goto end;
   1210
   1211	opts->iso_qlen = num;
   1212	ret = len;
   1213end:
   1214	mutex_unlock(&opts->lock);
   1215	return ret;
   1216}
   1217
   1218CONFIGFS_ATTR(f_ss_opts_, iso_qlen);
   1219
   1220static struct configfs_attribute *ss_attrs[] = {
   1221	&f_ss_opts_attr_pattern,
   1222	&f_ss_opts_attr_isoc_interval,
   1223	&f_ss_opts_attr_isoc_maxpacket,
   1224	&f_ss_opts_attr_isoc_mult,
   1225	&f_ss_opts_attr_isoc_maxburst,
   1226	&f_ss_opts_attr_bulk_buflen,
   1227	&f_ss_opts_attr_bulk_qlen,
   1228	&f_ss_opts_attr_iso_qlen,
   1229	NULL,
   1230};
   1231
   1232static const struct config_item_type ss_func_type = {
   1233	.ct_item_ops    = &ss_item_ops,
   1234	.ct_attrs	= ss_attrs,
   1235	.ct_owner       = THIS_MODULE,
   1236};
   1237
   1238static void source_sink_free_instance(struct usb_function_instance *fi)
   1239{
   1240	struct f_ss_opts *ss_opts;
   1241
   1242	ss_opts = container_of(fi, struct f_ss_opts, func_inst);
   1243	kfree(ss_opts);
   1244}
   1245
   1246static struct usb_function_instance *source_sink_alloc_inst(void)
   1247{
   1248	struct f_ss_opts *ss_opts;
   1249
   1250	ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL);
   1251	if (!ss_opts)
   1252		return ERR_PTR(-ENOMEM);
   1253	mutex_init(&ss_opts->lock);
   1254	ss_opts->func_inst.free_func_inst = source_sink_free_instance;
   1255	ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
   1256	ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
   1257	ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
   1258	ss_opts->bulk_qlen = GZERO_SS_BULK_QLEN;
   1259	ss_opts->iso_qlen = GZERO_SS_ISO_QLEN;
   1260
   1261	config_group_init_type_name(&ss_opts->func_inst.group, "",
   1262				    &ss_func_type);
   1263
   1264	return &ss_opts->func_inst;
   1265}
   1266DECLARE_USB_FUNCTION(SourceSink, source_sink_alloc_inst,
   1267		source_sink_alloc_func);
   1268
   1269static int __init sslb_modinit(void)
   1270{
   1271	int ret;
   1272
   1273	ret = usb_function_register(&SourceSinkusb_func);
   1274	if (ret)
   1275		return ret;
   1276	ret = lb_modinit();
   1277	if (ret)
   1278		usb_function_unregister(&SourceSinkusb_func);
   1279	return ret;
   1280}
   1281static void __exit sslb_modexit(void)
   1282{
   1283	usb_function_unregister(&SourceSinkusb_func);
   1284	lb_modexit();
   1285}
   1286module_init(sslb_modinit);
   1287module_exit(sslb_modexit);
   1288
   1289MODULE_LICENSE("GPL");