File Index
Files and directories
Sign in
FILE

uvc_configfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/usb/gadget/function/uvc_configfs.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * uvc_configfs.c
   4 *
   5 * Configfs support for the uvc function.
   6 *
   7 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
   8 *		http://www.samsung.com
   9 *
  10 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
  11 */
  12
  13#include "uvc_configfs.h"
  14
  15#include <linux/sort.h>
  16#include <linux/usb/uvc.h>
  17#include <linux/usb/video.h>
  18
  19/* -----------------------------------------------------------------------------
  20 * Global Utility Structures and Macros
  21 */
  22
  23#define UVC_ATTR(prefix, cname, aname) \
  24static struct configfs_attribute prefix##attr_##cname = { \
  25	.ca_name	= __stringify(aname),				\
  26	.ca_mode	= S_IRUGO | S_IWUGO,				\
  27	.ca_owner	= THIS_MODULE,					\
  28	.show		= prefix##cname##_show,				\
  29	.store		= prefix##cname##_store,			\
  30}
  31
  32#define UVC_ATTR_RO(prefix, cname, aname) \
  33static struct configfs_attribute prefix##attr_##cname = { \
  34	.ca_name	= __stringify(aname),				\
  35	.ca_mode	= S_IRUGO,					\
  36	.ca_owner	= THIS_MODULE,					\
  37	.show		= prefix##cname##_show,				\
  38}
  39
  40#define le8_to_cpu(x)	(x)
  41#define cpu_to_le8(x)	(x)
  42
  43static int uvcg_config_compare_u32(const void *l, const void *r)
  44{
  45	u32 li = *(const u32 *)l;
  46	u32 ri = *(const u32 *)r;
  47
  48	return li < ri ? -1 : li == ri ? 0 : 1;
  49}
  50
  51static inline int __uvcg_count_item_entries(char *buf, void *priv, unsigned int size)
  52{
  53	++*((int *)priv);
  54	return 0;
  55}
  56
  57static inline int __uvcg_fill_item_entries(char *buf, void *priv, unsigned int size)
  58{
  59	unsigned int num;
  60	u8 **values;
  61	int ret;
  62
  63	ret = kstrtouint(buf, 0, &num);
  64	if (ret)
  65		return ret;
  66
  67	if (num != (num & GENMASK((size * 8) - 1, 0)))
  68		return -ERANGE;
  69
  70	values = priv;
  71	memcpy(*values, &num, size);
  72	*values += size;
  73
  74	return 0;
  75}
  76
  77static int __uvcg_iter_item_entries(const char *page, size_t len,
  78				    int (*fun)(char *, void *, unsigned int),
  79				    void *priv, unsigned int size)
  80{
  81	/* sign, base 2 representation, newline, terminator */
  82	unsigned int bufsize = 1 + size * 8 + 1 + 1;
  83	const char *pg = page;
  84	int i, ret = 0;
  85	char *buf;
  86
  87	if (!fun)
  88		return -EINVAL;
  89
  90	buf = kzalloc(bufsize, GFP_KERNEL);
  91	if (!buf)
  92		return -ENOMEM;
  93
  94	while (pg - page < len) {
  95		i = 0;
  96		while (i < bufsize && (pg - page < len) &&
  97		       *pg != '\0' && *pg != '\n')
  98			buf[i++] = *pg++;
  99		if (i == bufsize) {
 100			ret = -EINVAL;
 101			goto out_free_buf;
 102		}
 103		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
 104			++pg;
 105		buf[i] = '\0';
 106		ret = fun(buf, priv, size);
 107		if (ret)
 108			goto out_free_buf;
 109	}
 110
 111out_free_buf:
 112	kfree(buf);
 113	return ret;
 114}
 115
 116struct uvcg_config_group_type {
 117	struct config_item_type type;
 118	const char *name;
 119	const struct uvcg_config_group_type **children;
 120	int (*create_children)(struct config_group *group);
 121};
 122
 123static void uvcg_config_item_release(struct config_item *item)
 124{
 125	struct config_group *group = to_config_group(item);
 126
 127	kfree(group);
 128}
 129
 130static struct configfs_item_operations uvcg_config_item_ops = {
 131	.release	= uvcg_config_item_release,
 132};
 133
 134static int uvcg_config_create_group(struct config_group *parent,
 135				    const struct uvcg_config_group_type *type);
 136
 137static int uvcg_config_create_children(struct config_group *group,
 138				const struct uvcg_config_group_type *type)
 139{
 140	const struct uvcg_config_group_type **child;
 141	int ret;
 142
 143	if (type->create_children)
 144		return type->create_children(group);
 145
 146	for (child = type->children; child && *child; ++child) {
 147		ret = uvcg_config_create_group(group, *child);
 148		if (ret < 0)
 149			return ret;
 150	}
 151
 152	return 0;
 153}
 154
 155static int uvcg_config_create_group(struct config_group *parent,
 156				    const struct uvcg_config_group_type *type)
 157{
 158	struct config_group *group;
 159
 160	group = kzalloc(sizeof(*group), GFP_KERNEL);
 161	if (!group)
 162		return -ENOMEM;
 163
 164	config_group_init_type_name(group, type->name, &type->type);
 165	configfs_add_default_group(group, parent);
 166
 167	return uvcg_config_create_children(group, type);
 168}
 169
 170static void uvcg_config_remove_children(struct config_group *group)
 171{
 172	struct config_group *child, *n;
 173
 174	list_for_each_entry_safe(child, n, &group->default_groups, group_entry) {
 175		list_del(&child->group_entry);
 176		uvcg_config_remove_children(child);
 177		config_item_put(&child->cg_item);
 178	}
 179}
 180
 181/* -----------------------------------------------------------------------------
 182 * control/header/<NAME>
 183 * control/header
 184 */
 185
 186#define UVCG_CTRL_HDR_ATTR(cname, aname, bits, limit)			\
 187static ssize_t uvcg_control_header_##cname##_show(			\
 188	struct config_item *item, char *page)				\
 189{									\
 190	struct uvcg_control_header *ch = to_uvcg_control_header(item);	\
 191	struct f_uvc_opts *opts;					\
 192	struct config_item *opts_item;					\
 193	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
 194	int result;							\
 195									\
 196	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 197									\
 198	opts_item = ch->item.ci_parent->ci_parent->ci_parent;		\
 199	opts = to_f_uvc_opts(opts_item);				\
 200									\
 201	mutex_lock(&opts->lock);					\
 202	result = sprintf(page, "%u\n", le##bits##_to_cpu(ch->desc.aname));\
 203	mutex_unlock(&opts->lock);					\
 204									\
 205	mutex_unlock(su_mutex);						\
 206	return result;							\
 207}									\
 208									\
 209static ssize_t								\
 210uvcg_control_header_##cname##_store(struct config_item *item,		\
 211			   const char *page, size_t len)		\
 212{									\
 213	struct uvcg_control_header *ch = to_uvcg_control_header(item);	\
 214	struct f_uvc_opts *opts;					\
 215	struct config_item *opts_item;					\
 216	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
 217	int ret;							\
 218	u##bits num;							\
 219									\
 220	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 221									\
 222	opts_item = ch->item.ci_parent->ci_parent->ci_parent;		\
 223	opts = to_f_uvc_opts(opts_item);				\
 224									\
 225	mutex_lock(&opts->lock);					\
 226	if (ch->linked || opts->refcnt) {				\
 227		ret = -EBUSY;						\
 228		goto end;						\
 229	}								\
 230									\
 231	ret = kstrtou##bits(page, 0, &num);				\
 232	if (ret)							\
 233		goto end;						\
 234									\
 235	if (num > limit) {						\
 236		ret = -EINVAL;						\
 237		goto end;						\
 238	}								\
 239	ch->desc.aname = cpu_to_le##bits(num);				\
 240	ret = len;							\
 241end:									\
 242	mutex_unlock(&opts->lock);					\
 243	mutex_unlock(su_mutex);						\
 244	return ret;							\
 245}									\
 246									\
 247UVC_ATTR(uvcg_control_header_, cname, aname)
 248
 249UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, 16, 0xffff);
 250
 251UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, 32, 0x7fffffff);
 252
 253#undef UVCG_CTRL_HDR_ATTR
 254
 255static struct configfs_attribute *uvcg_control_header_attrs[] = {
 256	&uvcg_control_header_attr_bcd_uvc,
 257	&uvcg_control_header_attr_dw_clock_frequency,
 258	NULL,
 259};
 260
 261static const struct config_item_type uvcg_control_header_type = {
 262	.ct_item_ops	= &uvcg_config_item_ops,
 263	.ct_attrs	= uvcg_control_header_attrs,
 264	.ct_owner	= THIS_MODULE,
 265};
 266
 267static struct config_item *uvcg_control_header_make(struct config_group *group,
 268						    const char *name)
 269{
 270	struct uvcg_control_header *h;
 271
 272	h = kzalloc(sizeof(*h), GFP_KERNEL);
 273	if (!h)
 274		return ERR_PTR(-ENOMEM);
 275
 276	h->desc.bLength			= UVC_DT_HEADER_SIZE(1);
 277	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
 278	h->desc.bDescriptorSubType	= UVC_VC_HEADER;
 279	h->desc.bcdUVC			= cpu_to_le16(0x0110);
 280	h->desc.dwClockFrequency	= cpu_to_le32(48000000);
 281
 282	config_item_init_type_name(&h->item, name, &uvcg_control_header_type);
 283
 284	return &h->item;
 285}
 286
 287static struct configfs_group_operations uvcg_control_header_grp_ops = {
 288	.make_item		= uvcg_control_header_make,
 289};
 290
 291static const struct uvcg_config_group_type uvcg_control_header_grp_type = {
 292	.type = {
 293		.ct_item_ops	= &uvcg_config_item_ops,
 294		.ct_group_ops	= &uvcg_control_header_grp_ops,
 295		.ct_owner	= THIS_MODULE,
 296	},
 297	.name = "header",
 298};
 299
 300/* -----------------------------------------------------------------------------
 301 * control/processing/default
 302 */
 303
 304#define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, bits)		\
 305static ssize_t uvcg_default_processing_##cname##_show(			\
 306	struct config_item *item, char *page)				\
 307{									\
 308	struct config_group *group = to_config_group(item);		\
 309	struct f_uvc_opts *opts;					\
 310	struct config_item *opts_item;					\
 311	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
 312	struct uvc_processing_unit_descriptor *pd;			\
 313	int result;							\
 314									\
 315	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 316									\
 317	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
 318	opts = to_f_uvc_opts(opts_item);				\
 319	pd = &opts->uvc_processing;					\
 320									\
 321	mutex_lock(&opts->lock);					\
 322	result = sprintf(page, "%u\n", le##bits##_to_cpu(pd->aname));	\
 323	mutex_unlock(&opts->lock);					\
 324									\
 325	mutex_unlock(su_mutex);						\
 326	return result;							\
 327}									\
 328									\
 329UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
 330
 331UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, 8);
 332UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, 8);
 333UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, 16);
 334UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, 8);
 335
 336#undef UVCG_DEFAULT_PROCESSING_ATTR
 337
 338static ssize_t uvcg_default_processing_bm_controls_store(
 339	struct config_item *item, const char *page, size_t len)
 340{
 341	struct config_group *group = to_config_group(item);
 342	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 343	struct uvc_processing_unit_descriptor *pd;
 344	struct config_item *opts_item;
 345	struct f_uvc_opts *opts;
 346	u8 *bm_controls, *tmp;
 347	unsigned int i;
 348	int ret, n = 0;
 349
 350	mutex_lock(su_mutex);
 351
 352	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
 353	opts = to_f_uvc_opts(opts_item);
 354	pd = &opts->uvc_processing;
 355
 356	mutex_lock(&opts->lock);
 357	if (opts->refcnt) {
 358		ret = -EBUSY;
 359		goto unlock;
 360	}
 361
 362	ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n,
 363				       sizeof(u8));
 364	if (ret)
 365		goto unlock;
 366
 367	if (n > pd->bControlSize) {
 368		ret = -EINVAL;
 369		goto unlock;
 370	}
 371
 372	tmp = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL);
 373	if (!bm_controls) {
 374		ret = -ENOMEM;
 375		goto unlock;
 376	}
 377
 378	ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp,
 379				       sizeof(u8));
 380	if (ret)
 381		goto free_mem;
 382
 383	for (i = 0; i < n; i++)
 384		pd->bmControls[i] = bm_controls[i];
 385
 386	ret = len;
 387
 388free_mem:
 389	kfree(bm_controls);
 390unlock:
 391	mutex_unlock(&opts->lock);
 392	mutex_unlock(su_mutex);
 393	return ret;
 394}
 395
 396static ssize_t uvcg_default_processing_bm_controls_show(
 397	struct config_item *item, char *page)
 398{
 399	struct config_group *group = to_config_group(item);
 400	struct f_uvc_opts *opts;
 401	struct config_item *opts_item;
 402	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 403	struct uvc_processing_unit_descriptor *pd;
 404	int result, i;
 405	char *pg = page;
 406
 407	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 408
 409	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
 410	opts = to_f_uvc_opts(opts_item);
 411	pd = &opts->uvc_processing;
 412
 413	mutex_lock(&opts->lock);
 414	for (result = 0, i = 0; i < pd->bControlSize; ++i) {
 415		result += sprintf(pg, "%u\n", pd->bmControls[i]);
 416		pg = page + result;
 417	}
 418	mutex_unlock(&opts->lock);
 419
 420	mutex_unlock(su_mutex);
 421
 422	return result;
 423}
 424
 425UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls);
 426
 427static struct configfs_attribute *uvcg_default_processing_attrs[] = {
 428	&uvcg_default_processing_attr_b_unit_id,
 429	&uvcg_default_processing_attr_b_source_id,
 430	&uvcg_default_processing_attr_w_max_multiplier,
 431	&uvcg_default_processing_attr_bm_controls,
 432	&uvcg_default_processing_attr_i_processing,
 433	NULL,
 434};
 435
 436static const struct uvcg_config_group_type uvcg_default_processing_type = {
 437	.type = {
 438		.ct_item_ops	= &uvcg_config_item_ops,
 439		.ct_attrs	= uvcg_default_processing_attrs,
 440		.ct_owner	= THIS_MODULE,
 441	},
 442	.name = "default",
 443};
 444
 445/* -----------------------------------------------------------------------------
 446 * control/processing
 447 */
 448
 449static const struct uvcg_config_group_type uvcg_processing_grp_type = {
 450	.type = {
 451		.ct_item_ops	= &uvcg_config_item_ops,
 452		.ct_owner	= THIS_MODULE,
 453	},
 454	.name = "processing",
 455	.children = (const struct uvcg_config_group_type*[]) {
 456		&uvcg_default_processing_type,
 457		NULL,
 458	},
 459};
 460
 461/* -----------------------------------------------------------------------------
 462 * control/terminal/camera/default
 463 */
 464
 465#define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, bits)			\
 466static ssize_t uvcg_default_camera_##cname##_show(			\
 467	struct config_item *item, char *page)				\
 468{									\
 469	struct config_group *group = to_config_group(item);		\
 470	struct f_uvc_opts *opts;					\
 471	struct config_item *opts_item;					\
 472	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
 473	struct uvc_camera_terminal_descriptor *cd;			\
 474	int result;							\
 475									\
 476	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 477									\
 478	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent->	\
 479			ci_parent;					\
 480	opts = to_f_uvc_opts(opts_item);				\
 481	cd = &opts->uvc_camera_terminal;				\
 482									\
 483	mutex_lock(&opts->lock);					\
 484	result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname));	\
 485	mutex_unlock(&opts->lock);					\
 486									\
 487	mutex_unlock(su_mutex);						\
 488									\
 489	return result;							\
 490}									\
 491									\
 492UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
 493
 494UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, 8);
 495UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, 16);
 496UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, 8);
 497UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, 8);
 498UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin,
 499			 16);
 500UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax,
 501			 16);
 502UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength,
 503			 16);
 504
 505#undef UVCG_DEFAULT_CAMERA_ATTR
 506
 507static ssize_t uvcg_default_camera_bm_controls_store(
 508	struct config_item *item, const char *page, size_t len)
 509{
 510	struct config_group *group = to_config_group(item);
 511	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 512	struct uvc_camera_terminal_descriptor *cd;
 513	struct config_item *opts_item;
 514	struct f_uvc_opts *opts;
 515	u8 *bm_controls, *tmp;
 516	unsigned int i;
 517	int ret, n = 0;
 518
 519	mutex_lock(su_mutex);
 520
 521	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent->
 522			ci_parent;
 523	opts = to_f_uvc_opts(opts_item);
 524	cd = &opts->uvc_camera_terminal;
 525
 526	mutex_lock(&opts->lock);
 527	if (opts->refcnt) {
 528		ret = -EBUSY;
 529		goto unlock;
 530	}
 531
 532	ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n,
 533				       sizeof(u8));
 534	if (ret)
 535		goto unlock;
 536
 537	if (n > cd->bControlSize) {
 538		ret = -EINVAL;
 539		goto unlock;
 540	}
 541
 542	tmp = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL);
 543	if (!bm_controls) {
 544		ret = -ENOMEM;
 545		goto unlock;
 546	}
 547
 548	ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp,
 549				       sizeof(u8));
 550	if (ret)
 551		goto free_mem;
 552
 553	for (i = 0; i < n; i++)
 554		cd->bmControls[i] = bm_controls[i];
 555
 556	ret = len;
 557
 558free_mem:
 559	kfree(bm_controls);
 560unlock:
 561	mutex_unlock(&opts->lock);
 562	mutex_unlock(su_mutex);
 563	return ret;
 564}
 565
 566static ssize_t uvcg_default_camera_bm_controls_show(
 567	struct config_item *item, char *page)
 568{
 569	struct config_group *group = to_config_group(item);
 570	struct f_uvc_opts *opts;
 571	struct config_item *opts_item;
 572	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 573	struct uvc_camera_terminal_descriptor *cd;
 574	int result, i;
 575	char *pg = page;
 576
 577	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 578
 579	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent->
 580			ci_parent;
 581	opts = to_f_uvc_opts(opts_item);
 582	cd = &opts->uvc_camera_terminal;
 583
 584	mutex_lock(&opts->lock);
 585	for (result = 0, i = 0; i < cd->bControlSize; ++i) {
 586		result += sprintf(pg, "%u\n", cd->bmControls[i]);
 587		pg = page + result;
 588	}
 589	mutex_unlock(&opts->lock);
 590
 591	mutex_unlock(su_mutex);
 592	return result;
 593}
 594
 595UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls);
 596
 597static struct configfs_attribute *uvcg_default_camera_attrs[] = {
 598	&uvcg_default_camera_attr_b_terminal_id,
 599	&uvcg_default_camera_attr_w_terminal_type,
 600	&uvcg_default_camera_attr_b_assoc_terminal,
 601	&uvcg_default_camera_attr_i_terminal,
 602	&uvcg_default_camera_attr_w_objective_focal_length_min,
 603	&uvcg_default_camera_attr_w_objective_focal_length_max,
 604	&uvcg_default_camera_attr_w_ocular_focal_length,
 605	&uvcg_default_camera_attr_bm_controls,
 606	NULL,
 607};
 608
 609static const struct uvcg_config_group_type uvcg_default_camera_type = {
 610	.type = {
 611		.ct_item_ops	= &uvcg_config_item_ops,
 612		.ct_attrs	= uvcg_default_camera_attrs,
 613		.ct_owner	= THIS_MODULE,
 614	},
 615	.name = "default",
 616};
 617
 618/* -----------------------------------------------------------------------------
 619 * control/terminal/camera
 620 */
 621
 622static const struct uvcg_config_group_type uvcg_camera_grp_type = {
 623	.type = {
 624		.ct_item_ops	= &uvcg_config_item_ops,
 625		.ct_owner	= THIS_MODULE,
 626	},
 627	.name = "camera",
 628	.children = (const struct uvcg_config_group_type*[]) {
 629		&uvcg_default_camera_type,
 630		NULL,
 631	},
 632};
 633
 634/* -----------------------------------------------------------------------------
 635 * control/terminal/output/default
 636 */
 637
 638#define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, bits)			\
 639static ssize_t uvcg_default_output_##cname##_show(			\
 640	struct config_item *item, char *page)				\
 641{									\
 642	struct config_group *group = to_config_group(item);		\
 643	struct f_uvc_opts *opts;					\
 644	struct config_item *opts_item;					\
 645	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
 646	struct uvc_output_terminal_descriptor *cd;			\
 647	int result;							\
 648									\
 649	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 650									\
 651	opts_item = group->cg_item.ci_parent->ci_parent->		\
 652			ci_parent->ci_parent;				\
 653	opts = to_f_uvc_opts(opts_item);				\
 654	cd = &opts->uvc_output_terminal;				\
 655									\
 656	mutex_lock(&opts->lock);					\
 657	result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname));	\
 658	mutex_unlock(&opts->lock);					\
 659									\
 660	mutex_unlock(su_mutex);						\
 661									\
 662	return result;							\
 663}									\
 664									\
 665UVC_ATTR_RO(uvcg_default_output_, cname, aname)
 666
 667UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8);
 668UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16);
 669UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8);
 670UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8);
 671
 672#undef UVCG_DEFAULT_OUTPUT_ATTR
 673
 674static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item,
 675						    char *page)
 676{
 677	struct config_group *group = to_config_group(item);
 678	struct f_uvc_opts *opts;
 679	struct config_item *opts_item;
 680	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 681	struct uvc_output_terminal_descriptor *cd;
 682	int result;
 683
 684	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 685
 686	opts_item = group->cg_item.ci_parent->ci_parent->
 687			ci_parent->ci_parent;
 688	opts = to_f_uvc_opts(opts_item);
 689	cd = &opts->uvc_output_terminal;
 690
 691	mutex_lock(&opts->lock);
 692	result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID));
 693	mutex_unlock(&opts->lock);
 694
 695	mutex_unlock(su_mutex);
 696
 697	return result;
 698}
 699
 700static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,
 701						     const char *page, size_t len)
 702{
 703	struct config_group *group = to_config_group(item);
 704	struct f_uvc_opts *opts;
 705	struct config_item *opts_item;
 706	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 707	struct uvc_output_terminal_descriptor *cd;
 708	int result;
 709	u8 num;
 710
 711	result = kstrtou8(page, 0, &num);
 712	if (result)
 713		return result;
 714
 715	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 716
 717	opts_item = group->cg_item.ci_parent->ci_parent->
 718			ci_parent->ci_parent;
 719	opts = to_f_uvc_opts(opts_item);
 720	cd = &opts->uvc_output_terminal;
 721
 722	mutex_lock(&opts->lock);
 723	cd->bSourceID = num;
 724	mutex_unlock(&opts->lock);
 725
 726	mutex_unlock(su_mutex);
 727
 728	return len;
 729}
 730UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID);
 731
 732static struct configfs_attribute *uvcg_default_output_attrs[] = {
 733	&uvcg_default_output_attr_b_terminal_id,
 734	&uvcg_default_output_attr_w_terminal_type,
 735	&uvcg_default_output_attr_b_assoc_terminal,
 736	&uvcg_default_output_attr_b_source_id,
 737	&uvcg_default_output_attr_i_terminal,
 738	NULL,
 739};
 740
 741static const struct uvcg_config_group_type uvcg_default_output_type = {
 742	.type = {
 743		.ct_item_ops	= &uvcg_config_item_ops,
 744		.ct_attrs	= uvcg_default_output_attrs,
 745		.ct_owner	= THIS_MODULE,
 746	},
 747	.name = "default",
 748};
 749
 750/* -----------------------------------------------------------------------------
 751 * control/terminal/output
 752 */
 753
 754static const struct uvcg_config_group_type uvcg_output_grp_type = {
 755	.type = {
 756		.ct_item_ops	= &uvcg_config_item_ops,
 757		.ct_owner	= THIS_MODULE,
 758	},
 759	.name = "output",
 760	.children = (const struct uvcg_config_group_type*[]) {
 761		&uvcg_default_output_type,
 762		NULL,
 763	},
 764};
 765
 766/* -----------------------------------------------------------------------------
 767 * control/terminal
 768 */
 769
 770static const struct uvcg_config_group_type uvcg_terminal_grp_type = {
 771	.type = {
 772		.ct_item_ops	= &uvcg_config_item_ops,
 773		.ct_owner	= THIS_MODULE,
 774	},
 775	.name = "terminal",
 776	.children = (const struct uvcg_config_group_type*[]) {
 777		&uvcg_camera_grp_type,
 778		&uvcg_output_grp_type,
 779		NULL,
 780	},
 781};
 782
 783/* -----------------------------------------------------------------------------
 784 * control/extensions
 785 */
 786
 787#define UVCG_EXTENSION_ATTR(cname, aname, ro...)			\
 788static ssize_t uvcg_extension_##cname##_show(struct config_item *item,	\
 789					     char *page)		\
 790{									\
 791	struct config_group *group = to_config_group(item->ci_parent);	\
 792	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
 793	struct uvcg_extension *xu = to_uvcg_extension(item);		\
 794	struct config_item *opts_item;					\
 795	struct f_uvc_opts *opts;					\
 796	int ret;							\
 797									\
 798	mutex_lock(su_mutex);						\
 799									\
 800	opts_item = item->ci_parent->ci_parent->ci_parent;		\
 801	opts = to_f_uvc_opts(opts_item);				\
 802									\
 803	mutex_lock(&opts->lock);					\
 804	ret = sprintf(page, "%u\n", xu->desc.aname);			\
 805	mutex_unlock(&opts->lock);					\
 806									\
 807	mutex_unlock(su_mutex);						\
 808									\
 809	return ret;							\
 810}									\
 811UVC_ATTR##ro(uvcg_extension_, cname, aname)
 812
 813UVCG_EXTENSION_ATTR(b_length, bLength, _RO);
 814UVCG_EXTENSION_ATTR(b_unit_id, bUnitID, _RO);
 815UVCG_EXTENSION_ATTR(i_extension, iExtension, _RO);
 816
 817static ssize_t uvcg_extension_b_num_controls_store(struct config_item *item,
 818						   const char *page, size_t len)
 819{
 820	struct config_group *group = to_config_group(item->ci_parent);
 821	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 822	struct uvcg_extension *xu = to_uvcg_extension(item);
 823	struct config_item *opts_item;
 824	struct f_uvc_opts *opts;
 825	int ret;
 826	u8 num;
 827
 828	ret = kstrtou8(page, 0, &num);
 829	if (ret)
 830		return ret;
 831
 832	mutex_lock(su_mutex);
 833
 834	opts_item = item->ci_parent->ci_parent->ci_parent;
 835	opts = to_f_uvc_opts(opts_item);
 836
 837	mutex_lock(&opts->lock);
 838	xu->desc.bNumControls = num;
 839	mutex_unlock(&opts->lock);
 840
 841	mutex_unlock(su_mutex);
 842
 843	return len;
 844}
 845UVCG_EXTENSION_ATTR(b_num_controls, bNumControls);
 846
 847/*
 848 * In addition to storing bNrInPins, this function needs to realloc the
 849 * memory for the baSourceID array and additionally expand bLength.
 850 */
 851static ssize_t uvcg_extension_b_nr_in_pins_store(struct config_item *item,
 852						 const char *page, size_t len)
 853{
 854	struct config_group *group = to_config_group(item->ci_parent);
 855	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 856	struct uvcg_extension *xu = to_uvcg_extension(item);
 857	struct config_item *opts_item;
 858	struct f_uvc_opts *opts;
 859	void *tmp_buf;
 860	int ret;
 861	u8 num;
 862
 863	ret = kstrtou8(page, 0, &num);
 864	if (ret)
 865		return ret;
 866
 867	mutex_lock(su_mutex);
 868
 869	opts_item = item->ci_parent->ci_parent->ci_parent;
 870	opts = to_f_uvc_opts(opts_item);
 871
 872	mutex_lock(&opts->lock);
 873
 874	if (num == xu->desc.bNrInPins) {
 875		ret = len;
 876		goto unlock;
 877	}
 878
 879	tmp_buf = krealloc_array(xu->desc.baSourceID, num, sizeof(u8),
 880				 GFP_KERNEL | __GFP_ZERO);
 881	if (!tmp_buf) {
 882		ret = -ENOMEM;
 883		goto unlock;
 884	}
 885
 886	xu->desc.baSourceID = tmp_buf;
 887	xu->desc.bNrInPins = num;
 888	xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins,
 889						      xu->desc.bControlSize);
 890
 891	ret = len;
 892
 893unlock:
 894	mutex_unlock(&opts->lock);
 895	mutex_unlock(su_mutex);
 896	return ret;
 897}
 898UVCG_EXTENSION_ATTR(b_nr_in_pins, bNrInPins);
 899
 900/*
 901 * In addition to storing bControlSize, this function needs to realloc the
 902 * memory for the bmControls array and additionally expand bLength.
 903 */
 904static ssize_t uvcg_extension_b_control_size_store(struct config_item *item,
 905						   const char *page, size_t len)
 906{
 907	struct config_group *group = to_config_group(item->ci_parent);
 908	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 909	struct uvcg_extension *xu = to_uvcg_extension(item);
 910	struct config_item *opts_item;
 911	struct f_uvc_opts *opts;
 912	void *tmp_buf;
 913	int ret;
 914	u8 num;
 915
 916	ret = kstrtou8(page, 0, &num);
 917	if (ret)
 918		return ret;
 919
 920	mutex_lock(su_mutex);
 921
 922	opts_item = item->ci_parent->ci_parent->ci_parent;
 923	opts = to_f_uvc_opts(opts_item);
 924
 925	mutex_lock(&opts->lock);
 926
 927	if (num == xu->desc.bControlSize) {
 928		ret = len;
 929		goto unlock;
 930	}
 931
 932	tmp_buf = krealloc_array(xu->desc.bmControls, num, sizeof(u8),
 933				 GFP_KERNEL | __GFP_ZERO);
 934	if (!tmp_buf) {
 935		ret = -ENOMEM;
 936		goto unlock;
 937	}
 938
 939	xu->desc.bmControls = tmp_buf;
 940	xu->desc.bControlSize = num;
 941	xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins,
 942						      xu->desc.bControlSize);
 943
 944	ret = len;
 945
 946unlock:
 947	mutex_unlock(&opts->lock);
 948	mutex_unlock(su_mutex);
 949	return ret;
 950}
 951
 952UVCG_EXTENSION_ATTR(b_control_size, bControlSize);
 953
 954static ssize_t uvcg_extension_guid_extension_code_show(struct config_item *item,
 955						       char *page)
 956{
 957	struct config_group *group = to_config_group(item->ci_parent);
 958	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 959	struct uvcg_extension *xu = to_uvcg_extension(item);
 960	struct config_item *opts_item;
 961	struct f_uvc_opts *opts;
 962
 963	mutex_lock(su_mutex);
 964
 965	opts_item = item->ci_parent->ci_parent->ci_parent;
 966	opts = to_f_uvc_opts(opts_item);
 967
 968	mutex_lock(&opts->lock);
 969	memcpy(page, xu->desc.guidExtensionCode, sizeof(xu->desc.guidExtensionCode));
 970	mutex_unlock(&opts->lock);
 971
 972	mutex_unlock(su_mutex);
 973
 974	return sizeof(xu->desc.guidExtensionCode);
 975}
 976
 977static ssize_t uvcg_extension_guid_extension_code_store(struct config_item *item,
 978							const char *page, size_t len)
 979{
 980	struct config_group *group = to_config_group(item->ci_parent);
 981	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
 982	struct uvcg_extension *xu = to_uvcg_extension(item);
 983	struct config_item *opts_item;
 984	struct f_uvc_opts *opts;
 985	int ret;
 986
 987	mutex_lock(su_mutex);
 988
 989	opts_item = item->ci_parent->ci_parent->ci_parent;
 990	opts = to_f_uvc_opts(opts_item);
 991
 992	mutex_lock(&opts->lock);
 993	memcpy(xu->desc.guidExtensionCode, page,
 994	       min(sizeof(xu->desc.guidExtensionCode), len));
 995	mutex_unlock(&opts->lock);
 996
 997	mutex_unlock(su_mutex);
 998
 999	ret = sizeof(xu->desc.guidExtensionCode);
1000
1001	return ret;
1002}
1003
1004UVC_ATTR(uvcg_extension_, guid_extension_code, guidExtensionCode);
1005
1006static ssize_t uvcg_extension_ba_source_id_show(struct config_item *item,
1007						char *page)
1008{
1009	struct config_group *group = to_config_group(item->ci_parent);
1010	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1011	struct uvcg_extension *xu = to_uvcg_extension(item);
1012	struct config_item *opts_item;
1013	struct f_uvc_opts *opts;
1014	char *pg = page;
1015	int ret, i;
1016
1017	mutex_lock(su_mutex);
1018
1019	opts_item = item->ci_parent->ci_parent->ci_parent;
1020	opts = to_f_uvc_opts(opts_item);
1021
1022	mutex_lock(&opts->lock);
1023	for (ret = 0, i = 0; i < xu->desc.bNrInPins; ++i) {
1024		ret += sprintf(pg, "%u\n", xu->desc.baSourceID[i]);
1025		pg = page + ret;
1026	}
1027	mutex_unlock(&opts->lock);
1028
1029	mutex_unlock(su_mutex);
1030
1031	return ret;
1032}
1033
1034static ssize_t uvcg_extension_ba_source_id_store(struct config_item *item,
1035						 const char *page, size_t len)
1036{
1037	struct config_group *group = to_config_group(item->ci_parent);
1038	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1039	struct uvcg_extension *xu = to_uvcg_extension(item);
1040	struct config_item *opts_item;
1041	struct f_uvc_opts *opts;
1042	u8 *source_ids, *iter;
1043	int ret, n = 0;
1044
1045	mutex_lock(su_mutex);
1046
1047	opts_item = item->ci_parent->ci_parent->ci_parent;
1048	opts = to_f_uvc_opts(opts_item);
1049
1050	mutex_lock(&opts->lock);
1051
1052	ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n,
1053				       sizeof(u8));
1054	if (ret)
1055		goto unlock;
1056
1057	iter = source_ids = kcalloc(n, sizeof(u8), GFP_KERNEL);
1058	if (!source_ids) {
1059		ret = -ENOMEM;
1060		goto unlock;
1061	}
1062
1063	ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &iter,
1064				       sizeof(u8));
1065	if (ret) {
1066		kfree(source_ids);
1067		goto unlock;
1068	}
1069
1070	kfree(xu->desc.baSourceID);
1071	xu->desc.baSourceID = source_ids;
1072	xu->desc.bNrInPins = n;
1073	xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins,
1074						      xu->desc.bControlSize);
1075
1076	ret = len;
1077
1078unlock:
1079	mutex_unlock(&opts->lock);
1080	mutex_unlock(su_mutex);
1081	return ret;
1082}
1083UVC_ATTR(uvcg_extension_, ba_source_id, baSourceID);
1084
1085static ssize_t uvcg_extension_bm_controls_show(struct config_item *item,
1086					       char *page)
1087{
1088	struct config_group *group = to_config_group(item->ci_parent);
1089	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1090	struct uvcg_extension *xu = to_uvcg_extension(item);
1091	struct config_item *opts_item;
1092	struct f_uvc_opts *opts;
1093	char *pg = page;
1094	int ret, i;
1095
1096	mutex_lock(su_mutex);
1097
1098	opts_item = item->ci_parent->ci_parent->ci_parent;
1099	opts = to_f_uvc_opts(opts_item);
1100
1101	mutex_lock(&opts->lock);
1102	for (ret = 0, i = 0; i < xu->desc.bControlSize; ++i) {
1103		ret += sprintf(pg, "0x%02x\n", xu->desc.bmControls[i]);
1104		pg = page + ret;
1105	}
1106	mutex_unlock(&opts->lock);
1107
1108	mutex_unlock(su_mutex);
1109
1110	return ret;
1111}
1112
1113static ssize_t uvcg_extension_bm_controls_store(struct config_item *item,
1114						const char *page, size_t len)
1115{
1116	struct config_group *group = to_config_group(item->ci_parent);
1117	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1118	struct uvcg_extension *xu = to_uvcg_extension(item);
1119	struct config_item *opts_item;
1120	struct f_uvc_opts *opts;
1121	u8 *bm_controls, *iter;
1122	int ret, n = 0;
1123
1124	mutex_lock(su_mutex);
1125
1126	opts_item = item->ci_parent->ci_parent->ci_parent;
1127	opts = to_f_uvc_opts(opts_item);
1128
1129	mutex_lock(&opts->lock);
1130
1131	ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n,
1132				       sizeof(u8));
1133	if (ret)
1134		goto unlock;
1135
1136	iter = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL);
1137	if (!bm_controls) {
1138		ret = -ENOMEM;
1139		goto unlock;
1140	}
1141
1142	ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &iter,
1143				       sizeof(u8));
1144	if (ret) {
1145		kfree(bm_controls);
1146		goto unlock;
1147	}
1148
1149	kfree(xu->desc.bmControls);
1150	xu->desc.bmControls = bm_controls;
1151	xu->desc.bControlSize = n;
1152	xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins,
1153						      xu->desc.bControlSize);
1154
1155	ret = len;
1156
1157unlock:
1158	mutex_unlock(&opts->lock);
1159	mutex_unlock(su_mutex);
1160	return ret;
1161}
1162
1163UVC_ATTR(uvcg_extension_, bm_controls, bmControls);
1164
1165static struct configfs_attribute *uvcg_extension_attrs[] = {
1166	&uvcg_extension_attr_b_length,
1167	&uvcg_extension_attr_b_unit_id,
1168	&uvcg_extension_attr_b_num_controls,
1169	&uvcg_extension_attr_b_nr_in_pins,
1170	&uvcg_extension_attr_b_control_size,
1171	&uvcg_extension_attr_guid_extension_code,
1172	&uvcg_extension_attr_ba_source_id,
1173	&uvcg_extension_attr_bm_controls,
1174	&uvcg_extension_attr_i_extension,
1175	NULL,
1176};
1177
1178static void uvcg_extension_release(struct config_item *item)
1179{
1180	struct uvcg_extension *xu = container_of(item, struct uvcg_extension, item);
1181
1182	kfree(xu);
1183}
1184
1185static int uvcg_extension_allow_link(struct config_item *src, struct config_item *tgt)
1186{
1187	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1188	struct uvcg_extension *xu = to_uvcg_extension(src);
1189	struct config_item *gadget_item;
1190	struct gadget_string *string;
1191	struct config_item *strings;
1192	int ret = 0;
1193
1194	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1195
1196	/* Validate that the target of the link is an entry in strings/<langid> */
1197	gadget_item = src->ci_parent->ci_parent->ci_parent->ci_parent->ci_parent;
1198	strings = config_group_find_item(to_config_group(gadget_item), "strings");
1199	if (!strings || tgt->ci_parent->ci_parent != strings) {
1200		ret = -EINVAL;
1201		goto put_strings;
1202	}
1203
1204	string = to_gadget_string(tgt);
1205	xu->string_descriptor_index = string->usb_string.id;
1206
1207put_strings:
1208	config_item_put(strings);
1209	mutex_unlock(su_mutex);
1210
1211	return ret;
1212}
1213
1214static void uvcg_extension_drop_link(struct config_item *src, struct config_item *tgt)
1215{
1216	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1217	struct uvcg_extension *xu = to_uvcg_extension(src);
1218	struct config_item *opts_item;
1219	struct f_uvc_opts *opts;
1220
1221	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1222
1223	opts_item = src->ci_parent->ci_parent->ci_parent;
1224	opts = to_f_uvc_opts(opts_item);
1225
1226	mutex_lock(&opts->lock);
1227
1228	xu->string_descriptor_index = 0;
1229
1230	mutex_unlock(&opts->lock);
1231
1232	mutex_unlock(su_mutex);
1233}
1234
1235static struct configfs_item_operations uvcg_extension_item_ops = {
1236	.release	= uvcg_extension_release,
1237	.allow_link	= uvcg_extension_allow_link,
1238	.drop_link	= uvcg_extension_drop_link,
1239};
1240
1241static const struct config_item_type uvcg_extension_type = {
1242	.ct_item_ops	= &uvcg_extension_item_ops,
1243	.ct_attrs	= uvcg_extension_attrs,
1244	.ct_owner	= THIS_MODULE,
1245};
1246
1247static void uvcg_extension_drop(struct config_group *group, struct config_item *item)
1248{
1249	struct uvcg_extension *xu = container_of(item, struct uvcg_extension, item);
1250	struct config_item *opts_item;
1251	struct f_uvc_opts *opts;
1252
1253	opts_item = group->cg_item.ci_parent->ci_parent;
1254	opts = to_f_uvc_opts(opts_item);
1255
1256	mutex_lock(&opts->lock);
1257
1258	config_item_put(item);
1259	list_del(&xu->list);
1260	kfree(xu->desc.baSourceID);
1261	kfree(xu->desc.bmControls);
1262
1263	mutex_unlock(&opts->lock);
1264}
1265
1266static struct config_item *uvcg_extension_make(struct config_group *group, const char *name)
1267{
1268	struct config_item *opts_item;
1269	struct uvcg_extension *xu;
1270	struct f_uvc_opts *opts;
1271
1272	opts_item = group->cg_item.ci_parent->ci_parent;
1273	opts = to_f_uvc_opts(opts_item);
1274
1275	xu = kzalloc(sizeof(*xu), GFP_KERNEL);
1276	if (!xu)
1277		return ERR_PTR(-ENOMEM);
1278
1279	xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(0, 0);
1280	xu->desc.bDescriptorType = USB_DT_CS_INTERFACE;
1281	xu->desc.bDescriptorSubType = UVC_VC_EXTENSION_UNIT;
1282	xu->desc.bNumControls = 0;
1283	xu->desc.bNrInPins = 0;
1284	xu->desc.baSourceID = NULL;
1285	xu->desc.bControlSize = 0;
1286	xu->desc.bmControls = NULL;
1287
1288	mutex_lock(&opts->lock);
1289
1290	xu->desc.bUnitID = ++opts->last_unit_id;
1291
1292	config_item_init_type_name(&xu->item, name, &uvcg_extension_type);
1293	list_add_tail(&xu->list, &opts->extension_units);
1294
1295	mutex_unlock(&opts->lock);
1296
1297	return &xu->item;
1298}
1299
1300static struct configfs_group_operations uvcg_extensions_grp_ops = {
1301	.make_item	= uvcg_extension_make,
1302	.drop_item	= uvcg_extension_drop,
1303};
1304
1305static const struct uvcg_config_group_type uvcg_extensions_grp_type = {
1306	.type = {
1307		.ct_item_ops	= &uvcg_config_item_ops,
1308		.ct_group_ops	= &uvcg_extensions_grp_ops,
1309		.ct_owner	= THIS_MODULE,
1310	},
1311	.name = "extensions",
1312};
1313
1314/* -----------------------------------------------------------------------------
1315 * control/class/{fs|ss}
1316 */
1317
1318struct uvcg_control_class_group {
1319	struct config_group group;
1320	const char *name;
1321};
1322
1323static inline struct uvc_descriptor_header
1324**uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
1325{
1326	struct uvcg_control_class_group *group =
1327		container_of(i, struct uvcg_control_class_group,
1328			     group.cg_item);
1329
1330	if (!strcmp(group->name, "fs"))
1331		return o->uvc_fs_control_cls;
1332
1333	if (!strcmp(group->name, "ss"))
1334		return o->uvc_ss_control_cls;
1335
1336	return NULL;
1337}
1338
1339static int uvcg_control_class_allow_link(struct config_item *src,
1340					 struct config_item *target)
1341{
1342	struct config_item *control, *header;
1343	struct f_uvc_opts *opts;
1344	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1345	struct uvc_descriptor_header **class_array;
1346	struct uvcg_control_header *target_hdr;
1347	int ret = -EINVAL;
1348
1349	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1350
1351	control = src->ci_parent->ci_parent;
1352	header = config_group_find_item(to_config_group(control), "header");
1353	if (!header || target->ci_parent != header)
1354		goto out;
1355
1356	opts = to_f_uvc_opts(control->ci_parent);
1357
1358	mutex_lock(&opts->lock);
1359
1360	class_array = uvcg_get_ctl_class_arr(src, opts);
1361	if (!class_array)
1362		goto unlock;
1363	if (opts->refcnt || class_array[0]) {
1364		ret = -EBUSY;
1365		goto unlock;
1366	}
1367
1368	target_hdr = to_uvcg_control_header(target);
1369	++target_hdr->linked;
1370	class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc;
1371	ret = 0;
1372
1373unlock:
1374	mutex_unlock(&opts->lock);
1375out:
1376	config_item_put(header);
1377	mutex_unlock(su_mutex);
1378	return ret;
1379}
1380
1381static void uvcg_control_class_drop_link(struct config_item *src,
1382					struct config_item *target)
1383{
1384	struct config_item *control, *header;
1385	struct f_uvc_opts *opts;
1386	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1387	struct uvc_descriptor_header **class_array;
1388	struct uvcg_control_header *target_hdr;
1389
1390	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1391
1392	control = src->ci_parent->ci_parent;
1393	header = config_group_find_item(to_config_group(control), "header");
1394	if (!header || target->ci_parent != header)
1395		goto out;
1396
1397	opts = to_f_uvc_opts(control->ci_parent);
1398
1399	mutex_lock(&opts->lock);
1400
1401	class_array = uvcg_get_ctl_class_arr(src, opts);
1402	if (!class_array || opts->refcnt)
1403		goto unlock;
1404
1405	target_hdr = to_uvcg_control_header(target);
1406	--target_hdr->linked;
1407	class_array[0] = NULL;
1408
1409unlock:
1410	mutex_unlock(&opts->lock);
1411out:
1412	config_item_put(header);
1413	mutex_unlock(su_mutex);
1414}
1415
1416static struct configfs_item_operations uvcg_control_class_item_ops = {
1417	.release	= uvcg_config_item_release,
1418	.allow_link	= uvcg_control_class_allow_link,
1419	.drop_link	= uvcg_control_class_drop_link,
1420};
1421
1422static const struct config_item_type uvcg_control_class_type = {
1423	.ct_item_ops	= &uvcg_control_class_item_ops,
1424	.ct_owner	= THIS_MODULE,
1425};
1426
1427/* -----------------------------------------------------------------------------
1428 * control/class
1429 */
1430
1431static int uvcg_control_class_create_children(struct config_group *parent)
1432{
1433	static const char * const names[] = { "fs", "ss" };
1434	unsigned int i;
1435
1436	for (i = 0; i < ARRAY_SIZE(names); ++i) {
1437		struct uvcg_control_class_group *group;
1438
1439		group = kzalloc(sizeof(*group), GFP_KERNEL);
1440		if (!group)
1441			return -ENOMEM;
1442
1443		group->name = names[i];
1444
1445		config_group_init_type_name(&group->group, group->name,
1446					    &uvcg_control_class_type);
1447		configfs_add_default_group(&group->group, parent);
1448	}
1449
1450	return 0;
1451}
1452
1453static const struct uvcg_config_group_type uvcg_control_class_grp_type = {
1454	.type = {
1455		.ct_item_ops	= &uvcg_config_item_ops,
1456		.ct_owner	= THIS_MODULE,
1457	},
1458	.name = "class",
1459	.create_children = uvcg_control_class_create_children,
1460};
1461
1462/* -----------------------------------------------------------------------------
1463 * control
1464 */
1465
1466static ssize_t uvcg_default_control_b_interface_number_show(
1467	struct config_item *item, char *page)
1468{
1469	struct config_group *group = to_config_group(item);
1470	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1471	struct config_item *opts_item;
1472	struct f_uvc_opts *opts;
1473	int result = 0;
1474
1475	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1476
1477	opts_item = item->ci_parent;
1478	opts = to_f_uvc_opts(opts_item);
1479
1480	mutex_lock(&opts->lock);
1481	result += sprintf(page, "%u\n", opts->control_interface);
1482	mutex_unlock(&opts->lock);
1483
1484	mutex_unlock(su_mutex);
1485
1486	return result;
1487}
1488
1489UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber);
1490
1491static ssize_t uvcg_default_control_enable_interrupt_ep_show(
1492	struct config_item *item, char *page)
1493{
1494	struct config_group *group = to_config_group(item);
1495	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1496	struct config_item *opts_item;
1497	struct f_uvc_opts *opts;
1498	int result = 0;
1499
1500	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1501
1502	opts_item = item->ci_parent;
1503	opts = to_f_uvc_opts(opts_item);
1504
1505	mutex_lock(&opts->lock);
1506	result += sprintf(page, "%u\n", opts->enable_interrupt_ep);
1507	mutex_unlock(&opts->lock);
1508
1509	mutex_unlock(su_mutex);
1510
1511	return result;
1512}
1513
1514static ssize_t uvcg_default_control_enable_interrupt_ep_store(
1515	struct config_item *item, const char *page, size_t len)
1516{
1517	struct config_group *group = to_config_group(item);
1518	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
1519	struct config_item *opts_item;
1520	struct f_uvc_opts *opts;
1521	ssize_t ret;
1522	u8 num;
1523
1524	ret = kstrtou8(page, 0, &num);
1525	if (ret)
1526		return ret;
1527
1528	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1529
1530	opts_item = item->ci_parent;
1531	opts = to_f_uvc_opts(opts_item);
1532
1533	mutex_lock(&opts->lock);
1534	opts->enable_interrupt_ep = num;
1535	mutex_unlock(&opts->lock);
1536
1537	mutex_unlock(su_mutex);
1538
1539	return len;
1540}
1541UVC_ATTR(uvcg_default_control_, enable_interrupt_ep, enable_interrupt_ep);
1542
1543static struct configfs_attribute *uvcg_default_control_attrs[] = {
1544	&uvcg_default_control_attr_b_interface_number,
1545	&uvcg_default_control_attr_enable_interrupt_ep,
1546	NULL,
1547};
1548
1549static const struct uvcg_config_group_type uvcg_control_grp_type = {
1550	.type = {
1551		.ct_item_ops	= &uvcg_config_item_ops,
1552		.ct_attrs	= uvcg_default_control_attrs,
1553		.ct_owner	= THIS_MODULE,
1554	},
1555	.name = "control",
1556	.children = (const struct uvcg_config_group_type*[]) {
1557		&uvcg_control_header_grp_type,
1558		&uvcg_processing_grp_type,
1559		&uvcg_terminal_grp_type,
1560		&uvcg_control_class_grp_type,
1561		&uvcg_extensions_grp_type,
1562		NULL,
1563	},
1564};
1565
1566/* -----------------------------------------------------------------------------
1567 * streaming/uncompressed
1568 * streaming/mjpeg
1569 * streaming/framebased
1570 */
1571
1572static const char * const uvcg_format_names[] = {
1573	"uncompressed",
1574	"mjpeg",
1575	"framebased",
1576};
1577
1578static struct uvcg_color_matching *
1579uvcg_format_get_default_color_match(struct config_item *streaming)
1580{
1581	struct config_item *color_matching_item, *cm_default;
1582	struct uvcg_color_matching *color_match;
1583
1584	color_matching_item = config_group_find_item(to_config_group(streaming),
1585						     "color_matching");
1586	if (!color_matching_item)
1587		return NULL;
1588
1589	cm_default = config_group_find_item(to_config_group(color_matching_item),
1590					    "default");
1591	config_item_put(color_matching_item);
1592	if (!cm_default)
1593		return NULL;
1594
1595	color_match = to_uvcg_color_matching(to_config_group(cm_default));
1596	config_item_put(cm_default);
1597
1598	return color_match;
1599}
1600
1601static int uvcg_format_allow_link(struct config_item *src, struct config_item *tgt)
1602{
1603	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1604	struct uvcg_color_matching *color_matching_desc;
1605	struct config_item *streaming, *color_matching;
1606	struct uvcg_format *fmt;
1607	int ret = 0;
1608
1609	mutex_lock(su_mutex);
1610
1611	streaming = src->ci_parent->ci_parent;
1612	color_matching = config_group_find_item(to_config_group(streaming), "color_matching");
1613	if (!color_matching || color_matching != tgt->ci_parent) {
1614		ret = -EINVAL;
1615		goto out_put_cm;
1616	}
1617
1618	fmt = to_uvcg_format(src);
1619
1620	/*
1621	 * There's always a color matching descriptor associated with the format
1622	 * but without a symlink it should only ever be the default one. If it's
1623	 * not the default, there's already a symlink and we should bail out.
1624	 */
1625	color_matching_desc = uvcg_format_get_default_color_match(streaming);
1626	if (fmt->color_matching != color_matching_desc) {
1627		ret = -EBUSY;
1628		goto out_put_cm;
1629	}
1630
1631	color_matching_desc->refcnt--;
1632
1633	color_matching_desc = to_uvcg_color_matching(to_config_group(tgt));
1634	fmt->color_matching = color_matching_desc;
1635	color_matching_desc->refcnt++;
1636
1637out_put_cm:
1638	config_item_put(color_matching);
1639	mutex_unlock(su_mutex);
1640
1641	return ret;
1642}
1643
1644static void uvcg_format_drop_link(struct config_item *src, struct config_item *tgt)
1645{
1646	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1647	struct uvcg_color_matching *color_matching_desc;
1648	struct config_item *streaming;
1649	struct uvcg_format *fmt;
1650
1651	mutex_lock(su_mutex);
1652
1653	color_matching_desc = to_uvcg_color_matching(to_config_group(tgt));
1654	color_matching_desc->refcnt--;
1655
1656	streaming = src->ci_parent->ci_parent;
1657	color_matching_desc = uvcg_format_get_default_color_match(streaming);
1658
1659	fmt = to_uvcg_format(src);
1660	fmt->color_matching = color_matching_desc;
1661	color_matching_desc->refcnt++;
1662
1663	mutex_unlock(su_mutex);
1664}
1665
1666static struct configfs_item_operations uvcg_format_item_operations = {
1667	.release	= uvcg_config_item_release,
1668	.allow_link	= uvcg_format_allow_link,
1669	.drop_link	= uvcg_format_drop_link,
1670};
1671
1672static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
1673{
1674	struct f_uvc_opts *opts;
1675	struct config_item *opts_item;
1676	struct mutex *su_mutex = &f->group.cg_subsys->su_mutex;
1677	int result, i;
1678	char *pg = page;
1679
1680	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1681
1682	opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent;
1683	opts = to_f_uvc_opts(opts_item);
1684
1685	mutex_lock(&opts->lock);
1686	result = sprintf(pg, "0x");
1687	pg += result;
1688	for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) {
1689		result += sprintf(pg, "%x\n", f->bmaControls[i]);
1690		pg = page + result;
1691	}
1692	mutex_unlock(&opts->lock);
1693
1694	mutex_unlock(su_mutex);
1695	return result;
1696}
1697
1698static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch,
1699					      const char *page, size_t len)
1700{
1701	struct f_uvc_opts *opts;
1702	struct config_item *opts_item;
1703	struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex;
1704	int ret = -EINVAL;
1705
1706	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1707
1708	opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent;
1709	opts = to_f_uvc_opts(opts_item);
1710
1711	mutex_lock(&opts->lock);
1712	if (ch->linked || opts->refcnt) {
1713		ret = -EBUSY;
1714		goto end;
1715	}
1716
1717	if (len < 4 || *page != '0' ||
1718	    (*(page + 1) != 'x' && *(page + 1) != 'X'))
1719		goto end;
1720	ret = hex2bin(ch->bmaControls, page + 2, 1);
1721	if (ret < 0)
1722		goto end;
1723	ret = len;
1724end:
1725	mutex_unlock(&opts->lock);
1726	mutex_unlock(su_mutex);
1727	return ret;
1728}
1729
1730/* -----------------------------------------------------------------------------
1731 * streaming/header/<NAME>
1732 * streaming/header
1733 */
1734
1735static void uvcg_format_set_indices(struct config_group *fmt);
1736
1737static int uvcg_streaming_header_allow_link(struct config_item *src,
1738					    struct config_item *target)
1739{
1740	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1741	struct config_item *opts_item;
1742	struct f_uvc_opts *opts;
1743	struct uvcg_streaming_header *src_hdr;
1744	struct uvcg_format *target_fmt = NULL;
1745	struct uvcg_format_ptr *format_ptr;
1746	int i, ret = -EINVAL;
1747
1748	src_hdr = to_uvcg_streaming_header(src);
1749	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1750
1751	opts_item = src->ci_parent->ci_parent->ci_parent;
1752	opts = to_f_uvc_opts(opts_item);
1753
1754	mutex_lock(&opts->lock);
1755
1756	if (src_hdr->linked) {
1757		ret = -EBUSY;
1758		goto out;
1759	}
1760
1761	/*
1762	 * Linking is only allowed to direct children of the format nodes
1763	 * (streaming/uncompressed or streaming/mjpeg nodes). First check that
1764	 * the grand-parent of the target matches the grand-parent of the source
1765	 * (the streaming node), and then verify that the target parent is a
1766	 * format node.
1767	 */
1768	if (src->ci_parent->ci_parent != target->ci_parent->ci_parent)
1769		goto out;
1770
1771	for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) {
1772		if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i]))
1773			break;
1774	}
1775
1776	if (i == ARRAY_SIZE(uvcg_format_names))
1777		goto out;
1778
1779	target_fmt = container_of(to_config_group(target), struct uvcg_format,
1780				  group);
1781
1782	if (!target_fmt)
1783		goto out;
1784
1785	uvcg_format_set_indices(to_config_group(target));
1786
1787	format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
1788	if (!format_ptr) {
1789		ret = -ENOMEM;
1790		goto out;
1791	}
1792	ret = 0;
1793	format_ptr->fmt = target_fmt;
1794	list_add_tail(&format_ptr->entry, &src_hdr->formats);
1795	++src_hdr->num_fmt;
1796	++target_fmt->linked;
1797
1798out:
1799	mutex_unlock(&opts->lock);
1800	mutex_unlock(su_mutex);
1801	return ret;
1802}
1803
1804static void uvcg_streaming_header_drop_link(struct config_item *src,
1805					   struct config_item *target)
1806{
1807	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1808	struct config_item *opts_item;
1809	struct f_uvc_opts *opts;
1810	struct uvcg_streaming_header *src_hdr;
1811	struct uvcg_format *target_fmt = NULL;
1812	struct uvcg_format_ptr *format_ptr, *tmp;
1813
1814	src_hdr = to_uvcg_streaming_header(src);
1815	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1816
1817	opts_item = src->ci_parent->ci_parent->ci_parent;
1818	opts = to_f_uvc_opts(opts_item);
1819
1820	mutex_lock(&opts->lock);
1821	target_fmt = container_of(to_config_group(target), struct uvcg_format,
1822				  group);
1823
1824	if (!target_fmt)
1825		goto out;
1826
1827	list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
1828		if (format_ptr->fmt == target_fmt) {
1829			list_del(&format_ptr->entry);
1830			kfree(format_ptr);
1831			--src_hdr->num_fmt;
1832			break;
1833		}
1834
1835	--target_fmt->linked;
1836
1837out:
1838	mutex_unlock(&opts->lock);
1839	mutex_unlock(su_mutex);
1840}
1841
1842static struct configfs_item_operations uvcg_streaming_header_item_ops = {
1843	.release	= uvcg_config_item_release,
1844	.allow_link	= uvcg_streaming_header_allow_link,
1845	.drop_link	= uvcg_streaming_header_drop_link,
1846};
1847
1848#define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits)			\
1849static ssize_t uvcg_streaming_header_##cname##_show(			\
1850	struct config_item *item, char *page)				\
1851{									\
1852	struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
1853	struct f_uvc_opts *opts;					\
1854	struct config_item *opts_item;					\
1855	struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
1856	int result;							\
1857									\
1858	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1859									\
1860	opts_item = sh->item.ci_parent->ci_parent->ci_parent;		\
1861	opts = to_f_uvc_opts(opts_item);				\
1862									\
1863	mutex_lock(&opts->lock);					\
1864	result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\
1865	mutex_unlock(&opts->lock);					\
1866									\
1867	mutex_unlock(su_mutex);						\
1868	return result;							\
1869}									\
1870									\
1871UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
1872
1873UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, 8);
1874UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, 8);
1875UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 8);
1876UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, 8);
1877UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, 8);
1878
1879#undef UVCG_STREAMING_HEADER_ATTR
1880
1881static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
1882	&uvcg_streaming_header_attr_bm_info,
1883	&uvcg_streaming_header_attr_b_terminal_link,
1884	&uvcg_streaming_header_attr_b_still_capture_method,
1885	&uvcg_streaming_header_attr_b_trigger_support,
1886	&uvcg_streaming_header_attr_b_trigger_usage,
1887	NULL,
1888};
1889
1890static const struct config_item_type uvcg_streaming_header_type = {
1891	.ct_item_ops	= &uvcg_streaming_header_item_ops,
1892	.ct_attrs	= uvcg_streaming_header_attrs,
1893	.ct_owner	= THIS_MODULE,
1894};
1895
1896static struct config_item
1897*uvcg_streaming_header_make(struct config_group *group, const char *name)
1898{
1899	struct uvcg_streaming_header *h;
1900
1901	h = kzalloc(sizeof(*h), GFP_KERNEL);
1902	if (!h)
1903		return ERR_PTR(-ENOMEM);
1904
1905	INIT_LIST_HEAD(&h->formats);
1906	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1907	h->desc.bDescriptorSubType	= UVC_VS_INPUT_HEADER;
1908	h->desc.bTerminalLink		= 3;
1909	h->desc.bControlSize		= UVCG_STREAMING_CONTROL_SIZE;
1910
1911	config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
1912
1913	return &h->item;
1914}
1915
1916static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
1917	.make_item		= uvcg_streaming_header_make,
1918};
1919
1920static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = {
1921	.type = {
1922		.ct_item_ops	= &uvcg_config_item_ops,
1923		.ct_group_ops	= &uvcg_streaming_header_grp_ops,
1924		.ct_owner	= THIS_MODULE,
1925	},
1926	.name = "header",
1927};
1928
1929/* -----------------------------------------------------------------------------
1930 * streaming/<mode>/<format>/<NAME>
1931 */
1932
1933#define UVCG_FRAME_ATTR(cname, aname, bits) \
1934static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
1935{									\
1936	struct uvcg_frame *f = to_uvcg_frame(item);			\
1937	struct f_uvc_opts *opts;					\
1938	struct config_item *opts_item;					\
1939	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1940	int result;							\
1941									\
1942	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1943									\
1944	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1945	opts = to_f_uvc_opts(opts_item);				\
1946									\
1947	mutex_lock(&opts->lock);					\
1948	result = sprintf(page, "%u\n", f->frame.cname);			\
1949	mutex_unlock(&opts->lock);					\
1950									\
1951	mutex_unlock(su_mutex);						\
1952	return result;							\
1953}									\
1954									\
1955static ssize_t  uvcg_frame_##cname##_store(struct config_item *item,	\
1956					   const char *page, size_t len)\
1957{									\
1958	struct uvcg_frame *f = to_uvcg_frame(item);			\
1959	struct f_uvc_opts *opts;					\
1960	struct config_item *opts_item;					\
1961	struct uvcg_format *fmt;					\
1962	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1963	typeof(f->frame.cname) num;					\
1964	int ret;							\
1965									\
1966	ret = kstrtou##bits(page, 0, &num);				\
1967	if (ret)							\
1968		return ret;						\
1969									\
1970	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1971									\
1972	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1973	opts = to_f_uvc_opts(opts_item);				\
1974	fmt = to_uvcg_format(f->item.ci_parent);			\
1975									\
1976	mutex_lock(&opts->lock);					\
1977	if (fmt->linked || opts->refcnt) {				\
1978		ret = -EBUSY;						\
1979		goto end;						\
1980	}								\
1981									\
1982	f->frame.cname = num;						\
1983	ret = len;							\
1984end:									\
1985	mutex_unlock(&opts->lock);					\
1986	mutex_unlock(su_mutex);						\
1987	return ret;							\
1988}									\
1989									\
1990UVC_ATTR(uvcg_frame_, cname, aname);
1991
1992static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item,
1993					     char *page)
1994{
1995	struct uvcg_frame *f = to_uvcg_frame(item);
1996	struct uvcg_format *fmt;
1997	struct f_uvc_opts *opts;
1998	struct config_item *opts_item;
1999	struct config_item *fmt_item;
2000	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;
2001	int result;
2002
2003	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2004
2005	fmt_item = f->item.ci_parent;
2006	fmt = to_uvcg_format(fmt_item);
2007
2008	if (!fmt->linked) {
2009		result = -EBUSY;
2010		goto out;
2011	}
2012
2013	opts_item = fmt_item->ci_parent->ci_parent->ci_parent;
2014	opts = to_f_uvc_opts(opts_item);
2015
2016	mutex_lock(&opts->lock);
2017	result = sprintf(page, "%u\n", f->frame.b_frame_index);
2018	mutex_unlock(&opts->lock);
2019
2020out:
2021	mutex_unlock(su_mutex);
2022	return result;
2023}
2024
2025UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex);
2026
2027UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, 8);
2028UVCG_FRAME_ATTR(w_width, wWidth, 16);
2029UVCG_FRAME_ATTR(w_height, wHeight, 16);
2030UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
2031UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
2032UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
2033UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
2034UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32);
2035
2036#undef UVCG_FRAME_ATTR
2037
2038static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
2039						 char *page)
2040{
2041	struct uvcg_frame *frm = to_uvcg_frame(item);
2042	struct f_uvc_opts *opts;
2043	struct config_item *opts_item;
2044	struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
2045	int result, i;
2046	char *pg = page;
2047
2048	mutex_lock(su_mutex);	/* for navigating configfs hierarchy */
2049
2050	opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
2051	opts = to_f_uvc_opts(opts_item);
2052
2053	mutex_lock(&opts->lock);
2054	for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
2055		result += sprintf(pg, "%u\n", frm->dw_frame_interval[i]);
2056		pg = page + result;
2057	}
2058	mutex_unlock(&opts->lock);
2059
2060	mutex_unlock(su_mutex);
2061	return result;
2062}
2063
2064static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
2065						  const char *page, size_t len)
2066{
2067	struct uvcg_frame *ch = to_uvcg_frame(item);
2068	struct f_uvc_opts *opts;
2069	struct config_item *opts_item;
2070	struct uvcg_format *fmt;
2071	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
2072	int ret = 0, n = 0;
2073	u32 *frm_intrv, *tmp;
2074
2075	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2076
2077	opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
2078	opts = to_f_uvc_opts(opts_item);
2079	fmt = to_uvcg_format(ch->item.ci_parent);
2080
2081	mutex_lock(&opts->lock);
2082	if (fmt->linked || opts->refcnt) {
2083		ret = -EBUSY;
2084		goto end;
2085	}
2086
2087	ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, sizeof(u32));
2088	if (ret)
2089		goto end;
2090
2091	tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
2092	if (!frm_intrv) {
2093		ret = -ENOMEM;
2094		goto end;
2095	}
2096
2097	ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, sizeof(u32));
2098	if (ret) {
2099		kfree(frm_intrv);
2100		goto end;
2101	}
2102
2103	kfree(ch->dw_frame_interval);
2104	ch->dw_frame_interval = frm_intrv;
2105	ch->frame.b_frame_interval_type = n;
2106	sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval),
2107	     uvcg_config_compare_u32, NULL);
2108	ret = len;
2109
2110end:
2111	mutex_unlock(&opts->lock);
2112	mutex_unlock(su_mutex);
2113	return ret;
2114}
2115
2116UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
2117
2118static struct configfs_attribute *uvcg_frame_attrs1[] = {
2119	&uvcg_frame_attr_b_frame_index,
2120	&uvcg_frame_attr_bm_capabilities,
2121	&uvcg_frame_attr_w_width,
2122	&uvcg_frame_attr_w_height,
2123	&uvcg_frame_attr_dw_min_bit_rate,
2124	&uvcg_frame_attr_dw_max_bit_rate,
2125	&uvcg_frame_attr_dw_max_video_frame_buffer_size,
2126	&uvcg_frame_attr_dw_default_frame_interval,
2127	&uvcg_frame_attr_dw_frame_interval,
2128	NULL,
2129};
2130
2131static struct configfs_attribute *uvcg_frame_attrs2[] = {
2132	&uvcg_frame_attr_b_frame_index,
2133	&uvcg_frame_attr_bm_capabilities,
2134	&uvcg_frame_attr_w_width,
2135	&uvcg_frame_attr_w_height,
2136	&uvcg_frame_attr_dw_min_bit_rate,
2137	&uvcg_frame_attr_dw_max_bit_rate,
2138	&uvcg_frame_attr_dw_default_frame_interval,
2139	&uvcg_frame_attr_dw_frame_interval,
2140	&uvcg_frame_attr_dw_bytes_perline,
2141	NULL,
2142};
2143
2144static const struct config_item_type uvcg_frame_type1 = {
2145	.ct_item_ops	= &uvcg_config_item_ops,
2146	.ct_attrs	= uvcg_frame_attrs1,
2147	.ct_owner	= THIS_MODULE,
2148};
2149
2150static const struct config_item_type uvcg_frame_type2 = {
2151	.ct_item_ops    = &uvcg_config_item_ops,
2152	.ct_attrs       = uvcg_frame_attrs2,
2153	.ct_owner       = THIS_MODULE,
2154};
2155
2156static struct config_item *uvcg_frame_make(struct config_group *group,
2157					   const char *name)
2158{
2159	struct uvcg_frame *h;
2160	struct uvcg_format *fmt;
2161	struct f_uvc_opts *opts;
2162	struct config_item *opts_item;
2163	struct uvcg_frame_ptr *frame_ptr;
2164
2165	h = kzalloc(sizeof(*h), GFP_KERNEL);
2166	if (!h)
2167		return ERR_PTR(-ENOMEM);
2168
2169	h->frame.b_descriptor_type		= USB_DT_CS_INTERFACE;
2170	h->frame.b_frame_index			= 1;
2171	h->frame.w_width			= 640;
2172	h->frame.w_height			= 360;
2173	h->frame.dw_min_bit_rate		= 18432000;
2174	h->frame.dw_max_bit_rate		= 55296000;
2175	h->frame.dw_max_video_frame_buffer_size	= 460800;
2176	h->frame.dw_default_frame_interval	= 666666;
2177	h->frame.dw_bytes_perline		= 0;
2178
2179	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
2180	opts = to_f_uvc_opts(opts_item);
2181
2182	mutex_lock(&opts->lock);
2183	fmt = to_uvcg_format(&group->cg_item);
2184	if (fmt->type == UVCG_UNCOMPRESSED) {
2185		h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
2186		h->fmt_type = UVCG_UNCOMPRESSED;
2187	} else if (fmt->type == UVCG_MJPEG) {
2188		h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
2189		h->fmt_type = UVCG_MJPEG;
2190	} else if (fmt->type == UVCG_FRAMEBASED) {
2191		h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED;
2192		h->fmt_type = UVCG_FRAMEBASED;
2193	} else {
2194		mutex_unlock(&opts->lock);
2195		kfree(h);
2196		return ERR_PTR(-EINVAL);
2197	}
2198
2199	frame_ptr = kzalloc(sizeof(*frame_ptr), GFP_KERNEL);
2200	if (!frame_ptr) {
2201		mutex_unlock(&opts->lock);
2202		kfree(h);
2203		return ERR_PTR(-ENOMEM);
2204	}
2205
2206	frame_ptr->frm = h;
2207	list_add_tail(&frame_ptr->entry, &fmt->frames);
2208	++fmt->num_frames;
2209	mutex_unlock(&opts->lock);
2210
2211	if (fmt->type == UVCG_FRAMEBASED)
2212		config_item_init_type_name(&h->item, name, &uvcg_frame_type2);
2213	else
2214		config_item_init_type_name(&h->item, name, &uvcg_frame_type1);
2215
2216	return &h->item;
2217}
2218
2219static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
2220{
2221	struct uvcg_format *fmt;
2222	struct f_uvc_opts *opts;
2223	struct config_item *opts_item;
2224	struct uvcg_frame *target_frm = NULL;
2225	struct uvcg_frame_ptr *frame_ptr, *tmp;
2226
2227	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
2228	opts = to_f_uvc_opts(opts_item);
2229
2230	mutex_lock(&opts->lock);
2231	target_frm = container_of(item, struct uvcg_frame, item);
2232	fmt = to_uvcg_format(&group->cg_item);
2233
2234	list_for_each_entry_safe(frame_ptr, tmp, &fmt->frames, entry)
2235		if (frame_ptr->frm == target_frm) {
2236			list_del(&frame_ptr->entry);
2237			kfree(frame_ptr);
2238			--fmt->num_frames;
2239			break;
2240		}
2241	mutex_unlock(&opts->lock);
2242
2243	config_item_put(item);
2244}
2245
2246static void uvcg_format_set_indices(struct config_group *fmt)
2247{
2248	struct config_item *ci;
2249	unsigned int i = 1;
2250
2251	list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
2252		struct uvcg_frame *frm;
2253
2254		frm = to_uvcg_frame(ci);
2255		frm->frame.b_frame_index = i++;
2256	}
2257}
2258
2259/* -----------------------------------------------------------------------------
2260 * streaming/uncompressed/<NAME>
2261 */
2262
2263static struct configfs_group_operations uvcg_uncompressed_group_ops = {
2264	.make_item		= uvcg_frame_make,
2265	.drop_item		= uvcg_frame_drop,
2266};
2267
2268static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
2269							char *page)
2270{
2271	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
2272	struct f_uvc_opts *opts;
2273	struct config_item *opts_item;
2274	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
2275
2276	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2277
2278	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
2279	opts = to_f_uvc_opts(opts_item);
2280
2281	mutex_lock(&opts->lock);
2282	memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
2283	mutex_unlock(&opts->lock);
2284
2285	mutex_unlock(su_mutex);
2286
2287	return sizeof(ch->desc.guidFormat);
2288}
2289
2290static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
2291						   const char *page, size_t len)
2292{
2293	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
2294	struct f_uvc_opts *opts;
2295	struct config_item *opts_item;
2296	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
2297	const struct uvc_format_desc *format;
2298	u8 tmpguidFormat[sizeof(ch->desc.guidFormat)];
2299	int ret;
2300
2301	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2302
2303	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
2304	opts = to_f_uvc_opts(opts_item);
2305
2306	mutex_lock(&opts->lock);
2307	if (ch->fmt.linked || opts->refcnt) {
2308		ret = -EBUSY;
2309		goto end;
2310	}
2311
2312	memcpy(tmpguidFormat, page,
2313	       min(sizeof(tmpguidFormat), len));
2314
2315	format = uvc_format_by_guid(tmpguidFormat);
2316	if (!format) {
2317		ret = -EINVAL;
2318		goto end;
2319	}
2320
2321	memcpy(ch->desc.guidFormat, tmpguidFormat,
2322	       min(sizeof(ch->desc.guidFormat), len));
2323	ret = sizeof(ch->desc.guidFormat);
2324
2325end:
2326	mutex_unlock(&opts->lock);
2327	mutex_unlock(su_mutex);
2328	return ret;
2329}
2330
2331UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
2332
2333#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits)			\
2334static ssize_t uvcg_uncompressed_##cname##_show(			\
2335	struct config_item *item, char *page)				\
2336{									\
2337	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
2338	struct f_uvc_opts *opts;					\
2339	struct config_item *opts_item;					\
2340	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2341	int result;							\
2342									\
2343	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2344									\
2345	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2346	opts = to_f_uvc_opts(opts_item);				\
2347									\
2348	mutex_lock(&opts->lock);					\
2349	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2350	mutex_unlock(&opts->lock);					\
2351									\
2352	mutex_unlock(su_mutex);						\
2353	return result;							\
2354}									\
2355									\
2356UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
2357
2358#define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits)			\
2359static ssize_t uvcg_uncompressed_##cname##_show(			\
2360	struct config_item *item, char *page)				\
2361{									\
2362	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
2363	struct f_uvc_opts *opts;					\
2364	struct config_item *opts_item;					\
2365	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2366	int result;							\
2367									\
2368	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2369									\
2370	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2371	opts = to_f_uvc_opts(opts_item);				\
2372									\
2373	mutex_lock(&opts->lock);					\
2374	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2375	mutex_unlock(&opts->lock);					\
2376									\
2377	mutex_unlock(su_mutex);						\
2378	return result;							\
2379}									\
2380									\
2381static ssize_t								\
2382uvcg_uncompressed_##cname##_store(struct config_item *item,		\
2383				    const char *page, size_t len)	\
2384{									\
2385	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
2386	struct f_uvc_opts *opts;					\
2387	struct config_item *opts_item;					\
2388	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2389	int ret;							\
2390	u8 num;								\
2391									\
2392	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2393									\
2394	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2395	opts = to_f_uvc_opts(opts_item);				\
2396									\
2397	mutex_lock(&opts->lock);					\
2398	if (u->fmt.linked || opts->refcnt) {				\
2399		ret = -EBUSY;						\
2400		goto end;						\
2401	}								\
2402									\
2403	ret = kstrtou8(page, 0, &num);					\
2404	if (ret)							\
2405		goto end;						\
2406									\
2407	/* index values in uvc are never 0 */				\
2408	if (!num) {							\
2409		ret = -EINVAL;						\
2410		goto end;						\
2411	}								\
2412									\
2413	u->desc.aname = num;						\
2414	ret = len;							\
2415end:									\
2416	mutex_unlock(&opts->lock);					\
2417	mutex_unlock(su_mutex);						\
2418	return ret;							\
2419}									\
2420									\
2421UVC_ATTR(uvcg_uncompressed_, cname, aname);
2422
2423UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8);
2424UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8);
2425UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
2426UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
2427UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
2428UVCG_UNCOMPRESSED_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
2429
2430#undef UVCG_UNCOMPRESSED_ATTR
2431#undef UVCG_UNCOMPRESSED_ATTR_RO
2432
2433static inline ssize_t
2434uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
2435{
2436	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
2437	return uvcg_format_bma_controls_show(&unc->fmt, page);
2438}
2439
2440static inline ssize_t
2441uvcg_uncompressed_bma_controls_store(struct config_item *item,
2442				     const char *page, size_t len)
2443{
2444	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
2445	return uvcg_format_bma_controls_store(&unc->fmt, page, len);
2446}
2447
2448UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
2449
2450static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
2451	&uvcg_uncompressed_attr_b_format_index,
2452	&uvcg_uncompressed_attr_guid_format,
2453	&uvcg_uncompressed_attr_b_bits_per_pixel,
2454	&uvcg_uncompressed_attr_b_default_frame_index,
2455	&uvcg_uncompressed_attr_b_aspect_ratio_x,
2456	&uvcg_uncompressed_attr_b_aspect_ratio_y,
2457	&uvcg_uncompressed_attr_bm_interlace_flags,
2458	&uvcg_uncompressed_attr_bma_controls,
2459	NULL,
2460};
2461
2462static const struct config_item_type uvcg_uncompressed_type = {
2463	.ct_item_ops	= &uvcg_format_item_operations,
2464	.ct_group_ops	= &uvcg_uncompressed_group_ops,
2465	.ct_attrs	= uvcg_uncompressed_attrs,
2466	.ct_owner	= THIS_MODULE,
2467};
2468
2469static struct config_group *uvcg_uncompressed_make(struct config_group *group,
2470						   const char *name)
2471{
2472	static char guid[] = {
2473		'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
2474		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
2475	};
2476	struct uvcg_color_matching *color_match;
2477	struct config_item *streaming;
2478	struct uvcg_uncompressed *h;
2479
2480	streaming = group->cg_item.ci_parent;
2481	color_match = uvcg_format_get_default_color_match(streaming);
2482	if (!color_match)
2483		return ERR_PTR(-EINVAL);
2484
2485	h = kzalloc(sizeof(*h), GFP_KERNEL);
2486	if (!h)
2487		return ERR_PTR(-ENOMEM);
2488
2489	h->desc.bLength			= UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
2490	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
2491	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED;
2492	memcpy(h->desc.guidFormat, guid, sizeof(guid));
2493	h->desc.bBitsPerPixel		= 16;
2494	h->desc.bDefaultFrameIndex	= 1;
2495	h->desc.bAspectRatioX		= 0;
2496	h->desc.bAspectRatioY		= 0;
2497	h->desc.bmInterlaceFlags	= 0;
2498	h->desc.bCopyProtect		= 0;
2499
2500	INIT_LIST_HEAD(&h->fmt.frames);
2501	h->fmt.type = UVCG_UNCOMPRESSED;
2502	h->fmt.color_matching = color_match;
2503	color_match->refcnt++;
2504	config_group_init_type_name(&h->fmt.group, name,
2505				    &uvcg_uncompressed_type);
2506
2507	return &h->fmt.group;
2508}
2509
2510static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
2511	.make_group		= uvcg_uncompressed_make,
2512};
2513
2514static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = {
2515	.type = {
2516		.ct_item_ops	= &uvcg_config_item_ops,
2517		.ct_group_ops	= &uvcg_uncompressed_grp_ops,
2518		.ct_owner	= THIS_MODULE,
2519	},
2520	.name = "uncompressed",
2521};
2522
2523/* -----------------------------------------------------------------------------
2524 * streaming/mjpeg/<NAME>
2525 */
2526
2527static struct configfs_group_operations uvcg_mjpeg_group_ops = {
2528	.make_item		= uvcg_frame_make,
2529	.drop_item		= uvcg_frame_drop,
2530};
2531
2532#define UVCG_MJPEG_ATTR_RO(cname, aname, bits)				\
2533static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
2534{									\
2535	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
2536	struct f_uvc_opts *opts;					\
2537	struct config_item *opts_item;					\
2538	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2539	int result;							\
2540									\
2541	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2542									\
2543	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2544	opts = to_f_uvc_opts(opts_item);				\
2545									\
2546	mutex_lock(&opts->lock);					\
2547	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2548	mutex_unlock(&opts->lock);					\
2549									\
2550	mutex_unlock(su_mutex);						\
2551	return result;							\
2552}									\
2553									\
2554UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
2555
2556#define UVCG_MJPEG_ATTR(cname, aname, bits)				\
2557static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
2558{									\
2559	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
2560	struct f_uvc_opts *opts;					\
2561	struct config_item *opts_item;					\
2562	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2563	int result;							\
2564									\
2565	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2566									\
2567	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2568	opts = to_f_uvc_opts(opts_item);				\
2569									\
2570	mutex_lock(&opts->lock);					\
2571	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2572	mutex_unlock(&opts->lock);					\
2573									\
2574	mutex_unlock(su_mutex);						\
2575	return result;							\
2576}									\
2577									\
2578static ssize_t								\
2579uvcg_mjpeg_##cname##_store(struct config_item *item,			\
2580			   const char *page, size_t len)		\
2581{									\
2582	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
2583	struct f_uvc_opts *opts;					\
2584	struct config_item *opts_item;					\
2585	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2586	int ret;							\
2587	u8 num;								\
2588									\
2589	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2590									\
2591	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2592	opts = to_f_uvc_opts(opts_item);				\
2593									\
2594	mutex_lock(&opts->lock);					\
2595	if (u->fmt.linked || opts->refcnt) {				\
2596		ret = -EBUSY;						\
2597		goto end;						\
2598	}								\
2599									\
2600	ret = kstrtou8(page, 0, &num);					\
2601	if (ret)							\
2602		goto end;						\
2603									\
2604	/* index values in uvc are never 0 */				\
2605	if (!num) {							\
2606		ret = -EINVAL;						\
2607		goto end;						\
2608	}								\
2609									\
2610	u->desc.aname = num;						\
2611	ret = len;							\
2612end:									\
2613	mutex_unlock(&opts->lock);					\
2614	mutex_unlock(su_mutex);						\
2615	return ret;							\
2616}									\
2617									\
2618UVC_ATTR(uvcg_mjpeg_, cname, aname)
2619
2620UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8);
2621UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
2622UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8);
2623UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
2624UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
2625UVCG_MJPEG_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
2626
2627#undef UVCG_MJPEG_ATTR
2628#undef UVCG_MJPEG_ATTR_RO
2629
2630static inline ssize_t
2631uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
2632{
2633	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
2634	return uvcg_format_bma_controls_show(&u->fmt, page);
2635}
2636
2637static inline ssize_t
2638uvcg_mjpeg_bma_controls_store(struct config_item *item,
2639				     const char *page, size_t len)
2640{
2641	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
2642	return uvcg_format_bma_controls_store(&u->fmt, page, len);
2643}
2644
2645UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
2646
2647static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
2648	&uvcg_mjpeg_attr_b_format_index,
2649	&uvcg_mjpeg_attr_b_default_frame_index,
2650	&uvcg_mjpeg_attr_bm_flags,
2651	&uvcg_mjpeg_attr_b_aspect_ratio_x,
2652	&uvcg_mjpeg_attr_b_aspect_ratio_y,
2653	&uvcg_mjpeg_attr_bm_interlace_flags,
2654	&uvcg_mjpeg_attr_bma_controls,
2655	NULL,
2656};
2657
2658static const struct config_item_type uvcg_mjpeg_type = {
2659	.ct_item_ops	= &uvcg_format_item_operations,
2660	.ct_group_ops	= &uvcg_mjpeg_group_ops,
2661	.ct_attrs	= uvcg_mjpeg_attrs,
2662	.ct_owner	= THIS_MODULE,
2663};
2664
2665static struct config_group *uvcg_mjpeg_make(struct config_group *group,
2666						   const char *name)
2667{
2668	struct uvcg_color_matching *color_match;
2669	struct config_item *streaming;
2670	struct uvcg_mjpeg *h;
2671
2672	streaming = group->cg_item.ci_parent;
2673	color_match = uvcg_format_get_default_color_match(streaming);
2674	if (!color_match)
2675		return ERR_PTR(-EINVAL);
2676
2677	h = kzalloc(sizeof(*h), GFP_KERNEL);
2678	if (!h)
2679		return ERR_PTR(-ENOMEM);
2680
2681	h->desc.bLength			= UVC_DT_FORMAT_MJPEG_SIZE;
2682	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
2683	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG;
2684	h->desc.bDefaultFrameIndex	= 1;
2685	h->desc.bAspectRatioX		= 0;
2686	h->desc.bAspectRatioY		= 0;
2687	h->desc.bmInterlaceFlags	= 0;
2688	h->desc.bCopyProtect		= 0;
2689
2690	INIT_LIST_HEAD(&h->fmt.frames);
2691	h->fmt.type = UVCG_MJPEG;
2692	h->fmt.color_matching = color_match;
2693	color_match->refcnt++;
2694	config_group_init_type_name(&h->fmt.group, name,
2695				    &uvcg_mjpeg_type);
2696
2697	return &h->fmt.group;
2698}
2699
2700static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
2701	.make_group		= uvcg_mjpeg_make,
2702};
2703
2704static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
2705	.type = {
2706		.ct_item_ops	= &uvcg_config_item_ops,
2707		.ct_group_ops	= &uvcg_mjpeg_grp_ops,
2708		.ct_owner	= THIS_MODULE,
2709	},
2710	.name = "mjpeg",
2711};
2712
2713/* -----------------------------------------------------------------------------
2714 * streaming/framebased/<NAME>
2715 */
2716
2717static struct configfs_group_operations uvcg_framebased_group_ops = {
2718	.make_item              = uvcg_frame_make,
2719	.drop_item              = uvcg_frame_drop,
2720};
2721
2722#define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits)			\
2723static ssize_t uvcg_framebased_##cname##_show(struct config_item *item,	\
2724		char *page)						\
2725{									\
2726	struct uvcg_framebased *u = to_uvcg_framebased(item);		\
2727	struct f_uvc_opts *opts;					\
2728	struct config_item *opts_item;					\
2729	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2730	int result;							\
2731									\
2732	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2733									\
2734	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2735	opts = to_f_uvc_opts(opts_item);				\
2736									\
2737	mutex_lock(&opts->lock);					\
2738	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2739	mutex_unlock(&opts->lock);					\
2740									\
2741	mutex_unlock(su_mutex);						\
2742	return result;							\
2743}									\
2744									\
2745UVC_ATTR_RO(uvcg_framebased_, cname, aname)
2746
2747#define UVCG_FRAMEBASED_ATTR(cname, aname, bits)			\
2748static ssize_t uvcg_framebased_##cname##_show(struct config_item *item,	\
2749		char *page)						\
2750{									\
2751	struct uvcg_framebased *u = to_uvcg_framebased(item);		\
2752	struct f_uvc_opts *opts;					\
2753	struct config_item *opts_item;					\
2754	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2755	int result;							\
2756									\
2757	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2758									\
2759	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2760	opts = to_f_uvc_opts(opts_item);				\
2761									\
2762	mutex_lock(&opts->lock);					\
2763	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
2764	mutex_unlock(&opts->lock);					\
2765									\
2766	mutex_unlock(su_mutex);						\
2767	return result;							\
2768}									\
2769									\
2770static ssize_t								\
2771uvcg_framebased_##cname##_store(struct config_item *item,		\
2772		const char *page, size_t len)				\
2773{									\
2774	struct uvcg_framebased *u = to_uvcg_framebased(item);		\
2775	struct f_uvc_opts *opts;					\
2776	struct config_item *opts_item;					\
2777	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
2778	int ret;							\
2779	u8 num;								\
2780									\
2781	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2782									\
2783	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
2784	opts = to_f_uvc_opts(opts_item);				\
2785									\
2786	mutex_lock(&opts->lock);					\
2787	if (u->fmt.linked || opts->refcnt) {				\
2788		ret = -EBUSY;						\
2789		goto end;						\
2790	}								\
2791									\
2792	ret = kstrtou8(page, 0, &num);					\
2793	if (ret)							\
2794		goto end;						\
2795									\
2796	if (num > 255) {						\
2797		ret = -EINVAL;						\
2798		goto end;						\
2799	}								\
2800	u->desc.aname = num;						\
2801	ret = len;							\
2802end:									\
2803	mutex_unlock(&opts->lock);					\
2804	mutex_unlock(su_mutex);						\
2805	return ret;							\
2806}									\
2807									\
2808UVC_ATTR(uvcg_framebased_, cname, aname)
2809
2810UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8);
2811UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8);
2812UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
2813UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
2814UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
2815UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
2816
2817#undef UVCG_FRAMEBASED_ATTR
2818#undef UVCG_FRAMEBASED_ATTR_RO
2819
2820static ssize_t uvcg_framebased_guid_format_show(struct config_item *item,
2821						char *page)
2822{
2823	struct uvcg_framebased *ch = to_uvcg_framebased(item);
2824	struct f_uvc_opts *opts;
2825	struct config_item *opts_item;
2826	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
2827
2828	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2829
2830	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
2831	opts = to_f_uvc_opts(opts_item);
2832
2833	mutex_lock(&opts->lock);
2834	memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
2835	mutex_unlock(&opts->lock);
2836
2837	mutex_unlock(su_mutex);
2838
2839	return sizeof(ch->desc.guidFormat);
2840}
2841
2842static ssize_t uvcg_framebased_guid_format_store(struct config_item *item,
2843						 const char *page, size_t len)
2844{
2845	struct uvcg_framebased *ch = to_uvcg_framebased(item);
2846	struct f_uvc_opts *opts;
2847	struct config_item *opts_item;
2848	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
2849	int ret;
2850
2851	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2852
2853	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
2854	opts = to_f_uvc_opts(opts_item);
2855
2856	mutex_lock(&opts->lock);
2857	if (ch->fmt.linked || opts->refcnt) {
2858		ret = -EBUSY;
2859		goto end;
2860	}
2861
2862	memcpy(ch->desc.guidFormat, page,
2863	       min(sizeof(ch->desc.guidFormat), len));
2864	ret = sizeof(ch->desc.guidFormat);
2865
2866end:
2867	mutex_unlock(&opts->lock);
2868	mutex_unlock(su_mutex);
2869	return ret;
2870}
2871
2872UVC_ATTR(uvcg_framebased_, guid_format, guidFormat);
2873
2874static inline ssize_t
2875uvcg_framebased_bma_controls_show(struct config_item *item, char *page)
2876{
2877	struct uvcg_framebased *u = to_uvcg_framebased(item);
2878
2879	return uvcg_format_bma_controls_show(&u->fmt, page);
2880}
2881
2882static inline ssize_t
2883uvcg_framebased_bma_controls_store(struct config_item *item,
2884				   const char *page, size_t len)
2885{
2886	struct uvcg_framebased *u = to_uvcg_framebased(item);
2887
2888	return uvcg_format_bma_controls_store(&u->fmt, page, len);
2889}
2890
2891UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls);
2892
2893static struct configfs_attribute *uvcg_framebased_attrs[] = {
2894	&uvcg_framebased_attr_b_format_index,
2895	&uvcg_framebased_attr_b_default_frame_index,
2896	&uvcg_framebased_attr_b_bits_per_pixel,
2897	&uvcg_framebased_attr_b_aspect_ratio_x,
2898	&uvcg_framebased_attr_b_aspect_ratio_y,
2899	&uvcg_framebased_attr_bm_interface_flags,
2900	&uvcg_framebased_attr_bma_controls,
2901	&uvcg_framebased_attr_guid_format,
2902	NULL,
2903};
2904
2905static const struct config_item_type uvcg_framebased_type = {
2906	.ct_item_ops    = &uvcg_config_item_ops,
2907	.ct_group_ops   = &uvcg_framebased_group_ops,
2908	.ct_attrs       = uvcg_framebased_attrs,
2909	.ct_owner       = THIS_MODULE,
2910};
2911
2912static struct config_group *uvcg_framebased_make(struct config_group *group,
2913						 const char *name)
2914{
2915	static char guid[] = { /*Declear frame based as H264 format*/
2916		'H',  '2',  '6',  '4', 0x00, 0x00, 0x10, 0x00,
2917		0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
2918	};
2919	struct uvcg_color_matching *color_match;
2920	struct config_item *streaming;
2921	struct uvcg_framebased *h;
2922
2923	streaming = group->cg_item.ci_parent;
2924	color_match = uvcg_format_get_default_color_match(streaming);
2925	if (!color_match)
2926		return ERR_PTR(-EINVAL);
2927
2928	h = kzalloc(sizeof(*h), GFP_KERNEL);
2929	if (!h)
2930		return ERR_PTR(-ENOMEM);
2931
2932	h->desc.bLength                 = UVC_DT_FORMAT_FRAMEBASED_SIZE;
2933	h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
2934	h->desc.bDescriptorSubType      = UVC_VS_FORMAT_FRAME_BASED;
2935	memcpy(h->desc.guidFormat, guid, sizeof(guid));
2936	h->desc.bBitsPerPixel           = 0;
2937	h->desc.bDefaultFrameIndex      = 1;
2938	h->desc.bAspectRatioX           = 0;
2939	h->desc.bAspectRatioY           = 0;
2940	h->desc.bmInterfaceFlags        = 0;
2941	h->desc.bCopyProtect            = 0;
2942	h->desc.bVariableSize           = 1;
2943
2944	INIT_LIST_HEAD(&h->fmt.frames);
2945	h->fmt.type = UVCG_FRAMEBASED;
2946
2947	h->fmt.color_matching = color_match;
2948	color_match->refcnt++;
2949	config_group_init_type_name(&h->fmt.group, name,
2950				    &uvcg_framebased_type);
2951
2952	return &h->fmt.group;
2953}
2954
2955static struct configfs_group_operations uvcg_framebased_grp_ops = {
2956	.make_group             = uvcg_framebased_make,
2957};
2958
2959static const struct uvcg_config_group_type uvcg_framebased_grp_type = {
2960	.type = {
2961		.ct_item_ops    = &uvcg_config_item_ops,
2962		.ct_group_ops   = &uvcg_framebased_grp_ops,
2963		.ct_owner       = THIS_MODULE,
2964	},
2965	.name = "framebased",
2966};
2967
2968/* -----------------------------------------------------------------------------
2969 * streaming/color_matching/default
2970 */
2971
2972#define UVCG_COLOR_MATCHING_ATTR(cname, aname, bits)			\
2973static ssize_t uvcg_color_matching_##cname##_show(			\
2974	struct config_item *item, char *page)				\
2975{									\
2976	struct config_group *group = to_config_group(item);		\
2977	struct uvcg_color_matching *color_match =			\
2978		to_uvcg_color_matching(group);				\
2979	struct f_uvc_opts *opts;					\
2980	struct config_item *opts_item;					\
2981	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
2982	int result;							\
2983									\
2984	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2985									\
2986	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
2987	opts = to_f_uvc_opts(opts_item);				\
2988									\
2989	mutex_lock(&opts->lock);					\
2990	result = sprintf(page, "%u\n",					\
2991			 le##bits##_to_cpu(color_match->desc.aname));	\
2992	mutex_unlock(&opts->lock);					\
2993									\
2994	mutex_unlock(su_mutex);						\
2995	return result;							\
2996}									\
2997									\
2998static ssize_t uvcg_color_matching_##cname##_store(			\
2999	struct config_item *item, const char *page, size_t len)		\
3000{									\
3001	struct config_group *group = to_config_group(item);		\
3002	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
3003	struct uvcg_color_matching *color_match =			\
3004		to_uvcg_color_matching(group);				\
3005	struct f_uvc_opts *opts;					\
3006	struct config_item *opts_item;					\
3007	int ret;							\
3008	u##bits num;							\
3009									\
3010	ret = kstrtou##bits(page, 0, &num);				\
3011	if (ret)							\
3012		return ret;						\
3013									\
3014	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
3015									\
3016	if (color_match->refcnt) {					\
3017		ret = -EBUSY;						\
3018		goto unlock_su;						\
3019	}								\
3020									\
3021	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
3022	opts = to_f_uvc_opts(opts_item);				\
3023									\
3024	mutex_lock(&opts->lock);					\
3025									\
3026	color_match->desc.aname = num;					\
3027	ret = len;							\
3028									\
3029	mutex_unlock(&opts->lock);					\
3030unlock_su:								\
3031	mutex_unlock(su_mutex);						\
3032									\
3033	return ret;							\
3034}									\
3035UVC_ATTR(uvcg_color_matching_, cname, aname)
3036
3037UVCG_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8);
3038UVCG_COLOR_MATCHING_ATTR(b_transfer_characteristics, bTransferCharacteristics, 8);
3039UVCG_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8);
3040
3041#undef UVCG_COLOR_MATCHING_ATTR
3042
3043static struct configfs_attribute *uvcg_color_matching_attrs[] = {
3044	&uvcg_color_matching_attr_b_color_primaries,
3045	&uvcg_color_matching_attr_b_transfer_characteristics,
3046	&uvcg_color_matching_attr_b_matrix_coefficients,
3047	NULL,
3048};
3049
3050static void uvcg_color_matching_release(struct config_item *item)
3051{
3052	struct uvcg_color_matching *color_match =
3053		to_uvcg_color_matching(to_config_group(item));
3054
3055	kfree(color_match);
3056}
3057
3058static struct configfs_item_operations uvcg_color_matching_item_ops = {
3059	.release	= uvcg_color_matching_release,
3060};
3061
3062static const struct config_item_type uvcg_color_matching_type = {
3063	.ct_item_ops	= &uvcg_color_matching_item_ops,
3064	.ct_attrs	= uvcg_color_matching_attrs,
3065	.ct_owner	= THIS_MODULE,
3066};
3067
3068/* -----------------------------------------------------------------------------
3069 * streaming/color_matching
3070 */
3071
3072static struct config_group *uvcg_color_matching_make(struct config_group *group,
3073						     const char *name)
3074{
3075	struct uvcg_color_matching *color_match;
3076
3077	color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
3078	if (!color_match)
3079		return ERR_PTR(-ENOMEM);
3080
3081	color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE;
3082	color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE;
3083	color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT;
3084
3085	config_group_init_type_name(&color_match->group, name,
3086				    &uvcg_color_matching_type);
3087
3088	return &color_match->group;
3089}
3090
3091static struct configfs_group_operations uvcg_color_matching_grp_group_ops = {
3092	.make_group	= uvcg_color_matching_make,
3093};
3094
3095static int uvcg_color_matching_create_children(struct config_group *parent)
3096{
3097	struct uvcg_color_matching *color_match;
3098
3099	color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
3100	if (!color_match)
3101		return -ENOMEM;
3102
3103	color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE;
3104	color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE;
3105	color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT;
3106	color_match->desc.bColorPrimaries = UVC_COLOR_PRIMARIES_BT_709_SRGB;
3107	color_match->desc.bTransferCharacteristics = UVC_TRANSFER_CHARACTERISTICS_BT_709;
3108	color_match->desc.bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS_SMPTE_170M;
3109
3110	config_group_init_type_name(&color_match->group, "default",
3111				    &uvcg_color_matching_type);
3112	configfs_add_default_group(&color_match->group, parent);
3113
3114	return 0;
3115}
3116
3117static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
3118	.type = {
3119		.ct_item_ops	= &uvcg_config_item_ops,
3120		.ct_group_ops	= &uvcg_color_matching_grp_group_ops,
3121		.ct_owner	= THIS_MODULE,
3122	},
3123	.name = "color_matching",
3124	.create_children = uvcg_color_matching_create_children,
3125};
3126
3127/* -----------------------------------------------------------------------------
3128 * streaming/class/{fs|hs|ss}
3129 */
3130
3131struct uvcg_streaming_class_group {
3132	struct config_group group;
3133	const char *name;
3134};
3135
3136static inline struct uvc_descriptor_header
3137***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
3138{
3139	struct uvcg_streaming_class_group *group =
3140		container_of(i, struct uvcg_streaming_class_group,
3141			     group.cg_item);
3142
3143	if (!strcmp(group->name, "fs"))
3144		return &o->uvc_fs_streaming_cls;
3145
3146	if (!strcmp(group->name, "hs"))
3147		return &o->uvc_hs_streaming_cls;
3148
3149	if (!strcmp(group->name, "ss"))
3150		return &o->uvc_ss_streaming_cls;
3151
3152	return NULL;
3153}
3154
3155enum uvcg_strm_type {
3156	UVCG_HEADER = 0,
3157	UVCG_FORMAT,
3158	UVCG_FRAME,
3159	UVCG_COLOR_MATCHING,
3160};
3161
3162/*
3163 * Iterate over a hierarchy of streaming descriptors' config items.
3164 * The items are created by the user with configfs.
3165 *
3166 * It "processes" the header pointed to by @priv1, then for each format
3167 * that follows the header "processes" the format itself and then for
3168 * each frame inside a format "processes" the frame.
3169 *
3170 * As a "processing" function the @fun is used.
3171 *
3172 * __uvcg_iter_strm_cls() is used in two context: first, to calculate
3173 * the amount of memory needed for an array of streaming descriptors
3174 * and second, to actually fill the array.
3175 *
3176 * @h: streaming header pointer
3177 * @priv2: an "inout" parameter (the caller might want to see the changes to it)
3178 * @priv3: an "inout" parameter (the caller might want to see the changes to it)
3179 * @fun: callback function for processing each level of the hierarchy
3180 */
3181static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
3182	void *priv2, void *priv3,
3183	int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
3184{
3185	struct uvcg_format_ptr *f;
3186	struct config_group *grp;
3187	struct config_item *item;
3188	struct uvcg_frame *frm;
3189	int ret, i, j;
3190
3191	if (!fun)
3192		return -EINVAL;
3193
3194	i = j = 0;
3195	ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
3196	if (ret)
3197		return ret;
3198	list_for_each_entry(f, &h->formats, entry) {
3199		ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
3200		if (ret)
3201			return ret;
3202		grp = &f->fmt->group;
3203		j = 0;
3204		list_for_each_entry(item, &grp->cg_children, ci_entry) {
3205			frm = to_uvcg_frame(item);
3206			ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
3207			if (ret)
3208				return ret;
3209		}
3210
3211		ret = fun(f->fmt->color_matching, priv2, priv3, 0,
3212			  UVCG_COLOR_MATCHING);
3213		if (ret)
3214			return ret;
3215	}
3216
3217	return ret;
3218}
3219
3220/*
3221 * Count how many bytes are needed for an array of streaming descriptors.
3222 *
3223 * @priv1: pointer to a header, format or frame
3224 * @priv2: inout parameter, accumulated size of the array
3225 * @priv3: inout parameter, accumulated number of the array elements
3226 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
3227 */
3228static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
3229			   enum uvcg_strm_type type)
3230{
3231	size_t *size = priv2;
3232	size_t *count = priv3;
3233
3234	switch (type) {
3235	case UVCG_HEADER: {
3236		struct uvcg_streaming_header *h = priv1;
3237
3238		*size += sizeof(h->desc);
3239		/* bmaControls */
3240		*size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
3241	}
3242	break;
3243	case UVCG_FORMAT: {
3244		struct uvcg_format *fmt = priv1;
3245
3246		if (fmt->type == UVCG_UNCOMPRESSED) {
3247			struct uvcg_uncompressed *u =
3248				container_of(fmt, struct uvcg_uncompressed,
3249					     fmt);
3250
3251			*size += sizeof(u->desc);
3252		} else if (fmt->type == UVCG_MJPEG) {
3253			struct uvcg_mjpeg *m =
3254				container_of(fmt, struct uvcg_mjpeg, fmt);
3255
3256			*size += sizeof(m->desc);
3257		} else if (fmt->type == UVCG_FRAMEBASED) {
3258			struct uvcg_framebased *f =
3259				container_of(fmt, struct uvcg_framebased, fmt);
3260
3261			*size += sizeof(f->desc);
3262		} else {
3263			return -EINVAL;
3264		}
3265	}
3266	break;
3267	case UVCG_FRAME: {
3268		struct uvcg_frame *frm = priv1;
3269		int sz = sizeof(frm->dw_frame_interval);
3270
3271		*size += sizeof(frm->frame);
3272		/*
3273		 * framebased has duplicate member with uncompressed and
3274		 * mjpeg, so minus it
3275		 */
3276		*size -= sizeof(u32);
3277		*size += frm->frame.b_frame_interval_type * sz;
3278	}
3279	break;
3280	case UVCG_COLOR_MATCHING: {
3281		struct uvcg_color_matching *color_match = priv1;
3282
3283		*size += sizeof(color_match->desc);
3284	}
3285	break;
3286	}
3287
3288	++*count;
3289
3290	return 0;
3291}
3292
3293static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm,
3294				       int sz)
3295{
3296	struct uvc_frame_framebased *desc = dest;
3297
3298	desc->bLength = frm->frame.b_length;
3299	desc->bDescriptorType = frm->frame.b_descriptor_type;
3300	desc->bDescriptorSubType = frm->frame.b_descriptor_subtype;
3301	desc->bFrameIndex = frm->frame.b_frame_index;
3302	desc->bmCapabilities = frm->frame.bm_capabilities;
3303	desc->wWidth = frm->frame.w_width;
3304	desc->wHeight = frm->frame.w_height;
3305	desc->dwMinBitRate = frm->frame.dw_min_bit_rate;
3306	desc->dwMaxBitRate = frm->frame.dw_max_bit_rate;
3307	desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval;
3308	desc->bFrameIntervalType = frm->frame.b_frame_interval_type;
3309	desc->dwBytesPerLine = frm->frame.dw_bytes_perline;
3310
3311	return 0;
3312}
3313
3314/*
3315 * Fill an array of streaming descriptors.
3316 *
3317 * @priv1: pointer to a header, format or frame
3318 * @priv2: inout parameter, pointer into a block of memory
3319 * @priv3: inout parameter, pointer to a 2-dimensional array
3320 */
3321static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
3322			    enum uvcg_strm_type type)
3323{
3324	void **dest = priv2;
3325	struct uvc_descriptor_header ***array = priv3;
3326	size_t sz;
3327
3328	**array = *dest;
3329	++*array;
3330
3331	switch (type) {
3332	case UVCG_HEADER: {
3333		struct uvc_input_header_descriptor *ihdr = *dest;
3334		struct uvcg_streaming_header *h = priv1;
3335		struct uvcg_format_ptr *f;
3336
3337		memcpy(*dest, &h->desc, sizeof(h->desc));
3338		*dest += sizeof(h->desc);
3339		sz = UVCG_STREAMING_CONTROL_SIZE;
3340		list_for_each_entry(f, &h->formats, entry) {
3341			memcpy(*dest, f->fmt->bmaControls, sz);
3342			*dest += sz;
3343		}
3344		ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
3345		ihdr->bNumFormats = h->num_fmt;
3346	}
3347	break;
3348	case UVCG_FORMAT: {
3349		struct uvcg_format *fmt = priv1;
3350
3351		if (fmt->type == UVCG_UNCOMPRESSED) {
3352			struct uvcg_uncompressed *u =
3353				container_of(fmt, struct uvcg_uncompressed,
3354					     fmt);
3355
3356			u->desc.bFormatIndex = n + 1;
3357			u->desc.bNumFrameDescriptors = fmt->num_frames;
3358			memcpy(*dest, &u->desc, sizeof(u->desc));
3359			*dest += sizeof(u->desc);
3360		} else if (fmt->type == UVCG_MJPEG) {
3361			struct uvcg_mjpeg *m =
3362				container_of(fmt, struct uvcg_mjpeg, fmt);
3363
3364			m->desc.bFormatIndex = n + 1;
3365			m->desc.bNumFrameDescriptors = fmt->num_frames;
3366			memcpy(*dest, &m->desc, sizeof(m->desc));
3367			*dest += sizeof(m->desc);
3368		} else if (fmt->type == UVCG_FRAMEBASED) {
3369			struct uvcg_framebased *f =
3370				container_of(fmt, struct uvcg_framebased,
3371					     fmt);
3372
3373			f->desc.bFormatIndex = n + 1;
3374			f->desc.bNumFrameDescriptors = fmt->num_frames;
3375			memcpy(*dest, &f->desc, sizeof(f->desc));
3376			*dest += sizeof(f->desc);
3377		} else {
3378			return -EINVAL;
3379		}
3380	}
3381	break;
3382	case UVCG_FRAME: {
3383		struct uvcg_frame *frm = priv1;
3384		struct uvc_descriptor_header *h = *dest;
3385
3386		sz = sizeof(frm->frame) - 4;
3387		if (frm->fmt_type != UVCG_FRAMEBASED)
3388			memcpy(*dest, &frm->frame, sz);
3389		else
3390			__uvcg_copy_framebased_desc(*dest, frm, sz);
3391		*dest += sz;
3392		sz = frm->frame.b_frame_interval_type *
3393			sizeof(*frm->dw_frame_interval);
3394		memcpy(*dest, frm->dw_frame_interval, sz);
3395		*dest += sz;
3396		if (frm->fmt_type == UVCG_UNCOMPRESSED)
3397			h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
3398				frm->frame.b_frame_interval_type);
3399		else if (frm->fmt_type == UVCG_MJPEG)
3400			h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
3401					frm->frame.b_frame_interval_type);
3402		else if (frm->fmt_type == UVCG_FRAMEBASED)
3403			h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE(
3404					frm->frame.b_frame_interval_type);
3405	}
3406	break;
3407	case UVCG_COLOR_MATCHING: {
3408		struct uvcg_color_matching *color_match = priv1;
3409
3410		memcpy(*dest, &color_match->desc, sizeof(color_match->desc));
3411		*dest += sizeof(color_match->desc);
3412	}
3413	break;
3414	}
3415
3416	return 0;
3417}
3418
3419static int uvcg_streaming_class_allow_link(struct config_item *src,
3420					   struct config_item *target)
3421{
3422	struct config_item *streaming, *header;
3423	struct f_uvc_opts *opts;
3424	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3425	struct uvc_descriptor_header ***class_array, **cl_arr;
3426	struct uvcg_streaming_header *target_hdr;
3427	void *data, *data_save;
3428	size_t size = 0, count = 0;
3429	int ret = -EINVAL;
3430
3431	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3432
3433	streaming = src->ci_parent->ci_parent;
3434	header = config_group_find_item(to_config_group(streaming), "header");
3435	if (!header || target->ci_parent != header)
3436		goto out;
3437
3438	opts = to_f_uvc_opts(streaming->ci_parent);
3439
3440	mutex_lock(&opts->lock);
3441
3442	class_array = __uvcg_get_stream_class_arr(src, opts);
3443	if (!class_array || *class_array || opts->refcnt) {
3444		ret = -EBUSY;
3445		goto unlock;
3446	}
3447
3448	target_hdr = to_uvcg_streaming_header(target);
3449	ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
3450	if (ret)
3451		goto unlock;
3452
3453	count += 1; /* NULL */
3454	*class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
3455	if (!*class_array) {
3456		ret = -ENOMEM;
3457		goto unlock;
3458	}
3459
3460	data = data_save = kzalloc(size, GFP_KERNEL);
3461	if (!data) {
3462		kfree(*class_array);
3463		*class_array = NULL;
3464		ret = -ENOMEM;
3465		goto unlock;
3466	}
3467	cl_arr = *class_array;
3468	ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
3469				   __uvcg_fill_strm);
3470	if (ret) {
3471		kfree(*class_array);
3472		*class_array = NULL;
3473		/*
3474		 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
3475		 * might have advanced the "data", so use a backup copy
3476		 */
3477		kfree(data_save);
3478		goto unlock;
3479	}
3480
3481	++target_hdr->linked;
3482	ret = 0;
3483
3484unlock:
3485	mutex_unlock(&opts->lock);
3486out:
3487	config_item_put(header);
3488	mutex_unlock(su_mutex);
3489	return ret;
3490}
3491
3492static void uvcg_streaming_class_drop_link(struct config_item *src,
3493					  struct config_item *target)
3494{
3495	struct config_item *streaming, *header;
3496	struct f_uvc_opts *opts;
3497	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3498	struct uvc_descriptor_header ***class_array;
3499	struct uvcg_streaming_header *target_hdr;
3500
3501	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3502
3503	streaming = src->ci_parent->ci_parent;
3504	header = config_group_find_item(to_config_group(streaming), "header");
3505	if (!header || target->ci_parent != header)
3506		goto out;
3507
3508	opts = to_f_uvc_opts(streaming->ci_parent);
3509
3510	mutex_lock(&opts->lock);
3511
3512	class_array = __uvcg_get_stream_class_arr(src, opts);
3513	if (!class_array || !*class_array)
3514		goto unlock;
3515
3516	if (opts->refcnt)
3517		goto unlock;
3518
3519	target_hdr = to_uvcg_streaming_header(target);
3520	--target_hdr->linked;
3521	kfree(**class_array);
3522	kfree(*class_array);
3523	*class_array = NULL;
3524
3525unlock:
3526	mutex_unlock(&opts->lock);
3527out:
3528	config_item_put(header);
3529	mutex_unlock(su_mutex);
3530}
3531
3532static struct configfs_item_operations uvcg_streaming_class_item_ops = {
3533	.release	= uvcg_config_item_release,
3534	.allow_link	= uvcg_streaming_class_allow_link,
3535	.drop_link	= uvcg_streaming_class_drop_link,
3536};
3537
3538static const struct config_item_type uvcg_streaming_class_type = {
3539	.ct_item_ops	= &uvcg_streaming_class_item_ops,
3540	.ct_owner	= THIS_MODULE,
3541};
3542
3543/* -----------------------------------------------------------------------------
3544 * streaming/class
3545 */
3546
3547static int uvcg_streaming_class_create_children(struct config_group *parent)
3548{
3549	static const char * const names[] = { "fs", "hs", "ss" };
3550	unsigned int i;
3551
3552	for (i = 0; i < ARRAY_SIZE(names); ++i) {
3553		struct uvcg_streaming_class_group *group;
3554
3555		group = kzalloc(sizeof(*group), GFP_KERNEL);
3556		if (!group)
3557			return -ENOMEM;
3558
3559		group->name = names[i];
3560
3561		config_group_init_type_name(&group->group, group->name,
3562					    &uvcg_streaming_class_type);
3563		configfs_add_default_group(&group->group, parent);
3564	}
3565
3566	return 0;
3567}
3568
3569static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = {
3570	.type = {
3571		.ct_item_ops	= &uvcg_config_item_ops,
3572		.ct_owner	= THIS_MODULE,
3573	},
3574	.name = "class",
3575	.create_children = uvcg_streaming_class_create_children,
3576};
3577
3578/* -----------------------------------------------------------------------------
3579 * streaming
3580 */
3581
3582static ssize_t uvcg_default_streaming_b_interface_number_show(
3583	struct config_item *item, char *page)
3584{
3585	struct config_group *group = to_config_group(item);
3586	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
3587	struct config_item *opts_item;
3588	struct f_uvc_opts *opts;
3589	int result = 0;
3590
3591	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3592
3593	opts_item = item->ci_parent;
3594	opts = to_f_uvc_opts(opts_item);
3595
3596	mutex_lock(&opts->lock);
3597	result += sprintf(page, "%u\n", opts->streaming_interface);
3598	mutex_unlock(&opts->lock);
3599
3600	mutex_unlock(su_mutex);
3601
3602	return result;
3603}
3604
3605UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber);
3606
3607static struct configfs_attribute *uvcg_default_streaming_attrs[] = {
3608	&uvcg_default_streaming_attr_b_interface_number,
3609	NULL,
3610};
3611
3612static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
3613	.type = {
3614		.ct_item_ops	= &uvcg_config_item_ops,
3615		.ct_attrs	= uvcg_default_streaming_attrs,
3616		.ct_owner	= THIS_MODULE,
3617	},
3618	.name = "streaming",
3619	.children = (const struct uvcg_config_group_type*[]) {
3620		&uvcg_streaming_header_grp_type,
3621		&uvcg_uncompressed_grp_type,
3622		&uvcg_mjpeg_grp_type,
3623		&uvcg_framebased_grp_type,
3624		&uvcg_color_matching_grp_type,
3625		&uvcg_streaming_class_grp_type,
3626		NULL,
3627	},
3628};
3629
3630/* -----------------------------------------------------------------------------
3631 * UVC function
3632 */
3633
3634static void uvc_func_item_release(struct config_item *item)
3635{
3636	struct f_uvc_opts *opts = to_f_uvc_opts(item);
3637
3638	uvcg_config_remove_children(to_config_group(item));
3639	usb_put_function_instance(&opts->func_inst);
3640}
3641
3642static int uvc_func_allow_link(struct config_item *src, struct config_item *tgt)
3643{
3644	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3645	struct gadget_string *string;
3646	struct config_item *strings;
3647	struct f_uvc_opts *opts;
3648	int ret = 0;
3649
3650	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3651
3652	/* Validate that the target is an entry in strings/<langid> */
3653	strings = config_group_find_item(to_config_group(src->ci_parent->ci_parent),
3654					 "strings");
3655	if (!strings || tgt->ci_parent->ci_parent != strings) {
3656		ret = -EINVAL;
3657		goto put_strings;
3658	}
3659
3660	string = to_gadget_string(tgt);
3661
3662	opts = to_f_uvc_opts(src);
3663	mutex_lock(&opts->lock);
3664
3665	if (!strcmp(tgt->ci_name, "iad_desc"))
3666		opts->iad_index = string->usb_string.id;
3667	else if (!strcmp(tgt->ci_name, "vs0_desc"))
3668		opts->vs0_index = string->usb_string.id;
3669	else if (!strcmp(tgt->ci_name, "vs1_desc"))
3670		opts->vs1_index = string->usb_string.id;
3671	else
3672		ret = -EINVAL;
3673
3674	mutex_unlock(&opts->lock);
3675
3676put_strings:
3677	config_item_put(strings);
3678	mutex_unlock(su_mutex);
3679
3680	return ret;
3681}
3682
3683static void uvc_func_drop_link(struct config_item *src, struct config_item *tgt)
3684{
3685	struct f_uvc_opts *opts;
3686
3687	opts = to_f_uvc_opts(src);
3688	mutex_lock(&opts->lock);
3689
3690	if (!strcmp(tgt->ci_name, "iad_desc"))
3691		opts->iad_index = 0;
3692	else if (!strcmp(tgt->ci_name, "vs0_desc"))
3693		opts->vs0_index = 0;
3694	else if (!strcmp(tgt->ci_name, "vs1_desc"))
3695		opts->vs1_index = 0;
3696
3697	mutex_unlock(&opts->lock);
3698}
3699
3700static struct configfs_item_operations uvc_func_item_ops = {
3701	.release	= uvc_func_item_release,
3702	.allow_link	= uvc_func_allow_link,
3703	.drop_link	= uvc_func_drop_link,
3704};
3705
3706#define UVCG_OPTS_ATTR(cname, aname, limit)				\
3707static ssize_t f_uvc_opts_##cname##_show(				\
3708	struct config_item *item, char *page)				\
3709{									\
3710	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3711	int result;							\
3712									\
3713	mutex_lock(&opts->lock);					\
3714	result = sprintf(page, "%u\n", opts->cname);			\
3715	mutex_unlock(&opts->lock);					\
3716									\
3717	return result;							\
3718}									\
3719									\
3720static ssize_t								\
3721f_uvc_opts_##cname##_store(struct config_item *item,			\
3722			   const char *page, size_t len)		\
3723{									\
3724	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3725	unsigned int num;						\
3726	int ret;							\
3727									\
3728	mutex_lock(&opts->lock);					\
3729	if (opts->refcnt) {						\
3730		ret = -EBUSY;						\
3731		goto end;						\
3732	}								\
3733									\
3734	ret = kstrtouint(page, 0, &num);				\
3735	if (ret)							\
3736		goto end;						\
3737									\
3738	if (num > limit) {						\
3739		ret = -EINVAL;						\
3740		goto end;						\
3741	}								\
3742	opts->cname = num;						\
3743	ret = len;							\
3744end:									\
3745	mutex_unlock(&opts->lock);					\
3746	return ret;							\
3747}									\
3748									\
3749UVC_ATTR(f_uvc_opts_, cname, cname)
3750
3751UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
3752UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
3753UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
3754
3755#undef UVCG_OPTS_ATTR
3756
3757#define UVCG_OPTS_STRING_ATTR(cname, aname)				\
3758static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\
3759					 char *page)			\
3760{									\
3761	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3762	int result;							\
3763									\
3764	mutex_lock(&opts->lock);					\
3765	result = scnprintf(page, sizeof(opts->aname), "%s", opts->aname);\
3766	mutex_unlock(&opts->lock);					\
3767									\
3768	return result;							\
3769}									\
3770									\
3771static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\
3772					  const char *page, size_t len)	\
3773{									\
3774	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3775	int size = min(sizeof(opts->aname), len + 1);			\
3776	int ret = 0;							\
3777									\
3778	mutex_lock(&opts->lock);					\
3779	if (opts->refcnt) {						\
3780		ret = -EBUSY;						\
3781		goto end;						\
3782	}								\
3783									\
3784	ret = strscpy(opts->aname, page, size);				\
3785	if (ret == -E2BIG)						\
3786		ret = size - 1;						\
3787									\
3788end:									\
3789	mutex_unlock(&opts->lock);					\
3790	return ret;							\
3791}									\
3792									\
3793UVC_ATTR(f_uvc_opts_string_, cname, aname)
3794
3795UVCG_OPTS_STRING_ATTR(function_name, function_name);
3796
3797#undef UVCG_OPTS_STRING_ATTR
3798
3799static struct configfs_attribute *uvc_attrs[] = {
3800	&f_uvc_opts_attr_streaming_interval,
3801	&f_uvc_opts_attr_streaming_maxpacket,
3802	&f_uvc_opts_attr_streaming_maxburst,
3803	&f_uvc_opts_string_attr_function_name,
3804	NULL,
3805};
3806
3807static const struct uvcg_config_group_type uvc_func_type = {
3808	.type = {
3809		.ct_item_ops	= &uvc_func_item_ops,
3810		.ct_attrs	= uvc_attrs,
3811		.ct_owner	= THIS_MODULE,
3812	},
3813	.name = "",
3814	.children = (const struct uvcg_config_group_type*[]) {
3815		&uvcg_control_grp_type,
3816		&uvcg_streaming_grp_type,
3817		NULL,
3818	},
3819};
3820
3821int uvcg_attach_configfs(struct f_uvc_opts *opts)
3822{
3823	int ret;
3824
3825	config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
3826				    &uvc_func_type.type);
3827
3828	ret = uvcg_config_create_children(&opts->func_inst.group,
3829					  &uvc_func_type);
3830	if (ret < 0)
3831		config_group_put(&opts->func_inst.group);
3832
3833	return ret;
3834}
~/ Read-only file preview.