Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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_framebased *h;
2920
2921	h = kzalloc(sizeof(*h), GFP_KERNEL);
2922	if (!h)
2923		return ERR_PTR(-ENOMEM);
2924
2925	h->desc.bLength                 = UVC_DT_FORMAT_FRAMEBASED_SIZE;
2926	h->desc.bDescriptorType         = USB_DT_CS_INTERFACE;
2927	h->desc.bDescriptorSubType      = UVC_VS_FORMAT_FRAME_BASED;
2928	memcpy(h->desc.guidFormat, guid, sizeof(guid));
2929	h->desc.bBitsPerPixel           = 0;
2930	h->desc.bDefaultFrameIndex      = 1;
2931	h->desc.bAspectRatioX           = 0;
2932	h->desc.bAspectRatioY           = 0;
2933	h->desc.bmInterfaceFlags        = 0;
2934	h->desc.bCopyProtect            = 0;
2935	h->desc.bVariableSize           = 1;
2936
2937	INIT_LIST_HEAD(&h->fmt.frames);
2938	h->fmt.type = UVCG_FRAMEBASED;
2939	config_group_init_type_name(&h->fmt.group, name,
2940				    &uvcg_framebased_type);
2941
2942	return &h->fmt.group;
2943}
2944
2945static struct configfs_group_operations uvcg_framebased_grp_ops = {
2946	.make_group             = uvcg_framebased_make,
2947};
2948
2949static const struct uvcg_config_group_type uvcg_framebased_grp_type = {
2950	.type = {
2951		.ct_item_ops    = &uvcg_config_item_ops,
2952		.ct_group_ops   = &uvcg_framebased_grp_ops,
2953		.ct_owner       = THIS_MODULE,
2954	},
2955	.name = "framebased",
2956};
2957
2958/* -----------------------------------------------------------------------------
2959 * streaming/color_matching/default
2960 */
2961
2962#define UVCG_COLOR_MATCHING_ATTR(cname, aname, bits)			\
2963static ssize_t uvcg_color_matching_##cname##_show(			\
2964	struct config_item *item, char *page)				\
2965{									\
2966	struct config_group *group = to_config_group(item);		\
2967	struct uvcg_color_matching *color_match =			\
2968		to_uvcg_color_matching(group);				\
2969	struct f_uvc_opts *opts;					\
2970	struct config_item *opts_item;					\
2971	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
2972	int result;							\
2973									\
2974	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
2975									\
2976	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
2977	opts = to_f_uvc_opts(opts_item);				\
2978									\
2979	mutex_lock(&opts->lock);					\
2980	result = sprintf(page, "%u\n",					\
2981			 le##bits##_to_cpu(color_match->desc.aname));	\
2982	mutex_unlock(&opts->lock);					\
2983									\
2984	mutex_unlock(su_mutex);						\
2985	return result;							\
2986}									\
2987									\
2988static ssize_t uvcg_color_matching_##cname##_store(			\
2989	struct config_item *item, const char *page, size_t len)		\
2990{									\
2991	struct config_group *group = to_config_group(item);		\
2992	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
2993	struct uvcg_color_matching *color_match =			\
2994		to_uvcg_color_matching(group);				\
2995	struct f_uvc_opts *opts;					\
2996	struct config_item *opts_item;					\
2997	int ret;							\
2998	u##bits num;							\
2999									\
3000	ret = kstrtou##bits(page, 0, &num);				\
3001	if (ret)							\
3002		return ret;						\
3003									\
3004	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
3005									\
3006	if (color_match->refcnt) {					\
3007		ret = -EBUSY;						\
3008		goto unlock_su;						\
3009	}								\
3010									\
3011	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
3012	opts = to_f_uvc_opts(opts_item);				\
3013									\
3014	mutex_lock(&opts->lock);					\
3015									\
3016	color_match->desc.aname = num;					\
3017	ret = len;							\
3018									\
3019	mutex_unlock(&opts->lock);					\
3020unlock_su:								\
3021	mutex_unlock(su_mutex);						\
3022									\
3023	return ret;							\
3024}									\
3025UVC_ATTR(uvcg_color_matching_, cname, aname)
3026
3027UVCG_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8);
3028UVCG_COLOR_MATCHING_ATTR(b_transfer_characteristics, bTransferCharacteristics, 8);
3029UVCG_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8);
3030
3031#undef UVCG_COLOR_MATCHING_ATTR
3032
3033static struct configfs_attribute *uvcg_color_matching_attrs[] = {
3034	&uvcg_color_matching_attr_b_color_primaries,
3035	&uvcg_color_matching_attr_b_transfer_characteristics,
3036	&uvcg_color_matching_attr_b_matrix_coefficients,
3037	NULL,
3038};
3039
3040static void uvcg_color_matching_release(struct config_item *item)
3041{
3042	struct uvcg_color_matching *color_match =
3043		to_uvcg_color_matching(to_config_group(item));
3044
3045	kfree(color_match);
3046}
3047
3048static struct configfs_item_operations uvcg_color_matching_item_ops = {
3049	.release	= uvcg_color_matching_release,
3050};
3051
3052static const struct config_item_type uvcg_color_matching_type = {
3053	.ct_item_ops	= &uvcg_color_matching_item_ops,
3054	.ct_attrs	= uvcg_color_matching_attrs,
3055	.ct_owner	= THIS_MODULE,
3056};
3057
3058/* -----------------------------------------------------------------------------
3059 * streaming/color_matching
3060 */
3061
3062static struct config_group *uvcg_color_matching_make(struct config_group *group,
3063						     const char *name)
3064{
3065	struct uvcg_color_matching *color_match;
3066
3067	color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
3068	if (!color_match)
3069		return ERR_PTR(-ENOMEM);
3070
3071	color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE;
3072	color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE;
3073	color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT;
3074
3075	config_group_init_type_name(&color_match->group, name,
3076				    &uvcg_color_matching_type);
3077
3078	return &color_match->group;
3079}
3080
3081static struct configfs_group_operations uvcg_color_matching_grp_group_ops = {
3082	.make_group	= uvcg_color_matching_make,
3083};
3084
3085static int uvcg_color_matching_create_children(struct config_group *parent)
3086{
3087	struct uvcg_color_matching *color_match;
3088
3089	color_match = kzalloc(sizeof(*color_match), GFP_KERNEL);
3090	if (!color_match)
3091		return -ENOMEM;
3092
3093	color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE;
3094	color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE;
3095	color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT;
3096	color_match->desc.bColorPrimaries = UVC_COLOR_PRIMARIES_BT_709_SRGB;
3097	color_match->desc.bTransferCharacteristics = UVC_TRANSFER_CHARACTERISTICS_BT_709;
3098	color_match->desc.bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS_SMPTE_170M;
3099
3100	config_group_init_type_name(&color_match->group, "default",
3101				    &uvcg_color_matching_type);
3102	configfs_add_default_group(&color_match->group, parent);
3103
3104	return 0;
3105}
3106
3107static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
3108	.type = {
3109		.ct_item_ops	= &uvcg_config_item_ops,
3110		.ct_group_ops	= &uvcg_color_matching_grp_group_ops,
3111		.ct_owner	= THIS_MODULE,
3112	},
3113	.name = "color_matching",
3114	.create_children = uvcg_color_matching_create_children,
3115};
3116
3117/* -----------------------------------------------------------------------------
3118 * streaming/class/{fs|hs|ss}
3119 */
3120
3121struct uvcg_streaming_class_group {
3122	struct config_group group;
3123	const char *name;
3124};
3125
3126static inline struct uvc_descriptor_header
3127***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
3128{
3129	struct uvcg_streaming_class_group *group =
3130		container_of(i, struct uvcg_streaming_class_group,
3131			     group.cg_item);
3132
3133	if (!strcmp(group->name, "fs"))
3134		return &o->uvc_fs_streaming_cls;
3135
3136	if (!strcmp(group->name, "hs"))
3137		return &o->uvc_hs_streaming_cls;
3138
3139	if (!strcmp(group->name, "ss"))
3140		return &o->uvc_ss_streaming_cls;
3141
3142	return NULL;
3143}
3144
3145enum uvcg_strm_type {
3146	UVCG_HEADER = 0,
3147	UVCG_FORMAT,
3148	UVCG_FRAME,
3149	UVCG_COLOR_MATCHING,
3150};
3151
3152/*
3153 * Iterate over a hierarchy of streaming descriptors' config items.
3154 * The items are created by the user with configfs.
3155 *
3156 * It "processes" the header pointed to by @priv1, then for each format
3157 * that follows the header "processes" the format itself and then for
3158 * each frame inside a format "processes" the frame.
3159 *
3160 * As a "processing" function the @fun is used.
3161 *
3162 * __uvcg_iter_strm_cls() is used in two context: first, to calculate
3163 * the amount of memory needed for an array of streaming descriptors
3164 * and second, to actually fill the array.
3165 *
3166 * @h: streaming header pointer
3167 * @priv2: an "inout" parameter (the caller might want to see the changes to it)
3168 * @priv3: an "inout" parameter (the caller might want to see the changes to it)
3169 * @fun: callback function for processing each level of the hierarchy
3170 */
3171static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
3172	void *priv2, void *priv3,
3173	int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
3174{
3175	struct uvcg_format_ptr *f;
3176	struct config_group *grp;
3177	struct config_item *item;
3178	struct uvcg_frame *frm;
3179	int ret, i, j;
3180
3181	if (!fun)
3182		return -EINVAL;
3183
3184	i = j = 0;
3185	ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
3186	if (ret)
3187		return ret;
3188	list_for_each_entry(f, &h->formats, entry) {
3189		ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
3190		if (ret)
3191			return ret;
3192		grp = &f->fmt->group;
3193		j = 0;
3194		list_for_each_entry(item, &grp->cg_children, ci_entry) {
3195			frm = to_uvcg_frame(item);
3196			ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
3197			if (ret)
3198				return ret;
3199		}
3200
3201		ret = fun(f->fmt->color_matching, priv2, priv3, 0,
3202			  UVCG_COLOR_MATCHING);
3203		if (ret)
3204			return ret;
3205	}
3206
3207	return ret;
3208}
3209
3210/*
3211 * Count how many bytes are needed for an array of streaming descriptors.
3212 *
3213 * @priv1: pointer to a header, format or frame
3214 * @priv2: inout parameter, accumulated size of the array
3215 * @priv3: inout parameter, accumulated number of the array elements
3216 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
3217 */
3218static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
3219			   enum uvcg_strm_type type)
3220{
3221	size_t *size = priv2;
3222	size_t *count = priv3;
3223
3224	switch (type) {
3225	case UVCG_HEADER: {
3226		struct uvcg_streaming_header *h = priv1;
3227
3228		*size += sizeof(h->desc);
3229		/* bmaControls */
3230		*size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
3231	}
3232	break;
3233	case UVCG_FORMAT: {
3234		struct uvcg_format *fmt = priv1;
3235
3236		if (fmt->type == UVCG_UNCOMPRESSED) {
3237			struct uvcg_uncompressed *u =
3238				container_of(fmt, struct uvcg_uncompressed,
3239					     fmt);
3240
3241			*size += sizeof(u->desc);
3242		} else if (fmt->type == UVCG_MJPEG) {
3243			struct uvcg_mjpeg *m =
3244				container_of(fmt, struct uvcg_mjpeg, fmt);
3245
3246			*size += sizeof(m->desc);
3247		} else if (fmt->type == UVCG_FRAMEBASED) {
3248			struct uvcg_framebased *f =
3249				container_of(fmt, struct uvcg_framebased, fmt);
3250
3251			*size += sizeof(f->desc);
3252		} else {
3253			return -EINVAL;
3254		}
3255	}
3256	break;
3257	case UVCG_FRAME: {
3258		struct uvcg_frame *frm = priv1;
3259		int sz = sizeof(frm->dw_frame_interval);
3260
3261		*size += sizeof(frm->frame);
3262		/*
3263		 * framebased has duplicate member with uncompressed and
3264		 * mjpeg, so minus it
3265		 */
3266		*size -= sizeof(u32);
3267		*size += frm->frame.b_frame_interval_type * sz;
3268	}
3269	break;
3270	case UVCG_COLOR_MATCHING: {
3271		struct uvcg_color_matching *color_match = priv1;
3272
3273		*size += sizeof(color_match->desc);
3274	}
3275	break;
3276	}
3277
3278	++*count;
3279
3280	return 0;
3281}
3282
3283static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm,
3284				       int sz)
3285{
3286	struct uvc_frame_framebased *desc = dest;
3287
3288	desc->bLength = frm->frame.b_length;
3289	desc->bDescriptorType = frm->frame.b_descriptor_type;
3290	desc->bDescriptorSubType = frm->frame.b_descriptor_subtype;
3291	desc->bFrameIndex = frm->frame.b_frame_index;
3292	desc->bmCapabilities = frm->frame.bm_capabilities;
3293	desc->wWidth = frm->frame.w_width;
3294	desc->wHeight = frm->frame.w_height;
3295	desc->dwMinBitRate = frm->frame.dw_min_bit_rate;
3296	desc->dwMaxBitRate = frm->frame.dw_max_bit_rate;
3297	desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval;
3298	desc->bFrameIntervalType = frm->frame.b_frame_interval_type;
3299	desc->dwBytesPerLine = frm->frame.dw_bytes_perline;
3300
3301	return 0;
3302}
3303
3304/*
3305 * Fill an array of streaming descriptors.
3306 *
3307 * @priv1: pointer to a header, format or frame
3308 * @priv2: inout parameter, pointer into a block of memory
3309 * @priv3: inout parameter, pointer to a 2-dimensional array
3310 */
3311static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
3312			    enum uvcg_strm_type type)
3313{
3314	void **dest = priv2;
3315	struct uvc_descriptor_header ***array = priv3;
3316	size_t sz;
3317
3318	**array = *dest;
3319	++*array;
3320
3321	switch (type) {
3322	case UVCG_HEADER: {
3323		struct uvc_input_header_descriptor *ihdr = *dest;
3324		struct uvcg_streaming_header *h = priv1;
3325		struct uvcg_format_ptr *f;
3326
3327		memcpy(*dest, &h->desc, sizeof(h->desc));
3328		*dest += sizeof(h->desc);
3329		sz = UVCG_STREAMING_CONTROL_SIZE;
3330		list_for_each_entry(f, &h->formats, entry) {
3331			memcpy(*dest, f->fmt->bmaControls, sz);
3332			*dest += sz;
3333		}
3334		ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
3335		ihdr->bNumFormats = h->num_fmt;
3336	}
3337	break;
3338	case UVCG_FORMAT: {
3339		struct uvcg_format *fmt = priv1;
3340
3341		if (fmt->type == UVCG_UNCOMPRESSED) {
3342			struct uvcg_uncompressed *u =
3343				container_of(fmt, struct uvcg_uncompressed,
3344					     fmt);
3345
3346			u->desc.bFormatIndex = n + 1;
3347			u->desc.bNumFrameDescriptors = fmt->num_frames;
3348			memcpy(*dest, &u->desc, sizeof(u->desc));
3349			*dest += sizeof(u->desc);
3350		} else if (fmt->type == UVCG_MJPEG) {
3351			struct uvcg_mjpeg *m =
3352				container_of(fmt, struct uvcg_mjpeg, fmt);
3353
3354			m->desc.bFormatIndex = n + 1;
3355			m->desc.bNumFrameDescriptors = fmt->num_frames;
3356			memcpy(*dest, &m->desc, sizeof(m->desc));
3357			*dest += sizeof(m->desc);
3358		} else if (fmt->type == UVCG_FRAMEBASED) {
3359			struct uvcg_framebased *f =
3360				container_of(fmt, struct uvcg_framebased,
3361					     fmt);
3362
3363			f->desc.bFormatIndex = n + 1;
3364			f->desc.bNumFrameDescriptors = fmt->num_frames;
3365			memcpy(*dest, &f->desc, sizeof(f->desc));
3366			*dest += sizeof(f->desc);
3367		} else {
3368			return -EINVAL;
3369		}
3370	}
3371	break;
3372	case UVCG_FRAME: {
3373		struct uvcg_frame *frm = priv1;
3374		struct uvc_descriptor_header *h = *dest;
3375
3376		sz = sizeof(frm->frame) - 4;
3377		if (frm->fmt_type != UVCG_FRAMEBASED)
3378			memcpy(*dest, &frm->frame, sz);
3379		else
3380			__uvcg_copy_framebased_desc(*dest, frm, sz);
3381		*dest += sz;
3382		sz = frm->frame.b_frame_interval_type *
3383			sizeof(*frm->dw_frame_interval);
3384		memcpy(*dest, frm->dw_frame_interval, sz);
3385		*dest += sz;
3386		if (frm->fmt_type == UVCG_UNCOMPRESSED)
3387			h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
3388				frm->frame.b_frame_interval_type);
3389		else if (frm->fmt_type == UVCG_MJPEG)
3390			h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
3391					frm->frame.b_frame_interval_type);
3392		else if (frm->fmt_type == UVCG_FRAMEBASED)
3393			h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE(
3394					frm->frame.b_frame_interval_type);
3395	}
3396	break;
3397	case UVCG_COLOR_MATCHING: {
3398		struct uvcg_color_matching *color_match = priv1;
3399
3400		memcpy(*dest, &color_match->desc, sizeof(color_match->desc));
3401		*dest += sizeof(color_match->desc);
3402	}
3403	break;
3404	}
3405
3406	return 0;
3407}
3408
3409static int uvcg_streaming_class_allow_link(struct config_item *src,
3410					   struct config_item *target)
3411{
3412	struct config_item *streaming, *header;
3413	struct f_uvc_opts *opts;
3414	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3415	struct uvc_descriptor_header ***class_array, **cl_arr;
3416	struct uvcg_streaming_header *target_hdr;
3417	void *data, *data_save;
3418	size_t size = 0, count = 0;
3419	int ret = -EINVAL;
3420
3421	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3422
3423	streaming = src->ci_parent->ci_parent;
3424	header = config_group_find_item(to_config_group(streaming), "header");
3425	if (!header || target->ci_parent != header)
3426		goto out;
3427
3428	opts = to_f_uvc_opts(streaming->ci_parent);
3429
3430	mutex_lock(&opts->lock);
3431
3432	class_array = __uvcg_get_stream_class_arr(src, opts);
3433	if (!class_array || *class_array || opts->refcnt) {
3434		ret = -EBUSY;
3435		goto unlock;
3436	}
3437
3438	target_hdr = to_uvcg_streaming_header(target);
3439	ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
3440	if (ret)
3441		goto unlock;
3442
3443	count += 1; /* NULL */
3444	*class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
3445	if (!*class_array) {
3446		ret = -ENOMEM;
3447		goto unlock;
3448	}
3449
3450	data = data_save = kzalloc(size, GFP_KERNEL);
3451	if (!data) {
3452		kfree(*class_array);
3453		*class_array = NULL;
3454		ret = -ENOMEM;
3455		goto unlock;
3456	}
3457	cl_arr = *class_array;
3458	ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
3459				   __uvcg_fill_strm);
3460	if (ret) {
3461		kfree(*class_array);
3462		*class_array = NULL;
3463		/*
3464		 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
3465		 * might have advanced the "data", so use a backup copy
3466		 */
3467		kfree(data_save);
3468		goto unlock;
3469	}
3470
3471	++target_hdr->linked;
3472	ret = 0;
3473
3474unlock:
3475	mutex_unlock(&opts->lock);
3476out:
3477	config_item_put(header);
3478	mutex_unlock(su_mutex);
3479	return ret;
3480}
3481
3482static void uvcg_streaming_class_drop_link(struct config_item *src,
3483					  struct config_item *target)
3484{
3485	struct config_item *streaming, *header;
3486	struct f_uvc_opts *opts;
3487	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3488	struct uvc_descriptor_header ***class_array;
3489	struct uvcg_streaming_header *target_hdr;
3490
3491	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3492
3493	streaming = src->ci_parent->ci_parent;
3494	header = config_group_find_item(to_config_group(streaming), "header");
3495	if (!header || target->ci_parent != header)
3496		goto out;
3497
3498	opts = to_f_uvc_opts(streaming->ci_parent);
3499
3500	mutex_lock(&opts->lock);
3501
3502	class_array = __uvcg_get_stream_class_arr(src, opts);
3503	if (!class_array || !*class_array)
3504		goto unlock;
3505
3506	if (opts->refcnt)
3507		goto unlock;
3508
3509	target_hdr = to_uvcg_streaming_header(target);
3510	--target_hdr->linked;
3511	kfree(**class_array);
3512	kfree(*class_array);
3513	*class_array = NULL;
3514
3515unlock:
3516	mutex_unlock(&opts->lock);
3517out:
3518	config_item_put(header);
3519	mutex_unlock(su_mutex);
3520}
3521
3522static struct configfs_item_operations uvcg_streaming_class_item_ops = {
3523	.release	= uvcg_config_item_release,
3524	.allow_link	= uvcg_streaming_class_allow_link,
3525	.drop_link	= uvcg_streaming_class_drop_link,
3526};
3527
3528static const struct config_item_type uvcg_streaming_class_type = {
3529	.ct_item_ops	= &uvcg_streaming_class_item_ops,
3530	.ct_owner	= THIS_MODULE,
3531};
3532
3533/* -----------------------------------------------------------------------------
3534 * streaming/class
3535 */
3536
3537static int uvcg_streaming_class_create_children(struct config_group *parent)
3538{
3539	static const char * const names[] = { "fs", "hs", "ss" };
3540	unsigned int i;
3541
3542	for (i = 0; i < ARRAY_SIZE(names); ++i) {
3543		struct uvcg_streaming_class_group *group;
3544
3545		group = kzalloc(sizeof(*group), GFP_KERNEL);
3546		if (!group)
3547			return -ENOMEM;
3548
3549		group->name = names[i];
3550
3551		config_group_init_type_name(&group->group, group->name,
3552					    &uvcg_streaming_class_type);
3553		configfs_add_default_group(&group->group, parent);
3554	}
3555
3556	return 0;
3557}
3558
3559static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = {
3560	.type = {
3561		.ct_item_ops	= &uvcg_config_item_ops,
3562		.ct_owner	= THIS_MODULE,
3563	},
3564	.name = "class",
3565	.create_children = uvcg_streaming_class_create_children,
3566};
3567
3568/* -----------------------------------------------------------------------------
3569 * streaming
3570 */
3571
3572static ssize_t uvcg_default_streaming_b_interface_number_show(
3573	struct config_item *item, char *page)
3574{
3575	struct config_group *group = to_config_group(item);
3576	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
3577	struct config_item *opts_item;
3578	struct f_uvc_opts *opts;
3579	int result = 0;
3580
3581	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3582
3583	opts_item = item->ci_parent;
3584	opts = to_f_uvc_opts(opts_item);
3585
3586	mutex_lock(&opts->lock);
3587	result += sprintf(page, "%u\n", opts->streaming_interface);
3588	mutex_unlock(&opts->lock);
3589
3590	mutex_unlock(su_mutex);
3591
3592	return result;
3593}
3594
3595UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber);
3596
3597static struct configfs_attribute *uvcg_default_streaming_attrs[] = {
3598	&uvcg_default_streaming_attr_b_interface_number,
3599	NULL,
3600};
3601
3602static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
3603	.type = {
3604		.ct_item_ops	= &uvcg_config_item_ops,
3605		.ct_attrs	= uvcg_default_streaming_attrs,
3606		.ct_owner	= THIS_MODULE,
3607	},
3608	.name = "streaming",
3609	.children = (const struct uvcg_config_group_type*[]) {
3610		&uvcg_streaming_header_grp_type,
3611		&uvcg_uncompressed_grp_type,
3612		&uvcg_mjpeg_grp_type,
3613		&uvcg_framebased_grp_type,
3614		&uvcg_color_matching_grp_type,
3615		&uvcg_streaming_class_grp_type,
3616		NULL,
3617	},
3618};
3619
3620/* -----------------------------------------------------------------------------
3621 * UVC function
3622 */
3623
3624static void uvc_func_item_release(struct config_item *item)
3625{
3626	struct f_uvc_opts *opts = to_f_uvc_opts(item);
3627
3628	uvcg_config_remove_children(to_config_group(item));
3629	usb_put_function_instance(&opts->func_inst);
3630}
3631
3632static int uvc_func_allow_link(struct config_item *src, struct config_item *tgt)
3633{
3634	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
3635	struct gadget_string *string;
3636	struct config_item *strings;
3637	struct f_uvc_opts *opts;
3638	int ret = 0;
3639
3640	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
3641
3642	/* Validate that the target is an entry in strings/<langid> */
3643	strings = config_group_find_item(to_config_group(src->ci_parent->ci_parent),
3644					 "strings");
3645	if (!strings || tgt->ci_parent->ci_parent != strings) {
3646		ret = -EINVAL;
3647		goto put_strings;
3648	}
3649
3650	string = to_gadget_string(tgt);
3651
3652	opts = to_f_uvc_opts(src);
3653	mutex_lock(&opts->lock);
3654
3655	if (!strcmp(tgt->ci_name, "iad_desc"))
3656		opts->iad_index = string->usb_string.id;
3657	else if (!strcmp(tgt->ci_name, "vs0_desc"))
3658		opts->vs0_index = string->usb_string.id;
3659	else if (!strcmp(tgt->ci_name, "vs1_desc"))
3660		opts->vs1_index = string->usb_string.id;
3661	else
3662		ret = -EINVAL;
3663
3664	mutex_unlock(&opts->lock);
3665
3666put_strings:
3667	config_item_put(strings);
3668	mutex_unlock(su_mutex);
3669
3670	return ret;
3671}
3672
3673static void uvc_func_drop_link(struct config_item *src, struct config_item *tgt)
3674{
3675	struct f_uvc_opts *opts;
3676
3677	opts = to_f_uvc_opts(src);
3678	mutex_lock(&opts->lock);
3679
3680	if (!strcmp(tgt->ci_name, "iad_desc"))
3681		opts->iad_index = 0;
3682	else if (!strcmp(tgt->ci_name, "vs0_desc"))
3683		opts->vs0_index = 0;
3684	else if (!strcmp(tgt->ci_name, "vs1_desc"))
3685		opts->vs1_index = 0;
3686
3687	mutex_unlock(&opts->lock);
3688}
3689
3690static struct configfs_item_operations uvc_func_item_ops = {
3691	.release	= uvc_func_item_release,
3692	.allow_link	= uvc_func_allow_link,
3693	.drop_link	= uvc_func_drop_link,
3694};
3695
3696#define UVCG_OPTS_ATTR(cname, aname, limit)				\
3697static ssize_t f_uvc_opts_##cname##_show(				\
3698	struct config_item *item, char *page)				\
3699{									\
3700	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3701	int result;							\
3702									\
3703	mutex_lock(&opts->lock);					\
3704	result = sprintf(page, "%u\n", opts->cname);			\
3705	mutex_unlock(&opts->lock);					\
3706									\
3707	return result;							\
3708}									\
3709									\
3710static ssize_t								\
3711f_uvc_opts_##cname##_store(struct config_item *item,			\
3712			   const char *page, size_t len)		\
3713{									\
3714	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3715	unsigned int num;						\
3716	int ret;							\
3717									\
3718	mutex_lock(&opts->lock);					\
3719	if (opts->refcnt) {						\
3720		ret = -EBUSY;						\
3721		goto end;						\
3722	}								\
3723									\
3724	ret = kstrtouint(page, 0, &num);				\
3725	if (ret)							\
3726		goto end;						\
3727									\
3728	if (num > limit) {						\
3729		ret = -EINVAL;						\
3730		goto end;						\
3731	}								\
3732	opts->cname = num;						\
3733	ret = len;							\
3734end:									\
3735	mutex_unlock(&opts->lock);					\
3736	return ret;							\
3737}									\
3738									\
3739UVC_ATTR(f_uvc_opts_, cname, cname)
3740
3741UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
3742UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
3743UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
3744
3745#undef UVCG_OPTS_ATTR
3746
3747#define UVCG_OPTS_STRING_ATTR(cname, aname)				\
3748static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\
3749					 char *page)			\
3750{									\
3751	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3752	int result;							\
3753									\
3754	mutex_lock(&opts->lock);					\
3755	result = scnprintf(page, sizeof(opts->aname), "%s", opts->aname);\
3756	mutex_unlock(&opts->lock);					\
3757									\
3758	return result;							\
3759}									\
3760									\
3761static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\
3762					  const char *page, size_t len)	\
3763{									\
3764	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
3765	int size = min(sizeof(opts->aname), len + 1);			\
3766	int ret = 0;							\
3767									\
3768	mutex_lock(&opts->lock);					\
3769	if (opts->refcnt) {						\
3770		ret = -EBUSY;						\
3771		goto end;						\
3772	}								\
3773									\
3774	ret = strscpy(opts->aname, page, size);				\
3775	if (ret == -E2BIG)						\
3776		ret = size - 1;						\
3777									\
3778end:									\
3779	mutex_unlock(&opts->lock);					\
3780	return ret;							\
3781}									\
3782									\
3783UVC_ATTR(f_uvc_opts_string_, cname, aname)
3784
3785UVCG_OPTS_STRING_ATTR(function_name, function_name);
3786
3787#undef UVCG_OPTS_STRING_ATTR
3788
3789static struct configfs_attribute *uvc_attrs[] = {
3790	&f_uvc_opts_attr_streaming_interval,
3791	&f_uvc_opts_attr_streaming_maxpacket,
3792	&f_uvc_opts_attr_streaming_maxburst,
3793	&f_uvc_opts_string_attr_function_name,
3794	NULL,
3795};
3796
3797static const struct uvcg_config_group_type uvc_func_type = {
3798	.type = {
3799		.ct_item_ops	= &uvc_func_item_ops,
3800		.ct_attrs	= uvc_attrs,
3801		.ct_owner	= THIS_MODULE,
3802	},
3803	.name = "",
3804	.children = (const struct uvcg_config_group_type*[]) {
3805		&uvcg_control_grp_type,
3806		&uvcg_streaming_grp_type,
3807		NULL,
3808	},
3809};
3810
3811int uvcg_attach_configfs(struct f_uvc_opts *opts)
3812{
3813	int ret;
3814
3815	config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
3816				    &uvc_func_type.type);
3817
3818	ret = uvcg_config_create_children(&opts->func_inst.group,
3819					  &uvc_func_type);
3820	if (ret < 0)
3821		config_group_put(&opts->func_inst.group);
3822
3823	return ret;
3824}