Linux Audio

Check our new training course

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