Linux Audio

Check our new training course

Loading...
v5.14.15
   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(0x0110);
 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
 918	uvcg_format_set_indices(to_config_group(target));
 919
 920	format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
 921	if (!format_ptr) {
 922		ret = -ENOMEM;
 923		goto out;
 924	}
 925	ret = 0;
 926	format_ptr->fmt = target_fmt;
 927	list_add_tail(&format_ptr->entry, &src_hdr->formats);
 928	++src_hdr->num_fmt;
 929	++target_fmt->linked;
 930
 931out:
 932	mutex_unlock(&opts->lock);
 933	mutex_unlock(su_mutex);
 934	return ret;
 935}
 936
 937static void uvcg_streaming_header_drop_link(struct config_item *src,
 938					   struct config_item *target)
 939{
 940	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
 941	struct config_item *opts_item;
 942	struct f_uvc_opts *opts;
 943	struct uvcg_streaming_header *src_hdr;
 944	struct uvcg_format *target_fmt = NULL;
 945	struct uvcg_format_ptr *format_ptr, *tmp;
 
 946
 947	src_hdr = to_uvcg_streaming_header(src);
 948	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 949
 950	opts_item = src->ci_parent->ci_parent->ci_parent;
 951	opts = to_f_uvc_opts(opts_item);
 952
 953	mutex_lock(&opts->lock);
 954	target_fmt = container_of(to_config_group(target), struct uvcg_format,
 955				  group);
 
 
 956
 957	list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
 958		if (format_ptr->fmt == target_fmt) {
 959			list_del(&format_ptr->entry);
 960			kfree(format_ptr);
 961			--src_hdr->num_fmt;
 962			break;
 963		}
 964
 965	--target_fmt->linked;
 966
 967	mutex_unlock(&opts->lock);
 968	mutex_unlock(su_mutex);
 
 
 969}
 970
 971static struct configfs_item_operations uvcg_streaming_header_item_ops = {
 972	.release	= uvcg_config_item_release,
 973	.allow_link	= uvcg_streaming_header_allow_link,
 974	.drop_link	= uvcg_streaming_header_drop_link,
 975};
 976
 977#define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits)			\
 978static ssize_t uvcg_streaming_header_##cname##_show(			\
 979	struct config_item *item, char *page)				\
 980{									\
 981	struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
 982	struct f_uvc_opts *opts;					\
 983	struct config_item *opts_item;					\
 984	struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
 985	int result;							\
 986									\
 987	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 988									\
 989	opts_item = sh->item.ci_parent->ci_parent->ci_parent;		\
 990	opts = to_f_uvc_opts(opts_item);				\
 991									\
 992	mutex_lock(&opts->lock);					\
 993	result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\
 994	mutex_unlock(&opts->lock);					\
 995									\
 996	mutex_unlock(su_mutex);						\
 997	return result;							\
 998}									\
 999									\
1000UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
1001
1002UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, 8);
1003UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, 8);
1004UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 8);
1005UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, 8);
1006UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, 8);
 
 
 
 
 
1007
1008#undef UVCG_STREAMING_HEADER_ATTR
1009
1010static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
1011	&uvcg_streaming_header_attr_bm_info,
1012	&uvcg_streaming_header_attr_b_terminal_link,
1013	&uvcg_streaming_header_attr_b_still_capture_method,
1014	&uvcg_streaming_header_attr_b_trigger_support,
1015	&uvcg_streaming_header_attr_b_trigger_usage,
1016	NULL,
1017};
1018
1019static const struct config_item_type uvcg_streaming_header_type = {
1020	.ct_item_ops	= &uvcg_streaming_header_item_ops,
1021	.ct_attrs	= uvcg_streaming_header_attrs,
1022	.ct_owner	= THIS_MODULE,
1023};
1024
1025static struct config_item
1026*uvcg_streaming_header_make(struct config_group *group, const char *name)
1027{
1028	struct uvcg_streaming_header *h;
1029
1030	h = kzalloc(sizeof(*h), GFP_KERNEL);
1031	if (!h)
1032		return ERR_PTR(-ENOMEM);
1033
1034	INIT_LIST_HEAD(&h->formats);
1035	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1036	h->desc.bDescriptorSubType	= UVC_VS_INPUT_HEADER;
1037	h->desc.bTerminalLink		= 3;
1038	h->desc.bControlSize		= UVCG_STREAMING_CONTROL_SIZE;
1039
1040	config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
1041
1042	return &h->item;
1043}
1044
 
 
 
 
 
 
 
 
 
 
 
 
 
1045static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
1046	.make_item		= uvcg_streaming_header_make,
 
1047};
1048
1049static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = {
1050	.type = {
1051		.ct_item_ops	= &uvcg_config_item_ops,
1052		.ct_group_ops	= &uvcg_streaming_header_grp_ops,
1053		.ct_owner	= THIS_MODULE,
1054	},
1055	.name = "header",
1056};
1057
1058/* -----------------------------------------------------------------------------
1059 * streaming/<mode>/<format>/<NAME>
1060 */
1061
1062struct uvcg_frame {
1063	struct config_item	item;
1064	enum uvcg_format_type	fmt_type;
1065	struct {
1066		u8	b_length;
1067		u8	b_descriptor_type;
1068		u8	b_descriptor_subtype;
1069		u8	b_frame_index;
1070		u8	bm_capabilities;
1071		u16	w_width;
1072		u16	w_height;
1073		u32	dw_min_bit_rate;
1074		u32	dw_max_bit_rate;
1075		u32	dw_max_video_frame_buffer_size;
1076		u32	dw_default_frame_interval;
1077		u8	b_frame_interval_type;
1078	} __attribute__((packed)) frame;
1079	u32 *dw_frame_interval;
 
 
1080};
1081
1082static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
1083{
1084	return container_of(item, struct uvcg_frame, item);
1085}
1086
1087#define UVCG_FRAME_ATTR(cname, aname, bits) \
1088static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
1089{									\
1090	struct uvcg_frame *f = to_uvcg_frame(item);			\
1091	struct f_uvc_opts *opts;					\
1092	struct config_item *opts_item;					\
1093	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1094	int result;							\
1095									\
1096	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1097									\
1098	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1099	opts = to_f_uvc_opts(opts_item);				\
1100									\
1101	mutex_lock(&opts->lock);					\
1102	result = sprintf(page, "%u\n", f->frame.cname);			\
1103	mutex_unlock(&opts->lock);					\
1104									\
1105	mutex_unlock(su_mutex);						\
1106	return result;							\
1107}									\
1108									\
1109static ssize_t  uvcg_frame_##cname##_store(struct config_item *item,	\
1110					   const char *page, size_t len)\
1111{									\
1112	struct uvcg_frame *f = to_uvcg_frame(item);			\
1113	struct f_uvc_opts *opts;					\
1114	struct config_item *opts_item;					\
1115	struct uvcg_format *fmt;					\
1116	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1117	typeof(f->frame.cname) num;					\
1118	int ret;							\
 
1119									\
1120	ret = kstrtou##bits(page, 0, &num);				\
1121	if (ret)							\
1122		return ret;						\
1123									\
1124	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1125									\
1126	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1127	opts = to_f_uvc_opts(opts_item);				\
1128	fmt = to_uvcg_format(f->item.ci_parent);			\
1129									\
1130	mutex_lock(&opts->lock);					\
1131	if (fmt->linked || opts->refcnt) {				\
1132		ret = -EBUSY;						\
1133		goto end;						\
1134	}								\
1135									\
1136	f->frame.cname = num;						\
1137	ret = len;							\
1138end:									\
1139	mutex_unlock(&opts->lock);					\
1140	mutex_unlock(su_mutex);						\
1141	return ret;							\
1142}									\
1143									\
1144UVC_ATTR(uvcg_frame_, cname, aname);
1145
1146static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item,
1147					     char *page)
1148{
1149	struct uvcg_frame *f = to_uvcg_frame(item);
1150	struct uvcg_format *fmt;
1151	struct f_uvc_opts *opts;
1152	struct config_item *opts_item;
1153	struct config_item *fmt_item;
1154	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;
1155	int result;
1156
1157	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1158
1159	fmt_item = f->item.ci_parent;
1160	fmt = to_uvcg_format(fmt_item);
1161
1162	if (!fmt->linked) {
1163		result = -EBUSY;
1164		goto out;
1165	}
1166
1167	opts_item = fmt_item->ci_parent->ci_parent->ci_parent;
1168	opts = to_f_uvc_opts(opts_item);
1169
1170	mutex_lock(&opts->lock);
1171	result = sprintf(page, "%u\n", f->frame.b_frame_index);
1172	mutex_unlock(&opts->lock);
1173
1174out:
1175	mutex_unlock(su_mutex);
1176	return result;
1177}
1178
1179UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex);
 
 
 
 
 
 
 
 
 
1180
1181UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, 8);
1182UVCG_FRAME_ATTR(w_width, wWidth, 16);
1183UVCG_FRAME_ATTR(w_height, wHeight, 16);
1184UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
1185UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
1186UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
1187UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
1188
1189#undef UVCG_FRAME_ATTR
1190
1191static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
1192						 char *page)
1193{
1194	struct uvcg_frame *frm = to_uvcg_frame(item);
1195	struct f_uvc_opts *opts;
1196	struct config_item *opts_item;
1197	struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
1198	int result, i;
1199	char *pg = page;
1200
1201	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1202
1203	opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
1204	opts = to_f_uvc_opts(opts_item);
1205
1206	mutex_lock(&opts->lock);
1207	for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
1208		result += sprintf(pg, "%u\n", frm->dw_frame_interval[i]);
 
1209		pg = page + result;
1210	}
1211	mutex_unlock(&opts->lock);
1212
1213	mutex_unlock(su_mutex);
1214	return result;
1215}
1216
1217static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1218{
1219	++*((int *)priv);
1220	return 0;
1221}
1222
1223static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
1224{
1225	u32 num, **interv;
1226	int ret;
1227
1228	ret = kstrtou32(buf, 0, &num);
1229	if (ret)
1230		return ret;
1231
1232	interv = priv;
1233	**interv = num;
1234	++*interv;
1235
1236	return 0;
1237}
1238
1239static int __uvcg_iter_frm_intrv(const char *page, size_t len,
1240				 int (*fun)(char *, void *), void *priv)
1241{
1242	/* sign, base 2 representation, newline, terminator */
1243	char buf[1 + sizeof(u32) * 8 + 1 + 1];
1244	const char *pg = page;
1245	int i, ret;
1246
1247	if (!fun)
1248		return -EINVAL;
1249
1250	while (pg - page < len) {
1251		i = 0;
1252		while (i < sizeof(buf) && (pg - page < len) &&
1253				*pg != '\0' && *pg != '\n')
1254			buf[i++] = *pg++;
1255		if (i == sizeof(buf))
1256			return -EINVAL;
1257		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
1258			++pg;
1259		buf[i] = '\0';
1260		ret = fun(buf, priv);
1261		if (ret)
1262			return ret;
1263	}
1264
1265	return 0;
1266}
1267
1268static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
1269						  const char *page, size_t len)
1270{
1271	struct uvcg_frame *ch = to_uvcg_frame(item);
1272	struct f_uvc_opts *opts;
1273	struct config_item *opts_item;
1274	struct uvcg_format *fmt;
1275	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
1276	int ret = 0, n = 0;
1277	u32 *frm_intrv, *tmp;
1278
1279	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1280
1281	opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
1282	opts = to_f_uvc_opts(opts_item);
1283	fmt = to_uvcg_format(ch->item.ci_parent);
1284
1285	mutex_lock(&opts->lock);
1286	if (fmt->linked || opts->refcnt) {
1287		ret = -EBUSY;
1288		goto end;
1289	}
1290
1291	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
1292	if (ret)
1293		goto end;
1294
1295	tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
1296	if (!frm_intrv) {
1297		ret = -ENOMEM;
1298		goto end;
1299	}
1300
1301	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
1302	if (ret) {
1303		kfree(frm_intrv);
1304		goto end;
1305	}
1306
1307	kfree(ch->dw_frame_interval);
1308	ch->dw_frame_interval = frm_intrv;
1309	ch->frame.b_frame_interval_type = n;
1310	sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval),
1311	     uvcg_config_compare_u32, NULL);
1312	ret = len;
1313
1314end:
1315	mutex_unlock(&opts->lock);
1316	mutex_unlock(su_mutex);
1317	return ret;
1318}
1319
1320UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
1321
1322static struct configfs_attribute *uvcg_frame_attrs[] = {
1323	&uvcg_frame_attr_b_frame_index,
1324	&uvcg_frame_attr_bm_capabilities,
1325	&uvcg_frame_attr_w_width,
1326	&uvcg_frame_attr_w_height,
1327	&uvcg_frame_attr_dw_min_bit_rate,
1328	&uvcg_frame_attr_dw_max_bit_rate,
1329	&uvcg_frame_attr_dw_max_video_frame_buffer_size,
1330	&uvcg_frame_attr_dw_default_frame_interval,
1331	&uvcg_frame_attr_dw_frame_interval,
1332	NULL,
1333};
1334
1335static const struct config_item_type uvcg_frame_type = {
1336	.ct_item_ops	= &uvcg_config_item_ops,
1337	.ct_attrs	= uvcg_frame_attrs,
1338	.ct_owner	= THIS_MODULE,
1339};
1340
1341static struct config_item *uvcg_frame_make(struct config_group *group,
1342					   const char *name)
1343{
1344	struct uvcg_frame *h;
1345	struct uvcg_format *fmt;
1346	struct f_uvc_opts *opts;
1347	struct config_item *opts_item;
1348
1349	h = kzalloc(sizeof(*h), GFP_KERNEL);
1350	if (!h)
1351		return ERR_PTR(-ENOMEM);
1352
1353	h->frame.b_descriptor_type		= USB_DT_CS_INTERFACE;
1354	h->frame.b_frame_index			= 1;
1355	h->frame.w_width			= 640;
1356	h->frame.w_height			= 360;
1357	h->frame.dw_min_bit_rate		= 18432000;
1358	h->frame.dw_max_bit_rate		= 55296000;
1359	h->frame.dw_max_video_frame_buffer_size	= 460800;
1360	h->frame.dw_default_frame_interval	= 666666;
1361
1362	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1363	opts = to_f_uvc_opts(opts_item);
1364
1365	mutex_lock(&opts->lock);
1366	fmt = to_uvcg_format(&group->cg_item);
1367	if (fmt->type == UVCG_UNCOMPRESSED) {
1368		h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
1369		h->fmt_type = UVCG_UNCOMPRESSED;
1370	} else if (fmt->type == UVCG_MJPEG) {
1371		h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
1372		h->fmt_type = UVCG_MJPEG;
1373	} else {
1374		mutex_unlock(&opts->lock);
1375		kfree(h);
1376		return ERR_PTR(-EINVAL);
1377	}
1378	++fmt->num_frames;
1379	mutex_unlock(&opts->lock);
1380
1381	config_item_init_type_name(&h->item, name, &uvcg_frame_type);
1382
1383	return &h->item;
1384}
1385
1386static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
1387{
 
1388	struct uvcg_format *fmt;
1389	struct f_uvc_opts *opts;
1390	struct config_item *opts_item;
1391
1392	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1393	opts = to_f_uvc_opts(opts_item);
1394
1395	mutex_lock(&opts->lock);
1396	fmt = to_uvcg_format(&group->cg_item);
1397	--fmt->num_frames;
 
1398	mutex_unlock(&opts->lock);
1399
1400	config_item_put(item);
1401}
1402
1403static void uvcg_format_set_indices(struct config_group *fmt)
1404{
1405	struct config_item *ci;
1406	unsigned int i = 1;
1407
1408	list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
1409		struct uvcg_frame *frm;
1410
1411		if (ci->ci_type != &uvcg_frame_type)
1412			continue;
1413
1414		frm = to_uvcg_frame(ci);
1415		frm->frame.b_frame_index = i++;
1416	}
1417}
1418
1419/* -----------------------------------------------------------------------------
1420 * streaming/uncompressed/<NAME>
1421 */
1422
1423struct uvcg_uncompressed {
1424	struct uvcg_format		fmt;
1425	struct uvc_format_uncompressed	desc;
1426};
1427
1428static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
1429{
1430	return container_of(
1431		container_of(to_config_group(item), struct uvcg_format, group),
1432		struct uvcg_uncompressed, fmt);
1433}
1434
1435static struct configfs_group_operations uvcg_uncompressed_group_ops = {
1436	.make_item		= uvcg_frame_make,
1437	.drop_item		= uvcg_frame_drop,
1438};
1439
1440static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
1441							char *page)
1442{
1443	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1444	struct f_uvc_opts *opts;
1445	struct config_item *opts_item;
1446	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1447
1448	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1449
1450	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1451	opts = to_f_uvc_opts(opts_item);
1452
1453	mutex_lock(&opts->lock);
1454	memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
1455	mutex_unlock(&opts->lock);
1456
1457	mutex_unlock(su_mutex);
1458
1459	return sizeof(ch->desc.guidFormat);
1460}
1461
1462static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
1463						   const char *page, size_t len)
1464{
1465	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1466	struct f_uvc_opts *opts;
1467	struct config_item *opts_item;
1468	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1469	int ret;
1470
1471	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1472
1473	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1474	opts = to_f_uvc_opts(opts_item);
1475
1476	mutex_lock(&opts->lock);
1477	if (ch->fmt.linked || opts->refcnt) {
1478		ret = -EBUSY;
1479		goto end;
1480	}
1481
1482	memcpy(ch->desc.guidFormat, page,
1483	       min(sizeof(ch->desc.guidFormat), len));
1484	ret = sizeof(ch->desc.guidFormat);
1485
1486end:
1487	mutex_unlock(&opts->lock);
1488	mutex_unlock(su_mutex);
1489	return ret;
1490}
1491
1492UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
1493
1494#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits)			\
1495static ssize_t uvcg_uncompressed_##cname##_show(			\
1496	struct config_item *item, char *page)				\
1497{									\
1498	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1499	struct f_uvc_opts *opts;					\
1500	struct config_item *opts_item;					\
1501	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1502	int result;							\
1503									\
1504	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1505									\
1506	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1507	opts = to_f_uvc_opts(opts_item);				\
1508									\
1509	mutex_lock(&opts->lock);					\
1510	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1511	mutex_unlock(&opts->lock);					\
1512									\
1513	mutex_unlock(su_mutex);						\
1514	return result;							\
1515}									\
1516									\
1517UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
1518
1519#define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits)			\
1520static ssize_t uvcg_uncompressed_##cname##_show(			\
1521	struct config_item *item, char *page)				\
1522{									\
1523	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1524	struct f_uvc_opts *opts;					\
1525	struct config_item *opts_item;					\
1526	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1527	int result;							\
1528									\
1529	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1530									\
1531	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1532	opts = to_f_uvc_opts(opts_item);				\
1533									\
1534	mutex_lock(&opts->lock);					\
1535	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1536	mutex_unlock(&opts->lock);					\
1537									\
1538	mutex_unlock(su_mutex);						\
1539	return result;							\
1540}									\
1541									\
1542static ssize_t								\
1543uvcg_uncompressed_##cname##_store(struct config_item *item,		\
1544				    const char *page, size_t len)	\
1545{									\
1546	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1547	struct f_uvc_opts *opts;					\
1548	struct config_item *opts_item;					\
1549	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1550	int ret;							\
1551	u8 num;								\
1552									\
1553	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1554									\
1555	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1556	opts = to_f_uvc_opts(opts_item);				\
1557									\
1558	mutex_lock(&opts->lock);					\
1559	if (u->fmt.linked || opts->refcnt) {				\
1560		ret = -EBUSY;						\
1561		goto end;						\
1562	}								\
1563									\
1564	ret = kstrtou8(page, 0, &num);					\
1565	if (ret)							\
1566		goto end;						\
1567									\
 
 
 
 
1568	u->desc.aname = num;						\
1569	ret = len;							\
1570end:									\
1571	mutex_unlock(&opts->lock);					\
1572	mutex_unlock(su_mutex);						\
1573	return ret;							\
1574}									\
1575									\
1576UVC_ATTR(uvcg_uncompressed_, cname, aname);
1577
1578UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8);
1579UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8);
1580UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
1581UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
1582UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
1583UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
 
 
 
 
1584
1585#undef UVCG_UNCOMPRESSED_ATTR
1586#undef UVCG_UNCOMPRESSED_ATTR_RO
1587
1588static inline ssize_t
1589uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
1590{
1591	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1592	return uvcg_format_bma_controls_show(&unc->fmt, page);
1593}
1594
1595static inline ssize_t
1596uvcg_uncompressed_bma_controls_store(struct config_item *item,
1597				     const char *page, size_t len)
1598{
1599	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1600	return uvcg_format_bma_controls_store(&unc->fmt, page, len);
1601}
1602
1603UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
1604
1605static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
1606	&uvcg_uncompressed_attr_b_format_index,
1607	&uvcg_uncompressed_attr_guid_format,
1608	&uvcg_uncompressed_attr_b_bits_per_pixel,
1609	&uvcg_uncompressed_attr_b_default_frame_index,
1610	&uvcg_uncompressed_attr_b_aspect_ratio_x,
1611	&uvcg_uncompressed_attr_b_aspect_ratio_y,
1612	&uvcg_uncompressed_attr_bm_interface_flags,
1613	&uvcg_uncompressed_attr_bma_controls,
1614	NULL,
1615};
1616
1617static const struct config_item_type uvcg_uncompressed_type = {
1618	.ct_item_ops	= &uvcg_config_item_ops,
1619	.ct_group_ops	= &uvcg_uncompressed_group_ops,
1620	.ct_attrs	= uvcg_uncompressed_attrs,
1621	.ct_owner	= THIS_MODULE,
1622};
1623
1624static struct config_group *uvcg_uncompressed_make(struct config_group *group,
1625						   const char *name)
1626{
1627	static char guid[] = {
1628		'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
1629		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
1630	};
1631	struct uvcg_uncompressed *h;
1632
1633	h = kzalloc(sizeof(*h), GFP_KERNEL);
1634	if (!h)
1635		return ERR_PTR(-ENOMEM);
1636
1637	h->desc.bLength			= UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
1638	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1639	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED;
1640	memcpy(h->desc.guidFormat, guid, sizeof(guid));
1641	h->desc.bBitsPerPixel		= 16;
1642	h->desc.bDefaultFrameIndex	= 1;
1643	h->desc.bAspectRatioX		= 0;
1644	h->desc.bAspectRatioY		= 0;
1645	h->desc.bmInterfaceFlags	= 0;
1646	h->desc.bCopyProtect		= 0;
1647
1648	h->fmt.type = UVCG_UNCOMPRESSED;
1649	config_group_init_type_name(&h->fmt.group, name,
1650				    &uvcg_uncompressed_type);
1651
1652	return &h->fmt.group;
1653}
1654
 
 
 
 
 
 
 
 
1655static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
1656	.make_group		= uvcg_uncompressed_make,
 
1657};
1658
1659static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = {
1660	.type = {
1661		.ct_item_ops	= &uvcg_config_item_ops,
1662		.ct_group_ops	= &uvcg_uncompressed_grp_ops,
1663		.ct_owner	= THIS_MODULE,
1664	},
1665	.name = "uncompressed",
1666};
1667
1668/* -----------------------------------------------------------------------------
1669 * streaming/mjpeg/<NAME>
1670 */
1671
1672struct uvcg_mjpeg {
1673	struct uvcg_format		fmt;
1674	struct uvc_format_mjpeg		desc;
1675};
1676
1677static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
1678{
1679	return container_of(
1680		container_of(to_config_group(item), struct uvcg_format, group),
1681		struct uvcg_mjpeg, fmt);
1682}
1683
1684static struct configfs_group_operations uvcg_mjpeg_group_ops = {
1685	.make_item		= uvcg_frame_make,
1686	.drop_item		= uvcg_frame_drop,
1687};
1688
1689#define UVCG_MJPEG_ATTR_RO(cname, aname, bits)				\
1690static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1691{									\
1692	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1693	struct f_uvc_opts *opts;					\
1694	struct config_item *opts_item;					\
1695	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1696	int result;							\
1697									\
1698	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1699									\
1700	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1701	opts = to_f_uvc_opts(opts_item);				\
1702									\
1703	mutex_lock(&opts->lock);					\
1704	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1705	mutex_unlock(&opts->lock);					\
1706									\
1707	mutex_unlock(su_mutex);						\
1708	return result;							\
1709}									\
1710									\
1711UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
1712
1713#define UVCG_MJPEG_ATTR(cname, aname, bits)				\
1714static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1715{									\
1716	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1717	struct f_uvc_opts *opts;					\
1718	struct config_item *opts_item;					\
1719	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1720	int result;							\
1721									\
1722	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1723									\
1724	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1725	opts = to_f_uvc_opts(opts_item);				\
1726									\
1727	mutex_lock(&opts->lock);					\
1728	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1729	mutex_unlock(&opts->lock);					\
1730									\
1731	mutex_unlock(su_mutex);						\
1732	return result;							\
1733}									\
1734									\
1735static ssize_t								\
1736uvcg_mjpeg_##cname##_store(struct config_item *item,			\
1737			   const char *page, size_t len)		\
1738{									\
1739	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1740	struct f_uvc_opts *opts;					\
1741	struct config_item *opts_item;					\
1742	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1743	int ret;							\
1744	u8 num;								\
1745									\
1746	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1747									\
1748	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1749	opts = to_f_uvc_opts(opts_item);				\
1750									\
1751	mutex_lock(&opts->lock);					\
1752	if (u->fmt.linked || opts->refcnt) {				\
1753		ret = -EBUSY;						\
1754		goto end;						\
1755	}								\
1756									\
1757	ret = kstrtou8(page, 0, &num);					\
1758	if (ret)							\
1759		goto end;						\
1760									\
 
 
 
 
1761	u->desc.aname = num;						\
1762	ret = len;							\
1763end:									\
1764	mutex_unlock(&opts->lock);					\
1765	mutex_unlock(su_mutex);						\
1766	return ret;							\
1767}									\
1768									\
1769UVC_ATTR(uvcg_mjpeg_, cname, aname)
1770
1771UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8);
1772UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
1773UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8);
1774UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
1775UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
1776UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
 
 
 
 
1777
1778#undef UVCG_MJPEG_ATTR
1779#undef UVCG_MJPEG_ATTR_RO
1780
1781static inline ssize_t
1782uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
1783{
1784	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1785	return uvcg_format_bma_controls_show(&u->fmt, page);
1786}
1787
1788static inline ssize_t
1789uvcg_mjpeg_bma_controls_store(struct config_item *item,
1790				     const char *page, size_t len)
1791{
1792	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1793	return uvcg_format_bma_controls_store(&u->fmt, page, len);
1794}
1795
1796UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
1797
1798static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
1799	&uvcg_mjpeg_attr_b_format_index,
1800	&uvcg_mjpeg_attr_b_default_frame_index,
1801	&uvcg_mjpeg_attr_bm_flags,
1802	&uvcg_mjpeg_attr_b_aspect_ratio_x,
1803	&uvcg_mjpeg_attr_b_aspect_ratio_y,
1804	&uvcg_mjpeg_attr_bm_interface_flags,
1805	&uvcg_mjpeg_attr_bma_controls,
1806	NULL,
1807};
1808
1809static const struct config_item_type uvcg_mjpeg_type = {
1810	.ct_item_ops	= &uvcg_config_item_ops,
1811	.ct_group_ops	= &uvcg_mjpeg_group_ops,
1812	.ct_attrs	= uvcg_mjpeg_attrs,
1813	.ct_owner	= THIS_MODULE,
1814};
1815
1816static struct config_group *uvcg_mjpeg_make(struct config_group *group,
1817						   const char *name)
1818{
1819	struct uvcg_mjpeg *h;
1820
1821	h = kzalloc(sizeof(*h), GFP_KERNEL);
1822	if (!h)
1823		return ERR_PTR(-ENOMEM);
1824
1825	h->desc.bLength			= UVC_DT_FORMAT_MJPEG_SIZE;
1826	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1827	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG;
1828	h->desc.bDefaultFrameIndex	= 1;
1829	h->desc.bAspectRatioX		= 0;
1830	h->desc.bAspectRatioY		= 0;
1831	h->desc.bmInterfaceFlags	= 0;
1832	h->desc.bCopyProtect		= 0;
1833
1834	h->fmt.type = UVCG_MJPEG;
1835	config_group_init_type_name(&h->fmt.group, name,
1836				    &uvcg_mjpeg_type);
1837
1838	return &h->fmt.group;
1839}
1840
 
 
 
 
 
 
 
 
1841static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
1842	.make_group		= uvcg_mjpeg_make,
 
1843};
1844
1845static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
1846	.type = {
1847		.ct_item_ops	= &uvcg_config_item_ops,
1848		.ct_group_ops	= &uvcg_mjpeg_grp_ops,
1849		.ct_owner	= THIS_MODULE,
1850	},
1851	.name = "mjpeg",
1852};
1853
1854/* -----------------------------------------------------------------------------
1855 * streaming/color_matching/default
1856 */
 
1857
1858#define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, bits)		\
 
 
 
 
 
 
 
1859static ssize_t uvcg_default_color_matching_##cname##_show(		\
1860	struct config_item *item, char *page)				\
1861{									\
1862	struct config_group *group = to_config_group(item);		\
 
1863	struct f_uvc_opts *opts;					\
1864	struct config_item *opts_item;					\
1865	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
1866	struct uvc_color_matching_descriptor *cd;			\
1867	int result;							\
1868									\
1869	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1870									\
1871	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
1872	opts = to_f_uvc_opts(opts_item);				\
1873	cd = &opts->uvc_color_matching;					\
1874									\
1875	mutex_lock(&opts->lock);					\
1876	result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname));	\
1877	mutex_unlock(&opts->lock);					\
1878									\
1879	mutex_unlock(su_mutex);						\
1880	return result;							\
1881}									\
1882									\
1883UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
1884
1885UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8);
 
 
 
1886UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
1887				 bTransferCharacteristics, 8);
1888UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8);
 
 
 
1889
1890#undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
1891
1892static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
1893	&uvcg_default_color_matching_attr_b_color_primaries,
1894	&uvcg_default_color_matching_attr_b_transfer_characteristics,
1895	&uvcg_default_color_matching_attr_b_matrix_coefficients,
1896	NULL,
1897};
1898
1899static const struct uvcg_config_group_type uvcg_default_color_matching_type = {
1900	.type = {
1901		.ct_item_ops	= &uvcg_config_item_ops,
1902		.ct_attrs	= uvcg_default_color_matching_attrs,
1903		.ct_owner	= THIS_MODULE,
1904	},
1905	.name = "default",
1906};
1907
1908/* -----------------------------------------------------------------------------
1909 * streaming/color_matching
1910 */
1911
1912static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
1913	.type = {
1914		.ct_item_ops	= &uvcg_config_item_ops,
1915		.ct_owner	= THIS_MODULE,
1916	},
1917	.name = "color_matching",
1918	.children = (const struct uvcg_config_group_type*[]) {
1919		&uvcg_default_color_matching_type,
1920		NULL,
1921	},
1922};
1923
1924/* -----------------------------------------------------------------------------
1925 * streaming/class/{fs|hs|ss}
1926 */
 
1927
1928struct uvcg_streaming_class_group {
1929	struct config_group group;
1930	const char *name;
1931};
1932
1933static inline struct uvc_descriptor_header
1934***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
1935{
1936	struct uvcg_streaming_class_group *group =
1937		container_of(i, struct uvcg_streaming_class_group,
1938			     group.cg_item);
1939
1940	if (!strcmp(group->name, "fs"))
1941		return &o->uvc_fs_streaming_cls;
1942
1943	if (!strcmp(group->name, "hs"))
1944		return &o->uvc_hs_streaming_cls;
1945
1946	if (!strcmp(group->name, "ss"))
1947		return &o->uvc_ss_streaming_cls;
1948
1949	return NULL;
1950}
1951
1952enum uvcg_strm_type {
1953	UVCG_HEADER = 0,
1954	UVCG_FORMAT,
1955	UVCG_FRAME
1956};
1957
1958/*
1959 * Iterate over a hierarchy of streaming descriptors' config items.
1960 * The items are created by the user with configfs.
1961 *
1962 * It "processes" the header pointed to by @priv1, then for each format
1963 * that follows the header "processes" the format itself and then for
1964 * each frame inside a format "processes" the frame.
1965 *
1966 * As a "processing" function the @fun is used.
1967 *
1968 * __uvcg_iter_strm_cls() is used in two context: first, to calculate
1969 * the amount of memory needed for an array of streaming descriptors
1970 * and second, to actually fill the array.
1971 *
1972 * @h: streaming header pointer
1973 * @priv2: an "inout" parameter (the caller might want to see the changes to it)
1974 * @priv3: an "inout" parameter (the caller might want to see the changes to it)
1975 * @fun: callback function for processing each level of the hierarchy
1976 */
1977static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
1978	void *priv2, void *priv3,
1979	int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
1980{
1981	struct uvcg_format_ptr *f;
1982	struct config_group *grp;
1983	struct config_item *item;
1984	struct uvcg_frame *frm;
1985	int ret, i, j;
1986
1987	if (!fun)
1988		return -EINVAL;
1989
1990	i = j = 0;
1991	ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
1992	if (ret)
1993		return ret;
1994	list_for_each_entry(f, &h->formats, entry) {
1995		ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
1996		if (ret)
1997			return ret;
1998		grp = &f->fmt->group;
1999		list_for_each_entry(item, &grp->cg_children, ci_entry) {
2000			frm = to_uvcg_frame(item);
2001			ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
2002			if (ret)
2003				return ret;
2004		}
2005	}
2006
2007	return ret;
2008}
2009
2010/*
2011 * Count how many bytes are needed for an array of streaming descriptors.
2012 *
2013 * @priv1: pointer to a header, format or frame
2014 * @priv2: inout parameter, accumulated size of the array
2015 * @priv3: inout parameter, accumulated number of the array elements
2016 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
2017 */
2018static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
2019			   enum uvcg_strm_type type)
2020{
2021	size_t *size = priv2;
2022	size_t *count = priv3;
2023
2024	switch (type) {
2025	case UVCG_HEADER: {
2026		struct uvcg_streaming_header *h = priv1;
2027
2028		*size += sizeof(h->desc);
2029		/* bmaControls */
2030		*size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
2031	}
2032	break;
2033	case UVCG_FORMAT: {
2034		struct uvcg_format *fmt = priv1;
2035
2036		if (fmt->type == UVCG_UNCOMPRESSED) {
2037			struct uvcg_uncompressed *u =
2038				container_of(fmt, struct uvcg_uncompressed,
2039					     fmt);
2040
2041			*size += sizeof(u->desc);
2042		} else if (fmt->type == UVCG_MJPEG) {
2043			struct uvcg_mjpeg *m =
2044				container_of(fmt, struct uvcg_mjpeg, fmt);
2045
2046			*size += sizeof(m->desc);
2047		} else {
2048			return -EINVAL;
2049		}
2050	}
2051	break;
2052	case UVCG_FRAME: {
2053		struct uvcg_frame *frm = priv1;
2054		int sz = sizeof(frm->dw_frame_interval);
2055
2056		*size += sizeof(frm->frame);
2057		*size += frm->frame.b_frame_interval_type * sz;
2058	}
2059	break;
2060	}
2061
2062	++*count;
2063
2064	return 0;
2065}
2066
2067/*
2068 * Fill an array of streaming descriptors.
2069 *
2070 * @priv1: pointer to a header, format or frame
2071 * @priv2: inout parameter, pointer into a block of memory
2072 * @priv3: inout parameter, pointer to a 2-dimensional array
2073 */
2074static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
2075			    enum uvcg_strm_type type)
2076{
2077	void **dest = priv2;
2078	struct uvc_descriptor_header ***array = priv3;
2079	size_t sz;
2080
2081	**array = *dest;
2082	++*array;
2083
2084	switch (type) {
2085	case UVCG_HEADER: {
2086		struct uvc_input_header_descriptor *ihdr = *dest;
2087		struct uvcg_streaming_header *h = priv1;
2088		struct uvcg_format_ptr *f;
2089
2090		memcpy(*dest, &h->desc, sizeof(h->desc));
2091		*dest += sizeof(h->desc);
2092		sz = UVCG_STREAMING_CONTROL_SIZE;
2093		list_for_each_entry(f, &h->formats, entry) {
2094			memcpy(*dest, f->fmt->bmaControls, sz);
2095			*dest += sz;
2096		}
2097		ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
2098		ihdr->bNumFormats = h->num_fmt;
2099	}
2100	break;
2101	case UVCG_FORMAT: {
2102		struct uvcg_format *fmt = priv1;
2103
2104		if (fmt->type == UVCG_UNCOMPRESSED) {
 
2105			struct uvcg_uncompressed *u =
2106				container_of(fmt, struct uvcg_uncompressed,
2107					     fmt);
2108
2109			u->desc.bFormatIndex = n + 1;
2110			u->desc.bNumFrameDescriptors = fmt->num_frames;
2111			memcpy(*dest, &u->desc, sizeof(u->desc));
2112			*dest += sizeof(u->desc);
 
 
2113		} else if (fmt->type == UVCG_MJPEG) {
 
2114			struct uvcg_mjpeg *m =
2115				container_of(fmt, struct uvcg_mjpeg, fmt);
2116
2117			m->desc.bFormatIndex = n + 1;
2118			m->desc.bNumFrameDescriptors = fmt->num_frames;
2119			memcpy(*dest, &m->desc, sizeof(m->desc));
2120			*dest += sizeof(m->desc);
 
 
2121		} else {
2122			return -EINVAL;
2123		}
2124	}
2125	break;
2126	case UVCG_FRAME: {
2127		struct uvcg_frame *frm = priv1;
2128		struct uvc_descriptor_header *h = *dest;
2129
2130		sz = sizeof(frm->frame);
2131		memcpy(*dest, &frm->frame, sz);
2132		*dest += sz;
2133		sz = frm->frame.b_frame_interval_type *
2134			sizeof(*frm->dw_frame_interval);
2135		memcpy(*dest, frm->dw_frame_interval, sz);
2136		*dest += sz;
2137		if (frm->fmt_type == UVCG_UNCOMPRESSED)
2138			h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
2139				frm->frame.b_frame_interval_type);
2140		else if (frm->fmt_type == UVCG_MJPEG)
2141			h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
2142				frm->frame.b_frame_interval_type);
2143	}
2144	break;
2145	}
2146
2147	return 0;
2148}
2149
2150static int uvcg_streaming_class_allow_link(struct config_item *src,
2151					   struct config_item *target)
2152{
2153	struct config_item *streaming, *header;
2154	struct f_uvc_opts *opts;
2155	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2156	struct uvc_descriptor_header ***class_array, **cl_arr;
2157	struct uvcg_streaming_header *target_hdr;
2158	void *data, *data_save;
2159	size_t size = 0, count = 0;
2160	int ret = -EINVAL;
2161
2162	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2163
2164	streaming = src->ci_parent->ci_parent;
2165	header = config_group_find_item(to_config_group(streaming), "header");
2166	if (!header || target->ci_parent != header)
2167		goto out;
2168
2169	opts = to_f_uvc_opts(streaming->ci_parent);
2170
2171	mutex_lock(&opts->lock);
2172
2173	class_array = __uvcg_get_stream_class_arr(src, opts);
2174	if (!class_array || *class_array || opts->refcnt) {
2175		ret = -EBUSY;
2176		goto unlock;
2177	}
2178
2179	target_hdr = to_uvcg_streaming_header(target);
2180	ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
2181	if (ret)
2182		goto unlock;
2183
2184	count += 2; /* color_matching, NULL */
2185	*class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
2186	if (!*class_array) {
2187		ret = -ENOMEM;
2188		goto unlock;
2189	}
2190
2191	data = data_save = kzalloc(size, GFP_KERNEL);
2192	if (!data) {
2193		kfree(*class_array);
2194		*class_array = NULL;
2195		ret = -ENOMEM;
2196		goto unlock;
2197	}
2198	cl_arr = *class_array;
2199	ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
2200				   __uvcg_fill_strm);
2201	if (ret) {
2202		kfree(*class_array);
2203		*class_array = NULL;
2204		/*
2205		 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
2206		 * might have advanced the "data", so use a backup copy
2207		 */
2208		kfree(data_save);
2209		goto unlock;
2210	}
2211	*cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;
2212
2213	++target_hdr->linked;
2214	ret = 0;
2215
2216unlock:
2217	mutex_unlock(&opts->lock);
2218out:
2219	config_item_put(header);
2220	mutex_unlock(su_mutex);
2221	return ret;
2222}
2223
2224static void uvcg_streaming_class_drop_link(struct config_item *src,
2225					  struct config_item *target)
2226{
2227	struct config_item *streaming, *header;
2228	struct f_uvc_opts *opts;
2229	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2230	struct uvc_descriptor_header ***class_array;
2231	struct uvcg_streaming_header *target_hdr;
 
2232
2233	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2234
2235	streaming = src->ci_parent->ci_parent;
2236	header = config_group_find_item(to_config_group(streaming), "header");
2237	if (!header || target->ci_parent != header)
2238		goto out;
2239
2240	opts = to_f_uvc_opts(streaming->ci_parent);
2241
2242	mutex_lock(&opts->lock);
2243
2244	class_array = __uvcg_get_stream_class_arr(src, opts);
2245	if (!class_array || !*class_array)
2246		goto unlock;
2247
2248	if (opts->refcnt)
 
2249		goto unlock;
 
2250
2251	target_hdr = to_uvcg_streaming_header(target);
2252	--target_hdr->linked;
2253	kfree(**class_array);
2254	kfree(*class_array);
2255	*class_array = NULL;
 
2256
2257unlock:
2258	mutex_unlock(&opts->lock);
2259out:
2260	config_item_put(header);
2261	mutex_unlock(su_mutex);
 
2262}
2263
2264static struct configfs_item_operations uvcg_streaming_class_item_ops = {
2265	.release	= uvcg_config_item_release,
2266	.allow_link	= uvcg_streaming_class_allow_link,
2267	.drop_link	= uvcg_streaming_class_drop_link,
2268};
2269
2270static const struct config_item_type uvcg_streaming_class_type = {
2271	.ct_item_ops	= &uvcg_streaming_class_item_ops,
2272	.ct_owner	= THIS_MODULE,
2273};
2274
2275/* -----------------------------------------------------------------------------
2276 * streaming/class
2277 */
2278
2279static int uvcg_streaming_class_create_children(struct config_group *parent)
2280{
2281	static const char * const names[] = { "fs", "hs", "ss" };
2282	unsigned int i;
2283
2284	for (i = 0; i < ARRAY_SIZE(names); ++i) {
2285		struct uvcg_streaming_class_group *group;
2286
2287		group = kzalloc(sizeof(*group), GFP_KERNEL);
2288		if (!group)
2289			return -ENOMEM;
2290
2291		group->name = names[i];
2292
2293		config_group_init_type_name(&group->group, group->name,
2294					    &uvcg_streaming_class_type);
2295		configfs_add_default_group(&group->group, parent);
2296	}
2297
2298	return 0;
2299}
 
 
2300
2301static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = {
2302	.type = {
2303		.ct_item_ops	= &uvcg_config_item_ops,
2304		.ct_owner	= THIS_MODULE,
2305	},
2306	.name = "class",
2307	.create_children = uvcg_streaming_class_create_children,
2308};
2309
2310/* -----------------------------------------------------------------------------
2311 * streaming
2312 */
2313
2314static ssize_t uvcg_default_streaming_b_interface_number_show(
2315	struct config_item *item, char *page)
2316{
2317	struct config_group *group = to_config_group(item);
2318	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
2319	struct config_item *opts_item;
2320	struct f_uvc_opts *opts;
2321	int result = 0;
2322
2323	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2324
2325	opts_item = item->ci_parent;
2326	opts = to_f_uvc_opts(opts_item);
2327
2328	mutex_lock(&opts->lock);
2329	result += sprintf(page, "%u\n", opts->streaming_interface);
2330	mutex_unlock(&opts->lock);
2331
2332	mutex_unlock(su_mutex);
2333
2334	return result;
2335}
2336
2337UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber);
2338
2339static struct configfs_attribute *uvcg_default_streaming_attrs[] = {
2340	&uvcg_default_streaming_attr_b_interface_number,
2341	NULL,
2342};
2343
2344static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
2345	.type = {
2346		.ct_item_ops	= &uvcg_config_item_ops,
2347		.ct_attrs	= uvcg_default_streaming_attrs,
2348		.ct_owner	= THIS_MODULE,
2349	},
2350	.name = "streaming",
2351	.children = (const struct uvcg_config_group_type*[]) {
2352		&uvcg_streaming_header_grp_type,
2353		&uvcg_uncompressed_grp_type,
2354		&uvcg_mjpeg_grp_type,
2355		&uvcg_color_matching_grp_type,
2356		&uvcg_streaming_class_grp_type,
2357		NULL,
2358	},
2359};
2360
2361/* -----------------------------------------------------------------------------
2362 * UVC function
2363 */
2364
2365static void uvc_func_item_release(struct config_item *item)
2366{
2367	struct f_uvc_opts *opts = to_f_uvc_opts(item);
2368
2369	uvcg_config_remove_children(to_config_group(item));
2370	usb_put_function_instance(&opts->func_inst);
2371}
2372
2373static struct configfs_item_operations uvc_func_item_ops = {
2374	.release	= uvc_func_item_release,
2375};
2376
2377#define UVCG_OPTS_ATTR(cname, aname, limit)				\
2378static ssize_t f_uvc_opts_##cname##_show(				\
2379	struct config_item *item, char *page)				\
2380{									\
2381	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2382	int result;							\
2383									\
2384	mutex_lock(&opts->lock);					\
2385	result = sprintf(page, "%u\n", opts->cname);			\
2386	mutex_unlock(&opts->lock);					\
2387									\
2388	return result;							\
2389}									\
2390									\
2391static ssize_t								\
2392f_uvc_opts_##cname##_store(struct config_item *item,			\
2393			   const char *page, size_t len)		\
2394{									\
2395	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2396	unsigned int num;						\
2397	int ret;							\
 
2398									\
2399	mutex_lock(&opts->lock);					\
2400	if (opts->refcnt) {						\
2401		ret = -EBUSY;						\
2402		goto end;						\
2403	}								\
2404									\
2405	ret = kstrtouint(page, 0, &num);				\
2406	if (ret)							\
2407		goto end;						\
2408									\
2409	if (num > limit) {						\
2410		ret = -EINVAL;						\
2411		goto end;						\
2412	}								\
2413	opts->cname = num;						\
2414	ret = len;							\
2415end:									\
2416	mutex_unlock(&opts->lock);					\
2417	return ret;							\
2418}									\
2419									\
2420UVC_ATTR(f_uvc_opts_, cname, cname)
2421
2422UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
2423UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
2424UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
 
 
 
 
 
 
 
2425
2426#undef UVCG_OPTS_ATTR
2427
2428static struct configfs_attribute *uvc_attrs[] = {
2429	&f_uvc_opts_attr_streaming_interval,
2430	&f_uvc_opts_attr_streaming_maxpacket,
2431	&f_uvc_opts_attr_streaming_maxburst,
2432	NULL,
2433};
2434
2435static const struct uvcg_config_group_type uvc_func_type = {
2436	.type = {
2437		.ct_item_ops	= &uvc_func_item_ops,
2438		.ct_attrs	= uvc_attrs,
2439		.ct_owner	= THIS_MODULE,
2440	},
2441	.name = "",
2442	.children = (const struct uvcg_config_group_type*[]) {
2443		&uvcg_control_grp_type,
2444		&uvcg_streaming_grp_type,
2445		NULL,
2446	},
2447};
2448
2449int uvcg_attach_configfs(struct f_uvc_opts *opts)
2450{
2451	int ret;
2452
2453	config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
2454				    &uvc_func_type.type);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2455
2456	ret = uvcg_config_create_children(&opts->func_inst.group,
2457					  &uvc_func_type);
2458	if (ret < 0)
2459		config_group_put(&opts->func_inst.group);
2460
2461	return ret;
2462}
v4.6
 
   1/*
   2 * uvc_configfs.c
   3 *
   4 * Configfs support for the uvc function.
   5 *
   6 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
   7 *		http://www.samsung.com
   8 *
   9 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
 
 
 
  15#include "u_uvc.h"
  16#include "uvc_configfs.h"
  17
 
 
 
 
  18#define UVCG_STREAMING_CONTROL_SIZE	1
  19
  20#define UVC_ATTR(prefix, cname, aname) \
  21static struct configfs_attribute prefix##attr_##cname = { \
  22	.ca_name	= __stringify(aname),				\
  23	.ca_mode	= S_IRUGO | S_IWUGO,				\
  24	.ca_owner	= THIS_MODULE,					\
  25	.show		= prefix##cname##_show,				\
  26	.store		= prefix##cname##_store,			\
  27}
  28
  29#define UVC_ATTR_RO(prefix, cname, aname) \
  30static struct configfs_attribute prefix##attr_##cname = { \
  31	.ca_name	= __stringify(aname),				\
  32	.ca_mode	= S_IRUGO,					\
  33	.ca_owner	= THIS_MODULE,					\
  34	.show		= prefix##cname##_show,				\
  35}
  36
  37static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  38
  39/* control/header/<NAME> */
  40DECLARE_UVC_HEADER_DESCRIPTOR(1);
  41
  42struct uvcg_control_header {
  43	struct config_item		item;
  44	struct UVC_HEADER_DESCRIPTOR(1)	desc;
  45	unsigned			linked;
  46};
  47
  48static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item)
  49{
  50	return container_of(item, struct uvcg_control_header, item);
  51}
  52
  53#define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit)	\
  54static ssize_t uvcg_control_header_##cname##_show(			\
  55	struct config_item *item, char *page)			\
  56{									\
  57	struct uvcg_control_header *ch = to_uvcg_control_header(item);	\
  58	struct f_uvc_opts *opts;					\
  59	struct config_item *opts_item;					\
  60	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
  61	int result;							\
  62									\
  63	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
  64									\
  65	opts_item = ch->item.ci_parent->ci_parent->ci_parent;		\
  66	opts = to_f_uvc_opts(opts_item);				\
  67									\
  68	mutex_lock(&opts->lock);					\
  69	result = sprintf(page, "%d\n", conv(ch->desc.aname));		\
  70	mutex_unlock(&opts->lock);					\
  71									\
  72	mutex_unlock(su_mutex);						\
  73	return result;							\
  74}									\
  75									\
  76static ssize_t								\
  77uvcg_control_header_##cname##_store(struct config_item *item,		\
  78			   const char *page, size_t len)		\
  79{									\
  80	struct uvcg_control_header *ch = to_uvcg_control_header(item);	\
  81	struct f_uvc_opts *opts;					\
  82	struct config_item *opts_item;					\
  83	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
  84	int ret;							\
  85	uxx num;							\
  86									\
  87	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
  88									\
  89	opts_item = ch->item.ci_parent->ci_parent->ci_parent;		\
  90	opts = to_f_uvc_opts(opts_item);				\
  91									\
  92	mutex_lock(&opts->lock);					\
  93	if (ch->linked || opts->refcnt) {				\
  94		ret = -EBUSY;						\
  95		goto end;						\
  96	}								\
  97									\
  98	ret = str2u(page, 0, &num);					\
  99	if (ret)							\
 100		goto end;						\
 101									\
 102	if (num > limit) {						\
 103		ret = -EINVAL;						\
 104		goto end;						\
 105	}								\
 106	ch->desc.aname = vnoc(num);					\
 107	ret = len;							\
 108end:									\
 109	mutex_unlock(&opts->lock);					\
 110	mutex_unlock(su_mutex);						\
 111	return ret;							\
 112}									\
 113									\
 114UVC_ATTR(uvcg_control_header_, cname, aname)
 115
 116UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16,
 117		   0xffff);
 118
 119UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32,
 120		   u32, cpu_to_le32, 0x7fffffff);
 121
 122#undef UVCG_CTRL_HDR_ATTR
 123
 124static struct configfs_attribute *uvcg_control_header_attrs[] = {
 125	&uvcg_control_header_attr_bcd_uvc,
 126	&uvcg_control_header_attr_dw_clock_frequency,
 127	NULL,
 128};
 129
 130static struct config_item_type uvcg_control_header_type = {
 
 131	.ct_attrs	= uvcg_control_header_attrs,
 132	.ct_owner	= THIS_MODULE,
 133};
 134
 135static struct config_item *uvcg_control_header_make(struct config_group *group,
 136						    const char *name)
 137{
 138	struct uvcg_control_header *h;
 139
 140	h = kzalloc(sizeof(*h), GFP_KERNEL);
 141	if (!h)
 142		return ERR_PTR(-ENOMEM);
 143
 144	h->desc.bLength			= UVC_DT_HEADER_SIZE(1);
 145	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
 146	h->desc.bDescriptorSubType	= UVC_VC_HEADER;
 147	h->desc.bcdUVC			= cpu_to_le16(0x0100);
 148	h->desc.dwClockFrequency	= cpu_to_le32(48000000);
 149
 150	config_item_init_type_name(&h->item, name, &uvcg_control_header_type);
 151
 152	return &h->item;
 153}
 154
 155static void uvcg_control_header_drop(struct config_group *group,
 156			      struct config_item *item)
 157{
 158	struct uvcg_control_header *h = to_uvcg_control_header(item);
 159
 160	kfree(h);
 161}
 162
 163/* control/header */
 164static struct uvcg_control_header_grp {
 165	struct config_group	group;
 166} uvcg_control_header_grp;
 167
 168static struct configfs_group_operations uvcg_control_header_grp_ops = {
 169	.make_item		= uvcg_control_header_make,
 170	.drop_item		= uvcg_control_header_drop,
 171};
 172
 173static struct config_item_type uvcg_control_header_grp_type = {
 174	.ct_group_ops	= &uvcg_control_header_grp_ops,
 175	.ct_owner	= THIS_MODULE,
 
 
 
 
 176};
 177
 178/* control/processing/default */
 179static struct uvcg_default_processing {
 180	struct config_group	group;
 181} uvcg_default_processing;
 182
 183static inline struct uvcg_default_processing
 184*to_uvcg_default_processing(struct config_item *item)
 185{
 186	return container_of(to_config_group(item),
 187			    struct uvcg_default_processing, group);
 188}
 189
 190#define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv)		\
 191static ssize_t uvcg_default_processing_##cname##_show(			\
 192	struct config_item *item, char *page)				\
 193{									\
 194	struct uvcg_default_processing *dp = to_uvcg_default_processing(item); \
 195	struct f_uvc_opts *opts;					\
 196	struct config_item *opts_item;					\
 197	struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;	\
 198	struct uvc_processing_unit_descriptor *pd;			\
 199	int result;							\
 200									\
 201	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 202									\
 203	opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;	\
 204	opts = to_f_uvc_opts(opts_item);				\
 205	pd = &opts->uvc_processing;					\
 206									\
 207	mutex_lock(&opts->lock);					\
 208	result = sprintf(page, "%d\n", conv(pd->aname));		\
 209	mutex_unlock(&opts->lock);					\
 210									\
 211	mutex_unlock(su_mutex);						\
 212	return result;							\
 213}									\
 214									\
 215UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
 216
 217#define identity_conv(x) (x)
 218
 219UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv);
 220UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv);
 221UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu);
 222UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv);
 223
 224#undef identity_conv
 225
 226#undef UVCG_DEFAULT_PROCESSING_ATTR
 227
 228static ssize_t uvcg_default_processing_bm_controls_show(
 229	struct config_item *item, char *page)
 230{
 231	struct uvcg_default_processing *dp = to_uvcg_default_processing(item);
 232	struct f_uvc_opts *opts;
 233	struct config_item *opts_item;
 234	struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;
 235	struct uvc_processing_unit_descriptor *pd;
 236	int result, i;
 237	char *pg = page;
 238
 239	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 240
 241	opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;
 242	opts = to_f_uvc_opts(opts_item);
 243	pd = &opts->uvc_processing;
 244
 245	mutex_lock(&opts->lock);
 246	for (result = 0, i = 0; i < pd->bControlSize; ++i) {
 247		result += sprintf(pg, "%d\n", pd->bmControls[i]);
 248		pg = page + result;
 249	}
 250	mutex_unlock(&opts->lock);
 251
 252	mutex_unlock(su_mutex);
 253
 254	return result;
 255}
 256
 257UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls);
 258
 259static struct configfs_attribute *uvcg_default_processing_attrs[] = {
 260	&uvcg_default_processing_attr_b_unit_id,
 261	&uvcg_default_processing_attr_b_source_id,
 262	&uvcg_default_processing_attr_w_max_multiplier,
 263	&uvcg_default_processing_attr_bm_controls,
 264	&uvcg_default_processing_attr_i_processing,
 265	NULL,
 266};
 267
 268static struct config_item_type uvcg_default_processing_type = {
 269	.ct_attrs	= uvcg_default_processing_attrs,
 270	.ct_owner	= THIS_MODULE,
 
 
 
 
 271};
 272
 273/* struct uvcg_processing {}; */
 
 
 274
 275/* control/processing */
 276static struct uvcg_processing_grp {
 277	struct config_group	group;
 278} uvcg_processing_grp;
 279
 280static struct config_item_type uvcg_processing_grp_type = {
 281	.ct_owner = THIS_MODULE,
 
 
 
 282};
 283
 284/* control/terminal/camera/default */
 285static struct uvcg_default_camera {
 286	struct config_group	group;
 287} uvcg_default_camera;
 288
 289static inline struct uvcg_default_camera
 290*to_uvcg_default_camera(struct config_item *item)
 291{
 292	return container_of(to_config_group(item),
 293			    struct uvcg_default_camera, group);
 294}
 295
 296#define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv)			\
 297static ssize_t uvcg_default_camera_##cname##_show(			\
 298	struct config_item *item, char *page)				\
 299{									\
 300	struct uvcg_default_camera *dc = to_uvcg_default_camera(item);	\
 301	struct f_uvc_opts *opts;					\
 302	struct config_item *opts_item;					\
 303	struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;	\
 304	struct uvc_camera_terminal_descriptor *cd;			\
 305	int result;							\
 306									\
 307	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 308									\
 309	opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent->	\
 310			ci_parent;					\
 311	opts = to_f_uvc_opts(opts_item);				\
 312	cd = &opts->uvc_camera_terminal;				\
 313									\
 314	mutex_lock(&opts->lock);					\
 315	result = sprintf(page, "%d\n", conv(cd->aname));		\
 316	mutex_unlock(&opts->lock);					\
 317									\
 318	mutex_unlock(su_mutex);						\
 319									\
 320	return result;							\
 321}									\
 322									\
 323UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
 324
 325#define identity_conv(x) (x)
 326
 327UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv);
 328UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
 329UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
 330UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv);
 331UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin,
 332			 le16_to_cpu);
 333UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax,
 334			 le16_to_cpu);
 335UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength,
 336			 le16_to_cpu);
 337
 338#undef identity_conv
 339
 340#undef UVCG_DEFAULT_CAMERA_ATTR
 341
 342static ssize_t uvcg_default_camera_bm_controls_show(
 343	struct config_item *item, char *page)
 344{
 345	struct uvcg_default_camera *dc = to_uvcg_default_camera(item);
 346	struct f_uvc_opts *opts;
 347	struct config_item *opts_item;
 348	struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;
 349	struct uvc_camera_terminal_descriptor *cd;
 350	int result, i;
 351	char *pg = page;
 352
 353	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 354
 355	opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent->
 356			ci_parent;
 357	opts = to_f_uvc_opts(opts_item);
 358	cd = &opts->uvc_camera_terminal;
 359
 360	mutex_lock(&opts->lock);
 361	for (result = 0, i = 0; i < cd->bControlSize; ++i) {
 362		result += sprintf(pg, "%d\n", cd->bmControls[i]);
 363		pg = page + result;
 364	}
 365	mutex_unlock(&opts->lock);
 366
 367	mutex_unlock(su_mutex);
 368	return result;
 369}
 370
 371UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls);
 372
 373static struct configfs_attribute *uvcg_default_camera_attrs[] = {
 374	&uvcg_default_camera_attr_b_terminal_id,
 375	&uvcg_default_camera_attr_w_terminal_type,
 376	&uvcg_default_camera_attr_b_assoc_terminal,
 377	&uvcg_default_camera_attr_i_terminal,
 378	&uvcg_default_camera_attr_w_objective_focal_length_min,
 379	&uvcg_default_camera_attr_w_objective_focal_length_max,
 380	&uvcg_default_camera_attr_w_ocular_focal_length,
 381	&uvcg_default_camera_attr_bm_controls,
 382	NULL,
 383};
 384
 385static struct config_item_type uvcg_default_camera_type = {
 386	.ct_attrs	= uvcg_default_camera_attrs,
 387	.ct_owner	= THIS_MODULE,
 
 
 
 
 388};
 389
 390/* struct uvcg_camera {}; */
 391
 392/* control/terminal/camera */
 393static struct uvcg_camera_grp {
 394	struct config_group	group;
 395} uvcg_camera_grp;
 396
 397static struct config_item_type uvcg_camera_grp_type = {
 398	.ct_owner = THIS_MODULE,
 
 
 
 
 
 
 
 
 399};
 400
 401/* control/terminal/output/default */
 402static struct uvcg_default_output {
 403	struct config_group	group;
 404} uvcg_default_output;
 405
 406static inline struct uvcg_default_output
 407*to_uvcg_default_output(struct config_item *item)
 408{
 409	return container_of(to_config_group(item),
 410			    struct uvcg_default_output, group);
 411}
 412
 413#define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv)			\
 414static ssize_t uvcg_default_output_##cname##_show(			\
 415	struct config_item *item, char *page)			\
 416{									\
 417	struct uvcg_default_output *dout = to_uvcg_default_output(item); \
 418	struct f_uvc_opts *opts;					\
 419	struct config_item *opts_item;					\
 420	struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex;	\
 421	struct uvc_output_terminal_descriptor *cd;			\
 422	int result;							\
 423									\
 424	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 425									\
 426	opts_item = dout->group.cg_item.ci_parent->ci_parent->		\
 427			ci_parent->ci_parent;				\
 428	opts = to_f_uvc_opts(opts_item);				\
 429	cd = &opts->uvc_output_terminal;				\
 430									\
 431	mutex_lock(&opts->lock);					\
 432	result = sprintf(page, "%d\n", conv(cd->aname));		\
 433	mutex_unlock(&opts->lock);					\
 434									\
 435	mutex_unlock(su_mutex);						\
 436									\
 437	return result;							\
 438}									\
 439									\
 440UVC_ATTR_RO(uvcg_default_output_, cname, aname)
 441
 442#define identity_conv(x) (x)
 443
 444UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv);
 445UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
 446UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
 447UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv);
 448UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv);
 449
 450#undef identity_conv
 451
 452#undef UVCG_DEFAULT_OUTPUT_ATTR
 453
 454static struct configfs_attribute *uvcg_default_output_attrs[] = {
 455	&uvcg_default_output_attr_b_terminal_id,
 456	&uvcg_default_output_attr_w_terminal_type,
 457	&uvcg_default_output_attr_b_assoc_terminal,
 458	&uvcg_default_output_attr_b_source_id,
 459	&uvcg_default_output_attr_i_terminal,
 460	NULL,
 461};
 462
 463static struct config_item_type uvcg_default_output_type = {
 464	.ct_attrs	= uvcg_default_output_attrs,
 465	.ct_owner	= THIS_MODULE,
 
 
 
 
 466};
 467
 468/* struct uvcg_output {}; */
 469
 470/* control/terminal/output */
 471static struct uvcg_output_grp {
 472	struct config_group	group;
 473} uvcg_output_grp;
 474
 475static struct config_item_type uvcg_output_grp_type = {
 476	.ct_owner = THIS_MODULE,
 
 
 
 
 
 
 
 
 477};
 478
 479/* control/terminal */
 480static struct uvcg_terminal_grp {
 481	struct config_group	group;
 482} uvcg_terminal_grp;
 483
 484static struct config_item_type uvcg_terminal_grp_type = {
 485	.ct_owner = THIS_MODULE,
 
 
 
 
 
 
 
 
 
 486};
 487
 488/* control/class/{fs} */
 489static struct uvcg_control_class {
 490	struct config_group	group;
 491} uvcg_control_class_fs, uvcg_control_class_ss;
 492
 
 
 
 
 493
 494static inline struct uvc_descriptor_header
 495**uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
 496{
 497	struct uvcg_control_class *cl = container_of(to_config_group(i),
 498		struct uvcg_control_class, group);
 
 499
 500	if (cl == &uvcg_control_class_fs)
 501		return o->uvc_fs_control_cls;
 502
 503	if (cl == &uvcg_control_class_ss)
 504		return o->uvc_ss_control_cls;
 505
 506	return NULL;
 507}
 508
 509static int uvcg_control_class_allow_link(struct config_item *src,
 510					 struct config_item *target)
 511{
 512	struct config_item *control, *header;
 513	struct f_uvc_opts *opts;
 514	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
 515	struct uvc_descriptor_header **class_array;
 516	struct uvcg_control_header *target_hdr;
 517	int ret = -EINVAL;
 518
 519	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 520
 521	control = src->ci_parent->ci_parent;
 522	header = config_group_find_item(to_config_group(control), "header");
 523	if (!header || target->ci_parent != header)
 524		goto out;
 525
 526	opts = to_f_uvc_opts(control->ci_parent);
 527
 528	mutex_lock(&opts->lock);
 529
 530	class_array = uvcg_get_ctl_class_arr(src, opts);
 531	if (!class_array)
 532		goto unlock;
 533	if (opts->refcnt || class_array[0]) {
 534		ret = -EBUSY;
 535		goto unlock;
 536	}
 537
 538	target_hdr = to_uvcg_control_header(target);
 539	++target_hdr->linked;
 540	class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc;
 541	ret = 0;
 542
 543unlock:
 544	mutex_unlock(&opts->lock);
 545out:
 
 546	mutex_unlock(su_mutex);
 547	return ret;
 548}
 549
 550static int uvcg_control_class_drop_link(struct config_item *src,
 551					struct config_item *target)
 552{
 553	struct config_item *control, *header;
 554	struct f_uvc_opts *opts;
 555	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
 556	struct uvc_descriptor_header **class_array;
 557	struct uvcg_control_header *target_hdr;
 558	int ret = -EINVAL;
 559
 560	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 561
 562	control = src->ci_parent->ci_parent;
 563	header = config_group_find_item(to_config_group(control), "header");
 564	if (!header || target->ci_parent != header)
 565		goto out;
 566
 567	opts = to_f_uvc_opts(control->ci_parent);
 568
 569	mutex_lock(&opts->lock);
 570
 571	class_array = uvcg_get_ctl_class_arr(src, opts);
 572	if (!class_array)
 573		goto unlock;
 574	if (opts->refcnt) {
 575		ret = -EBUSY;
 576		goto unlock;
 577	}
 578
 579	target_hdr = to_uvcg_control_header(target);
 580	--target_hdr->linked;
 581	class_array[0] = NULL;
 582	ret = 0;
 583
 584unlock:
 585	mutex_unlock(&opts->lock);
 586out:
 
 587	mutex_unlock(su_mutex);
 588	return ret;
 589}
 590
 591static struct configfs_item_operations uvcg_control_class_item_ops = {
 
 592	.allow_link	= uvcg_control_class_allow_link,
 593	.drop_link	= uvcg_control_class_drop_link,
 594};
 595
 596static struct config_item_type uvcg_control_class_type = {
 597	.ct_item_ops	= &uvcg_control_class_item_ops,
 598	.ct_owner	= THIS_MODULE,
 599};
 600
 601/* control/class */
 602static struct uvcg_control_class_grp {
 603	struct config_group	group;
 604} uvcg_control_class_grp;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 605
 606static struct config_item_type uvcg_control_class_grp_type = {
 607	.ct_owner = THIS_MODULE,
 
 
 
 
 
 608};
 609
 610/* control */
 611static struct uvcg_control_grp {
 612	struct config_group	group;
 613} uvcg_control_grp;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 614
 615static struct config_item_type uvcg_control_grp_type = {
 616	.ct_owner = THIS_MODULE,
 
 617};
 618
 619/* streaming/uncompressed */
 620static struct uvcg_uncompressed_grp {
 621	struct config_group	group;
 622} uvcg_uncompressed_grp;
 623
 624/* streaming/mjpeg */
 625static struct uvcg_mjpeg_grp {
 626	struct config_group	group;
 627} uvcg_mjpeg_grp;
 
 
 
 
 
 
 
 
 
 
 
 628
 629static struct config_item *fmt_parent[] = {
 630	&uvcg_uncompressed_grp.group.cg_item,
 631	&uvcg_mjpeg_grp.group.cg_item,
 632};
 633
 634enum uvcg_format_type {
 635	UVCG_UNCOMPRESSED = 0,
 636	UVCG_MJPEG,
 637};
 638
 639struct uvcg_format {
 640	struct config_group	group;
 641	enum uvcg_format_type	type;
 642	unsigned		linked;
 643	unsigned		num_frames;
 644	__u8			bmaControls[UVCG_STREAMING_CONTROL_SIZE];
 645};
 646
 647static struct uvcg_format *to_uvcg_format(struct config_item *item)
 648{
 649	return container_of(to_config_group(item), struct uvcg_format, group);
 650}
 651
 652static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
 653{
 654	struct f_uvc_opts *opts;
 655	struct config_item *opts_item;
 656	struct mutex *su_mutex = &f->group.cg_subsys->su_mutex;
 657	int result, i;
 658	char *pg = page;
 659
 660	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 661
 662	opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent;
 663	opts = to_f_uvc_opts(opts_item);
 664
 665	mutex_lock(&opts->lock);
 666	result = sprintf(pg, "0x");
 667	pg += result;
 668	for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) {
 669		result += sprintf(pg, "%x\n", f->bmaControls[i]);
 670		pg = page + result;
 671	}
 672	mutex_unlock(&opts->lock);
 673
 674	mutex_unlock(su_mutex);
 675	return result;
 676}
 677
 678static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch,
 679					      const char *page, size_t len)
 680{
 681	struct f_uvc_opts *opts;
 682	struct config_item *opts_item;
 683	struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex;
 684	int ret = -EINVAL;
 685
 686	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 687
 688	opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent;
 689	opts = to_f_uvc_opts(opts_item);
 690
 691	mutex_lock(&opts->lock);
 692	if (ch->linked || opts->refcnt) {
 693		ret = -EBUSY;
 694		goto end;
 695	}
 696
 697	if (len < 4 || *page != '0' ||
 698	    (*(page + 1) != 'x' && *(page + 1) != 'X'))
 699		goto end;
 700	ret = hex2bin(ch->bmaControls, page + 2, 1);
 701	if (ret < 0)
 702		goto end;
 703	ret = len;
 704end:
 705	mutex_unlock(&opts->lock);
 706	mutex_unlock(su_mutex);
 707	return ret;
 708}
 709
 710struct uvcg_format_ptr {
 711	struct uvcg_format	*fmt;
 712	struct list_head	entry;
 713};
 714
 715/* streaming/header/<NAME> */
 
 
 
 
 716struct uvcg_streaming_header {
 717	struct config_item				item;
 718	struct uvc_input_header_descriptor		desc;
 719	unsigned					linked;
 720	struct list_head				formats;
 721	unsigned					num_fmt;
 722};
 723
 724static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item)
 725{
 726	return container_of(item, struct uvcg_streaming_header, item);
 727}
 728
 
 
 729static int uvcg_streaming_header_allow_link(struct config_item *src,
 730					    struct config_item *target)
 731{
 732	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
 733	struct config_item *opts_item;
 734	struct f_uvc_opts *opts;
 735	struct uvcg_streaming_header *src_hdr;
 736	struct uvcg_format *target_fmt = NULL;
 737	struct uvcg_format_ptr *format_ptr;
 738	int i, ret = -EINVAL;
 739
 740	src_hdr = to_uvcg_streaming_header(src);
 741	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 742
 743	opts_item = src->ci_parent->ci_parent->ci_parent;
 744	opts = to_f_uvc_opts(opts_item);
 745
 746	mutex_lock(&opts->lock);
 747
 748	if (src_hdr->linked) {
 749		ret = -EBUSY;
 750		goto out;
 751	}
 752
 753	for (i = 0; i < ARRAY_SIZE(fmt_parent); ++i)
 754		if (target->ci_parent == fmt_parent[i])
 
 
 
 
 
 
 
 
 
 
 755			break;
 756	if (i == ARRAY_SIZE(fmt_parent))
 
 
 757		goto out;
 758
 759	target_fmt = container_of(to_config_group(target), struct uvcg_format,
 760				  group);
 761	if (!target_fmt)
 762		goto out;
 763
 764	format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
 765	if (!format_ptr) {
 766		ret = -ENOMEM;
 767		goto out;
 768	}
 769	ret = 0;
 770	format_ptr->fmt = target_fmt;
 771	list_add_tail(&format_ptr->entry, &src_hdr->formats);
 772	++src_hdr->num_fmt;
 
 773
 774out:
 775	mutex_unlock(&opts->lock);
 776	mutex_unlock(su_mutex);
 777	return ret;
 778}
 779
 780static int uvcg_streaming_header_drop_link(struct config_item *src,
 781					   struct config_item *target)
 782{
 783	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
 784	struct config_item *opts_item;
 785	struct f_uvc_opts *opts;
 786	struct uvcg_streaming_header *src_hdr;
 787	struct uvcg_format *target_fmt = NULL;
 788	struct uvcg_format_ptr *format_ptr, *tmp;
 789	int ret = -EINVAL;
 790
 791	src_hdr = to_uvcg_streaming_header(src);
 792	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
 793
 794	opts_item = src->ci_parent->ci_parent->ci_parent;
 795	opts = to_f_uvc_opts(opts_item);
 796
 797	mutex_lock(&opts->lock);
 798	target_fmt = container_of(to_config_group(target), struct uvcg_format,
 799				  group);
 800	if (!target_fmt)
 801		goto out;
 802
 803	list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
 804		if (format_ptr->fmt == target_fmt) {
 805			list_del(&format_ptr->entry);
 806			kfree(format_ptr);
 807			--src_hdr->num_fmt;
 808			break;
 809		}
 810
 811out:
 
 812	mutex_unlock(&opts->lock);
 813	mutex_unlock(su_mutex);
 814	return ret;
 815
 816}
 817
 818static struct configfs_item_operations uvcg_streaming_header_item_ops = {
 819	.allow_link		= uvcg_streaming_header_allow_link,
 820	.drop_link		= uvcg_streaming_header_drop_link,
 
 821};
 822
 823#define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv)			\
 824static ssize_t uvcg_streaming_header_##cname##_show(			\
 825	struct config_item *item, char *page)			\
 826{									\
 827	struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
 828	struct f_uvc_opts *opts;					\
 829	struct config_item *opts_item;					\
 830	struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
 831	int result;							\
 832									\
 833	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 834									\
 835	opts_item = sh->item.ci_parent->ci_parent->ci_parent;		\
 836	opts = to_f_uvc_opts(opts_item);				\
 837									\
 838	mutex_lock(&opts->lock);					\
 839	result = sprintf(page, "%d\n", conv(sh->desc.aname));		\
 840	mutex_unlock(&opts->lock);					\
 841									\
 842	mutex_unlock(su_mutex);						\
 843	return result;							\
 844}									\
 845									\
 846UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
 847
 848#define identity_conv(x) (x)
 849
 850UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv);
 851UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv);
 852UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod,
 853			   identity_conv);
 854UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv);
 855UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv);
 856
 857#undef identity_conv
 858
 859#undef UVCG_STREAMING_HEADER_ATTR
 860
 861static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
 862	&uvcg_streaming_header_attr_bm_info,
 863	&uvcg_streaming_header_attr_b_terminal_link,
 864	&uvcg_streaming_header_attr_b_still_capture_method,
 865	&uvcg_streaming_header_attr_b_trigger_support,
 866	&uvcg_streaming_header_attr_b_trigger_usage,
 867	NULL,
 868};
 869
 870static struct config_item_type uvcg_streaming_header_type = {
 871	.ct_item_ops	= &uvcg_streaming_header_item_ops,
 872	.ct_attrs	= uvcg_streaming_header_attrs,
 873	.ct_owner	= THIS_MODULE,
 874};
 875
 876static struct config_item
 877*uvcg_streaming_header_make(struct config_group *group, const char *name)
 878{
 879	struct uvcg_streaming_header *h;
 880
 881	h = kzalloc(sizeof(*h), GFP_KERNEL);
 882	if (!h)
 883		return ERR_PTR(-ENOMEM);
 884
 885	INIT_LIST_HEAD(&h->formats);
 886	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
 887	h->desc.bDescriptorSubType	= UVC_VS_INPUT_HEADER;
 888	h->desc.bTerminalLink		= 3;
 889	h->desc.bControlSize		= UVCG_STREAMING_CONTROL_SIZE;
 890
 891	config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
 892
 893	return &h->item;
 894}
 895
 896static void uvcg_streaming_header_drop(struct config_group *group,
 897			      struct config_item *item)
 898{
 899	struct uvcg_streaming_header *h = to_uvcg_streaming_header(item);
 900
 901	kfree(h);
 902}
 903
 904/* streaming/header */
 905static struct uvcg_streaming_header_grp {
 906	struct config_group	group;
 907} uvcg_streaming_header_grp;
 908
 909static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
 910	.make_item		= uvcg_streaming_header_make,
 911	.drop_item		= uvcg_streaming_header_drop,
 912};
 913
 914static struct config_item_type uvcg_streaming_header_grp_type = {
 915	.ct_group_ops	= &uvcg_streaming_header_grp_ops,
 916	.ct_owner	= THIS_MODULE,
 
 
 
 
 917};
 918
 919/* streaming/<mode>/<format>/<NAME> */
 
 
 
 920struct uvcg_frame {
 
 
 921	struct {
 922		u8	b_length;
 923		u8	b_descriptor_type;
 924		u8	b_descriptor_subtype;
 925		u8	b_frame_index;
 926		u8	bm_capabilities;
 927		u16	w_width;
 928		u16	w_height;
 929		u32	dw_min_bit_rate;
 930		u32	dw_max_bit_rate;
 931		u32	dw_max_video_frame_buffer_size;
 932		u32	dw_default_frame_interval;
 933		u8	b_frame_interval_type;
 934	} __attribute__((packed)) frame;
 935	u32 *dw_frame_interval;
 936	enum uvcg_format_type	fmt_type;
 937	struct config_item	item;
 938};
 939
 940static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
 941{
 942	return container_of(item, struct uvcg_frame, item);
 943}
 944
 945#define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
 946static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
 947{									\
 948	struct uvcg_frame *f = to_uvcg_frame(item);			\
 949	struct f_uvc_opts *opts;					\
 950	struct config_item *opts_item;					\
 951	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
 952	int result;							\
 953									\
 954	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 955									\
 956	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
 957	opts = to_f_uvc_opts(opts_item);				\
 958									\
 959	mutex_lock(&opts->lock);					\
 960	result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname));	\
 961	mutex_unlock(&opts->lock);					\
 962									\
 963	mutex_unlock(su_mutex);						\
 964	return result;							\
 965}									\
 966									\
 967static ssize_t  uvcg_frame_##cname##_store(struct config_item *item,	\
 968					   const char *page, size_t len)\
 969{									\
 970	struct uvcg_frame *f = to_uvcg_frame(item);			\
 971	struct f_uvc_opts *opts;					\
 972	struct config_item *opts_item;					\
 973	struct uvcg_format *fmt;					\
 974	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
 
 975	int ret;							\
 976	u##bits num;							\
 977									\
 978	ret = kstrtou##bits(page, 0, &num);				\
 979	if (ret)							\
 980		return ret;						\
 981									\
 982	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
 983									\
 984	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
 985	opts = to_f_uvc_opts(opts_item);				\
 986	fmt = to_uvcg_format(f->item.ci_parent);			\
 987									\
 988	mutex_lock(&opts->lock);					\
 989	if (fmt->linked || opts->refcnt) {				\
 990		ret = -EBUSY;						\
 991		goto end;						\
 992	}								\
 993									\
 994	f->frame.cname = to_little_endian(num);				\
 995	ret = len;							\
 996end:									\
 997	mutex_unlock(&opts->lock);					\
 998	mutex_unlock(su_mutex);						\
 999	return ret;							\
1000}									\
1001									\
1002UVC_ATTR(uvcg_frame_, cname, aname);
1003
1004#define noop_conversion(x) (x)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1005
1006UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
1007		noop_conversion, 8);
1008UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
1009UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16);
1010UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32);
1011UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32);
1012UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize,
1013		le32_to_cpu, cpu_to_le32, 32);
1014UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval,
1015		le32_to_cpu, cpu_to_le32, 32);
1016
1017#undef noop_conversion
 
 
 
 
 
 
1018
1019#undef UVCG_FRAME_ATTR
1020
1021static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
1022						 char *page)
1023{
1024	struct uvcg_frame *frm = to_uvcg_frame(item);
1025	struct f_uvc_opts *opts;
1026	struct config_item *opts_item;
1027	struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
1028	int result, i;
1029	char *pg = page;
1030
1031	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1032
1033	opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
1034	opts = to_f_uvc_opts(opts_item);
1035
1036	mutex_lock(&opts->lock);
1037	for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
1038		result += sprintf(pg, "%d\n",
1039				  le32_to_cpu(frm->dw_frame_interval[i]));
1040		pg = page + result;
1041	}
1042	mutex_unlock(&opts->lock);
1043
1044	mutex_unlock(su_mutex);
1045	return result;
1046}
1047
1048static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1049{
1050	++*((int *)priv);
1051	return 0;
1052}
1053
1054static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
1055{
1056	u32 num, **interv;
1057	int ret;
1058
1059	ret = kstrtou32(buf, 0, &num);
1060	if (ret)
1061		return ret;
1062
1063	interv = priv;
1064	**interv = cpu_to_le32(num);
1065	++*interv;
1066
1067	return 0;
1068}
1069
1070static int __uvcg_iter_frm_intrv(const char *page, size_t len,
1071				 int (*fun)(char *, void *), void *priv)
1072{
1073	/* sign, base 2 representation, newline, terminator */
1074	char buf[1 + sizeof(u32) * 8 + 1 + 1];
1075	const char *pg = page;
1076	int i, ret;
1077
1078	if (!fun)
1079		return -EINVAL;
1080
1081	while (pg - page < len) {
1082		i = 0;
1083		while (i < sizeof(buf) && (pg - page < len) &&
1084				*pg != '\0' && *pg != '\n')
1085			buf[i++] = *pg++;
1086		if (i == sizeof(buf))
1087			return -EINVAL;
1088		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
1089			++pg;
1090		buf[i] = '\0';
1091		ret = fun(buf, priv);
1092		if (ret)
1093			return ret;
1094	}
1095
1096	return 0;
1097}
1098
1099static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
1100						  const char *page, size_t len)
1101{
1102	struct uvcg_frame *ch = to_uvcg_frame(item);
1103	struct f_uvc_opts *opts;
1104	struct config_item *opts_item;
1105	struct uvcg_format *fmt;
1106	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
1107	int ret = 0, n = 0;
1108	u32 *frm_intrv, *tmp;
1109
1110	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1111
1112	opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
1113	opts = to_f_uvc_opts(opts_item);
1114	fmt = to_uvcg_format(ch->item.ci_parent);
1115
1116	mutex_lock(&opts->lock);
1117	if (fmt->linked || opts->refcnt) {
1118		ret = -EBUSY;
1119		goto end;
1120	}
1121
1122	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
1123	if (ret)
1124		goto end;
1125
1126	tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
1127	if (!frm_intrv) {
1128		ret = -ENOMEM;
1129		goto end;
1130	}
1131
1132	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
1133	if (ret) {
1134		kfree(frm_intrv);
1135		goto end;
1136	}
1137
1138	kfree(ch->dw_frame_interval);
1139	ch->dw_frame_interval = frm_intrv;
1140	ch->frame.b_frame_interval_type = n;
 
 
1141	ret = len;
1142
1143end:
1144	mutex_unlock(&opts->lock);
1145	mutex_unlock(su_mutex);
1146	return ret;
1147}
1148
1149UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
1150
1151static struct configfs_attribute *uvcg_frame_attrs[] = {
 
1152	&uvcg_frame_attr_bm_capabilities,
1153	&uvcg_frame_attr_w_width,
1154	&uvcg_frame_attr_w_height,
1155	&uvcg_frame_attr_dw_min_bit_rate,
1156	&uvcg_frame_attr_dw_max_bit_rate,
1157	&uvcg_frame_attr_dw_max_video_frame_buffer_size,
1158	&uvcg_frame_attr_dw_default_frame_interval,
1159	&uvcg_frame_attr_dw_frame_interval,
1160	NULL,
1161};
1162
1163static struct config_item_type uvcg_frame_type = {
 
1164	.ct_attrs	= uvcg_frame_attrs,
1165	.ct_owner	= THIS_MODULE,
1166};
1167
1168static struct config_item *uvcg_frame_make(struct config_group *group,
1169					   const char *name)
1170{
1171	struct uvcg_frame *h;
1172	struct uvcg_format *fmt;
1173	struct f_uvc_opts *opts;
1174	struct config_item *opts_item;
1175
1176	h = kzalloc(sizeof(*h), GFP_KERNEL);
1177	if (!h)
1178		return ERR_PTR(-ENOMEM);
1179
1180	h->frame.b_descriptor_type		= USB_DT_CS_INTERFACE;
1181	h->frame.b_frame_index			= 1;
1182	h->frame.w_width			= cpu_to_le16(640);
1183	h->frame.w_height			= cpu_to_le16(360);
1184	h->frame.dw_min_bit_rate		= cpu_to_le32(18432000);
1185	h->frame.dw_max_bit_rate		= cpu_to_le32(55296000);
1186	h->frame.dw_max_video_frame_buffer_size	= cpu_to_le32(460800);
1187	h->frame.dw_default_frame_interval	= cpu_to_le32(666666);
1188
1189	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1190	opts = to_f_uvc_opts(opts_item);
1191
1192	mutex_lock(&opts->lock);
1193	fmt = to_uvcg_format(&group->cg_item);
1194	if (fmt->type == UVCG_UNCOMPRESSED) {
1195		h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
1196		h->fmt_type = UVCG_UNCOMPRESSED;
1197	} else if (fmt->type == UVCG_MJPEG) {
1198		h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
1199		h->fmt_type = UVCG_MJPEG;
1200	} else {
1201		mutex_unlock(&opts->lock);
1202		kfree(h);
1203		return ERR_PTR(-EINVAL);
1204	}
1205	++fmt->num_frames;
1206	mutex_unlock(&opts->lock);
1207
1208	config_item_init_type_name(&h->item, name, &uvcg_frame_type);
1209
1210	return &h->item;
1211}
1212
1213static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
1214{
1215	struct uvcg_frame *h = to_uvcg_frame(item);
1216	struct uvcg_format *fmt;
1217	struct f_uvc_opts *opts;
1218	struct config_item *opts_item;
1219
1220	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1221	opts = to_f_uvc_opts(opts_item);
1222
1223	mutex_lock(&opts->lock);
1224	fmt = to_uvcg_format(&group->cg_item);
1225	--fmt->num_frames;
1226	kfree(h);
1227	mutex_unlock(&opts->lock);
 
 
1228}
1229
1230/* streaming/uncompressed/<NAME> */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1231struct uvcg_uncompressed {
1232	struct uvcg_format		fmt;
1233	struct uvc_format_uncompressed	desc;
1234};
1235
1236static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
1237{
1238	return container_of(
1239		container_of(to_config_group(item), struct uvcg_format, group),
1240		struct uvcg_uncompressed, fmt);
1241}
1242
1243static struct configfs_group_operations uvcg_uncompressed_group_ops = {
1244	.make_item		= uvcg_frame_make,
1245	.drop_item		= uvcg_frame_drop,
1246};
1247
1248static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
1249							char *page)
1250{
1251	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1252	struct f_uvc_opts *opts;
1253	struct config_item *opts_item;
1254	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1255
1256	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1257
1258	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1259	opts = to_f_uvc_opts(opts_item);
1260
1261	mutex_lock(&opts->lock);
1262	memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
1263	mutex_unlock(&opts->lock);
1264
1265	mutex_unlock(su_mutex);
1266
1267	return sizeof(ch->desc.guidFormat);
1268}
1269
1270static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
1271						   const char *page, size_t len)
1272{
1273	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1274	struct f_uvc_opts *opts;
1275	struct config_item *opts_item;
1276	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1277	int ret;
1278
1279	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1280
1281	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1282	opts = to_f_uvc_opts(opts_item);
1283
1284	mutex_lock(&opts->lock);
1285	if (ch->fmt.linked || opts->refcnt) {
1286		ret = -EBUSY;
1287		goto end;
1288	}
1289
1290	memcpy(ch->desc.guidFormat, page,
1291	       min(sizeof(ch->desc.guidFormat), len));
1292	ret = sizeof(ch->desc.guidFormat);
1293
1294end:
1295	mutex_unlock(&opts->lock);
1296	mutex_unlock(su_mutex);
1297	return ret;
1298}
1299
1300UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
1301
1302#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv)			\
1303static ssize_t uvcg_uncompressed_##cname##_show(			\
1304	struct config_item *item, char *page)				\
1305{									\
1306	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1307	struct f_uvc_opts *opts;					\
1308	struct config_item *opts_item;					\
1309	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1310	int result;							\
1311									\
1312	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1313									\
1314	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1315	opts = to_f_uvc_opts(opts_item);				\
1316									\
1317	mutex_lock(&opts->lock);					\
1318	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
1319	mutex_unlock(&opts->lock);					\
1320									\
1321	mutex_unlock(su_mutex);						\
1322	return result;							\
1323}									\
1324									\
1325UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
1326
1327#define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv)			\
1328static ssize_t uvcg_uncompressed_##cname##_show(			\
1329	struct config_item *item, char *page)				\
1330{									\
1331	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1332	struct f_uvc_opts *opts;					\
1333	struct config_item *opts_item;					\
1334	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1335	int result;							\
1336									\
1337	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1338									\
1339	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1340	opts = to_f_uvc_opts(opts_item);				\
1341									\
1342	mutex_lock(&opts->lock);					\
1343	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
1344	mutex_unlock(&opts->lock);					\
1345									\
1346	mutex_unlock(su_mutex);						\
1347	return result;							\
1348}									\
1349									\
1350static ssize_t								\
1351uvcg_uncompressed_##cname##_store(struct config_item *item,		\
1352				    const char *page, size_t len)	\
1353{									\
1354	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1355	struct f_uvc_opts *opts;					\
1356	struct config_item *opts_item;					\
1357	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1358	int ret;							\
1359	u8 num;								\
1360									\
1361	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1362									\
1363	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1364	opts = to_f_uvc_opts(opts_item);				\
1365									\
1366	mutex_lock(&opts->lock);					\
1367	if (u->fmt.linked || opts->refcnt) {				\
1368		ret = -EBUSY;						\
1369		goto end;						\
1370	}								\
1371									\
1372	ret = kstrtou8(page, 0, &num);					\
1373	if (ret)							\
1374		goto end;						\
1375									\
1376	if (num > 255) {						\
1377		ret = -EINVAL;						\
1378		goto end;						\
1379	}								\
1380	u->desc.aname = num;						\
1381	ret = len;							\
1382end:									\
1383	mutex_unlock(&opts->lock);					\
1384	mutex_unlock(su_mutex);						\
1385	return ret;							\
1386}									\
1387									\
1388UVC_ATTR(uvcg_uncompressed_, cname, aname);
1389
1390#define identity_conv(x) (x)
1391
1392UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv);
1393UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex,
1394		       identity_conv);
1395UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1396UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1397UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
1398
1399#undef identity_conv
1400
1401#undef UVCG_UNCOMPRESSED_ATTR
1402#undef UVCG_UNCOMPRESSED_ATTR_RO
1403
1404static inline ssize_t
1405uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
1406{
1407	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1408	return uvcg_format_bma_controls_show(&unc->fmt, page);
1409}
1410
1411static inline ssize_t
1412uvcg_uncompressed_bma_controls_store(struct config_item *item,
1413				     const char *page, size_t len)
1414{
1415	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1416	return uvcg_format_bma_controls_store(&unc->fmt, page, len);
1417}
1418
1419UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
1420
1421static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
 
1422	&uvcg_uncompressed_attr_guid_format,
1423	&uvcg_uncompressed_attr_b_bits_per_pixel,
1424	&uvcg_uncompressed_attr_b_default_frame_index,
1425	&uvcg_uncompressed_attr_b_aspect_ratio_x,
1426	&uvcg_uncompressed_attr_b_aspect_ratio_y,
1427	&uvcg_uncompressed_attr_bm_interface_flags,
1428	&uvcg_uncompressed_attr_bma_controls,
1429	NULL,
1430};
1431
1432static struct config_item_type uvcg_uncompressed_type = {
 
1433	.ct_group_ops	= &uvcg_uncompressed_group_ops,
1434	.ct_attrs	= uvcg_uncompressed_attrs,
1435	.ct_owner	= THIS_MODULE,
1436};
1437
1438static struct config_group *uvcg_uncompressed_make(struct config_group *group,
1439						   const char *name)
1440{
1441	static char guid[] = {
1442		'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
1443		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
1444	};
1445	struct uvcg_uncompressed *h;
1446
1447	h = kzalloc(sizeof(*h), GFP_KERNEL);
1448	if (!h)
1449		return ERR_PTR(-ENOMEM);
1450
1451	h->desc.bLength			= UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
1452	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1453	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED;
1454	memcpy(h->desc.guidFormat, guid, sizeof(guid));
1455	h->desc.bBitsPerPixel		= 16;
1456	h->desc.bDefaultFrameIndex	= 1;
1457	h->desc.bAspectRatioX		= 0;
1458	h->desc.bAspectRatioY		= 0;
1459	h->desc.bmInterfaceFlags	= 0;
1460	h->desc.bCopyProtect		= 0;
1461
1462	h->fmt.type = UVCG_UNCOMPRESSED;
1463	config_group_init_type_name(&h->fmt.group, name,
1464				    &uvcg_uncompressed_type);
1465
1466	return &h->fmt.group;
1467}
1468
1469static void uvcg_uncompressed_drop(struct config_group *group,
1470			    struct config_item *item)
1471{
1472	struct uvcg_uncompressed *h = to_uvcg_uncompressed(item);
1473
1474	kfree(h);
1475}
1476
1477static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
1478	.make_group		= uvcg_uncompressed_make,
1479	.drop_item		= uvcg_uncompressed_drop,
1480};
1481
1482static struct config_item_type uvcg_uncompressed_grp_type = {
1483	.ct_group_ops	= &uvcg_uncompressed_grp_ops,
1484	.ct_owner	= THIS_MODULE,
 
 
 
 
1485};
1486
1487/* streaming/mjpeg/<NAME> */
 
 
 
1488struct uvcg_mjpeg {
1489	struct uvcg_format		fmt;
1490	struct uvc_format_mjpeg		desc;
1491};
1492
1493static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
1494{
1495	return container_of(
1496		container_of(to_config_group(item), struct uvcg_format, group),
1497		struct uvcg_mjpeg, fmt);
1498}
1499
1500static struct configfs_group_operations uvcg_mjpeg_group_ops = {
1501	.make_item		= uvcg_frame_make,
1502	.drop_item		= uvcg_frame_drop,
1503};
1504
1505#define UVCG_MJPEG_ATTR_RO(cname, aname, conv)				\
1506static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1507{									\
1508	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1509	struct f_uvc_opts *opts;					\
1510	struct config_item *opts_item;					\
1511	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1512	int result;							\
1513									\
1514	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1515									\
1516	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1517	opts = to_f_uvc_opts(opts_item);				\
1518									\
1519	mutex_lock(&opts->lock);					\
1520	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
1521	mutex_unlock(&opts->lock);					\
1522									\
1523	mutex_unlock(su_mutex);						\
1524	return result;							\
1525}									\
1526									\
1527UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
1528
1529#define UVCG_MJPEG_ATTR(cname, aname, conv)				\
1530static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1531{									\
1532	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1533	struct f_uvc_opts *opts;					\
1534	struct config_item *opts_item;					\
1535	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1536	int result;							\
1537									\
1538	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1539									\
1540	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1541	opts = to_f_uvc_opts(opts_item);				\
1542									\
1543	mutex_lock(&opts->lock);					\
1544	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
1545	mutex_unlock(&opts->lock);					\
1546									\
1547	mutex_unlock(su_mutex);						\
1548	return result;							\
1549}									\
1550									\
1551static ssize_t								\
1552uvcg_mjpeg_##cname##_store(struct config_item *item,			\
1553			   const char *page, size_t len)		\
1554{									\
1555	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1556	struct f_uvc_opts *opts;					\
1557	struct config_item *opts_item;					\
1558	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1559	int ret;							\
1560	u8 num;								\
1561									\
1562	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1563									\
1564	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1565	opts = to_f_uvc_opts(opts_item);				\
1566									\
1567	mutex_lock(&opts->lock);					\
1568	if (u->fmt.linked || opts->refcnt) {				\
1569		ret = -EBUSY;						\
1570		goto end;						\
1571	}								\
1572									\
1573	ret = kstrtou8(page, 0, &num);					\
1574	if (ret)							\
1575		goto end;						\
1576									\
1577	if (num > 255) {						\
1578		ret = -EINVAL;						\
1579		goto end;						\
1580	}								\
1581	u->desc.aname = num;						\
1582	ret = len;							\
1583end:									\
1584	mutex_unlock(&opts->lock);					\
1585	mutex_unlock(su_mutex);						\
1586	return ret;							\
1587}									\
1588									\
1589UVC_ATTR(uvcg_mjpeg_, cname, aname)
1590
1591#define identity_conv(x) (x)
1592
1593UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex,
1594		       identity_conv);
1595UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv);
1596UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1597UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1598UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
1599
1600#undef identity_conv
1601
1602#undef UVCG_MJPEG_ATTR
1603#undef UVCG_MJPEG_ATTR_RO
1604
1605static inline ssize_t
1606uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
1607{
1608	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1609	return uvcg_format_bma_controls_show(&u->fmt, page);
1610}
1611
1612static inline ssize_t
1613uvcg_mjpeg_bma_controls_store(struct config_item *item,
1614				     const char *page, size_t len)
1615{
1616	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1617	return uvcg_format_bma_controls_store(&u->fmt, page, len);
1618}
1619
1620UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
1621
1622static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
 
1623	&uvcg_mjpeg_attr_b_default_frame_index,
1624	&uvcg_mjpeg_attr_bm_flags,
1625	&uvcg_mjpeg_attr_b_aspect_ratio_x,
1626	&uvcg_mjpeg_attr_b_aspect_ratio_y,
1627	&uvcg_mjpeg_attr_bm_interface_flags,
1628	&uvcg_mjpeg_attr_bma_controls,
1629	NULL,
1630};
1631
1632static struct config_item_type uvcg_mjpeg_type = {
 
1633	.ct_group_ops	= &uvcg_mjpeg_group_ops,
1634	.ct_attrs	= uvcg_mjpeg_attrs,
1635	.ct_owner	= THIS_MODULE,
1636};
1637
1638static struct config_group *uvcg_mjpeg_make(struct config_group *group,
1639						   const char *name)
1640{
1641	struct uvcg_mjpeg *h;
1642
1643	h = kzalloc(sizeof(*h), GFP_KERNEL);
1644	if (!h)
1645		return ERR_PTR(-ENOMEM);
1646
1647	h->desc.bLength			= UVC_DT_FORMAT_MJPEG_SIZE;
1648	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1649	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG;
1650	h->desc.bDefaultFrameIndex	= 1;
1651	h->desc.bAspectRatioX		= 0;
1652	h->desc.bAspectRatioY		= 0;
1653	h->desc.bmInterfaceFlags	= 0;
1654	h->desc.bCopyProtect		= 0;
1655
1656	h->fmt.type = UVCG_MJPEG;
1657	config_group_init_type_name(&h->fmt.group, name,
1658				    &uvcg_mjpeg_type);
1659
1660	return &h->fmt.group;
1661}
1662
1663static void uvcg_mjpeg_drop(struct config_group *group,
1664			    struct config_item *item)
1665{
1666	struct uvcg_mjpeg *h = to_uvcg_mjpeg(item);
1667
1668	kfree(h);
1669}
1670
1671static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
1672	.make_group		= uvcg_mjpeg_make,
1673	.drop_item		= uvcg_mjpeg_drop,
1674};
1675
1676static struct config_item_type uvcg_mjpeg_grp_type = {
1677	.ct_group_ops	= &uvcg_mjpeg_grp_ops,
1678	.ct_owner	= THIS_MODULE,
 
 
 
 
1679};
1680
1681/* streaming/color_matching/default */
1682static struct uvcg_default_color_matching {
1683	struct config_group	group;
1684} uvcg_default_color_matching;
1685
1686static inline struct uvcg_default_color_matching
1687*to_uvcg_default_color_matching(struct config_item *item)
1688{
1689	return container_of(to_config_group(item),
1690			    struct uvcg_default_color_matching, group);
1691}
1692
1693#define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv)		\
1694static ssize_t uvcg_default_color_matching_##cname##_show(		\
1695	struct config_item *item, char *page)		\
1696{									\
1697	struct uvcg_default_color_matching *dc =			\
1698		to_uvcg_default_color_matching(item);			\
1699	struct f_uvc_opts *opts;					\
1700	struct config_item *opts_item;					\
1701	struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;	\
1702	struct uvc_color_matching_descriptor *cd;			\
1703	int result;							\
1704									\
1705	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1706									\
1707	opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent;	\
1708	opts = to_f_uvc_opts(opts_item);				\
1709	cd = &opts->uvc_color_matching;					\
1710									\
1711	mutex_lock(&opts->lock);					\
1712	result = sprintf(page, "%d\n", conv(cd->aname));		\
1713	mutex_unlock(&opts->lock);					\
1714									\
1715	mutex_unlock(su_mutex);						\
1716	return result;							\
1717}									\
1718									\
1719UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
1720
1721#define identity_conv(x) (x)
1722
1723UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries,
1724				 identity_conv);
1725UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
1726				 bTransferCharacteristics, identity_conv);
1727UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients,
1728				 identity_conv);
1729
1730#undef identity_conv
1731
1732#undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
1733
1734static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
1735	&uvcg_default_color_matching_attr_b_color_primaries,
1736	&uvcg_default_color_matching_attr_b_transfer_characteristics,
1737	&uvcg_default_color_matching_attr_b_matrix_coefficients,
1738	NULL,
1739};
1740
1741static struct config_item_type uvcg_default_color_matching_type = {
1742	.ct_attrs	= uvcg_default_color_matching_attrs,
1743	.ct_owner	= THIS_MODULE,
 
 
 
 
1744};
1745
1746/* struct uvcg_color_matching {}; */
 
 
1747
1748/* streaming/color_matching */
1749static struct uvcg_color_matching_grp {
1750	struct config_group	group;
1751} uvcg_color_matching_grp;
1752
1753static struct config_item_type uvcg_color_matching_grp_type = {
1754	.ct_owner = THIS_MODULE,
 
 
 
1755};
1756
1757/* streaming/class/{fs|hs|ss} */
1758static struct uvcg_streaming_class {
1759	struct config_group	group;
1760} uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss;
1761
 
 
 
 
1762
1763static inline struct uvc_descriptor_header
1764***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
1765{
1766	struct uvcg_streaming_class *cl = container_of(to_config_group(i),
1767		struct uvcg_streaming_class, group);
 
1768
1769	if (cl == &uvcg_streaming_class_fs)
1770		return &o->uvc_fs_streaming_cls;
1771
1772	if (cl == &uvcg_streaming_class_hs)
1773		return &o->uvc_hs_streaming_cls;
1774
1775	if (cl == &uvcg_streaming_class_ss)
1776		return &o->uvc_ss_streaming_cls;
1777
1778	return NULL;
1779}
1780
1781enum uvcg_strm_type {
1782	UVCG_HEADER = 0,
1783	UVCG_FORMAT,
1784	UVCG_FRAME
1785};
1786
1787/*
1788 * Iterate over a hierarchy of streaming descriptors' config items.
1789 * The items are created by the user with configfs.
1790 *
1791 * It "processes" the header pointed to by @priv1, then for each format
1792 * that follows the header "processes" the format itself and then for
1793 * each frame inside a format "processes" the frame.
1794 *
1795 * As a "processing" function the @fun is used.
1796 *
1797 * __uvcg_iter_strm_cls() is used in two context: first, to calculate
1798 * the amount of memory needed for an array of streaming descriptors
1799 * and second, to actually fill the array.
1800 *
1801 * @h: streaming header pointer
1802 * @priv2: an "inout" parameter (the caller might want to see the changes to it)
1803 * @priv3: an "inout" parameter (the caller might want to see the changes to it)
1804 * @fun: callback function for processing each level of the hierarchy
1805 */
1806static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
1807	void *priv2, void *priv3,
1808	int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
1809{
1810	struct uvcg_format_ptr *f;
1811	struct config_group *grp;
1812	struct config_item *item;
1813	struct uvcg_frame *frm;
1814	int ret, i, j;
1815
1816	if (!fun)
1817		return -EINVAL;
1818
1819	i = j = 0;
1820	ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
1821	if (ret)
1822		return ret;
1823	list_for_each_entry(f, &h->formats, entry) {
1824		ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
1825		if (ret)
1826			return ret;
1827		grp = &f->fmt->group;
1828		list_for_each_entry(item, &grp->cg_children, ci_entry) {
1829			frm = to_uvcg_frame(item);
1830			ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
1831			if (ret)
1832				return ret;
1833		}
1834	}
1835
1836	return ret;
1837}
1838
1839/*
1840 * Count how many bytes are needed for an array of streaming descriptors.
1841 *
1842 * @priv1: pointer to a header, format or frame
1843 * @priv2: inout parameter, accumulated size of the array
1844 * @priv3: inout parameter, accumulated number of the array elements
1845 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
1846 */
1847static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
1848			   enum uvcg_strm_type type)
1849{
1850	size_t *size = priv2;
1851	size_t *count = priv3;
1852
1853	switch (type) {
1854	case UVCG_HEADER: {
1855		struct uvcg_streaming_header *h = priv1;
1856
1857		*size += sizeof(h->desc);
1858		/* bmaControls */
1859		*size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
1860	}
1861	break;
1862	case UVCG_FORMAT: {
1863		struct uvcg_format *fmt = priv1;
1864
1865		if (fmt->type == UVCG_UNCOMPRESSED) {
1866			struct uvcg_uncompressed *u =
1867				container_of(fmt, struct uvcg_uncompressed,
1868					     fmt);
1869
1870			*size += sizeof(u->desc);
1871		} else if (fmt->type == UVCG_MJPEG) {
1872			struct uvcg_mjpeg *m =
1873				container_of(fmt, struct uvcg_mjpeg, fmt);
1874
1875			*size += sizeof(m->desc);
1876		} else {
1877			return -EINVAL;
1878		}
1879	}
1880	break;
1881	case UVCG_FRAME: {
1882		struct uvcg_frame *frm = priv1;
1883		int sz = sizeof(frm->dw_frame_interval);
1884
1885		*size += sizeof(frm->frame);
1886		*size += frm->frame.b_frame_interval_type * sz;
1887	}
1888	break;
1889	}
1890
1891	++*count;
1892
1893	return 0;
1894}
1895
1896/*
1897 * Fill an array of streaming descriptors.
1898 *
1899 * @priv1: pointer to a header, format or frame
1900 * @priv2: inout parameter, pointer into a block of memory
1901 * @priv3: inout parameter, pointer to a 2-dimensional array
1902 */
1903static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
1904			    enum uvcg_strm_type type)
1905{
1906	void **dest = priv2;
1907	struct uvc_descriptor_header ***array = priv3;
1908	size_t sz;
1909
1910	**array = *dest;
1911	++*array;
1912
1913	switch (type) {
1914	case UVCG_HEADER: {
1915		struct uvc_input_header_descriptor *ihdr = *dest;
1916		struct uvcg_streaming_header *h = priv1;
1917		struct uvcg_format_ptr *f;
1918
1919		memcpy(*dest, &h->desc, sizeof(h->desc));
1920		*dest += sizeof(h->desc);
1921		sz = UVCG_STREAMING_CONTROL_SIZE;
1922		list_for_each_entry(f, &h->formats, entry) {
1923			memcpy(*dest, f->fmt->bmaControls, sz);
1924			*dest += sz;
1925		}
1926		ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
1927		ihdr->bNumFormats = h->num_fmt;
1928	}
1929	break;
1930	case UVCG_FORMAT: {
1931		struct uvcg_format *fmt = priv1;
1932
1933		if (fmt->type == UVCG_UNCOMPRESSED) {
1934			struct uvc_format_uncompressed *unc = *dest;
1935			struct uvcg_uncompressed *u =
1936				container_of(fmt, struct uvcg_uncompressed,
1937					     fmt);
1938
 
 
1939			memcpy(*dest, &u->desc, sizeof(u->desc));
1940			*dest += sizeof(u->desc);
1941			unc->bNumFrameDescriptors = fmt->num_frames;
1942			unc->bFormatIndex = n + 1;
1943		} else if (fmt->type == UVCG_MJPEG) {
1944			struct uvc_format_mjpeg *mjp = *dest;
1945			struct uvcg_mjpeg *m =
1946				container_of(fmt, struct uvcg_mjpeg, fmt);
1947
 
 
1948			memcpy(*dest, &m->desc, sizeof(m->desc));
1949			*dest += sizeof(m->desc);
1950			mjp->bNumFrameDescriptors = fmt->num_frames;
1951			mjp->bFormatIndex = n + 1;
1952		} else {
1953			return -EINVAL;
1954		}
1955	}
1956	break;
1957	case UVCG_FRAME: {
1958		struct uvcg_frame *frm = priv1;
1959		struct uvc_descriptor_header *h = *dest;
1960
1961		sz = sizeof(frm->frame);
1962		memcpy(*dest, &frm->frame, sz);
1963		*dest += sz;
1964		sz = frm->frame.b_frame_interval_type *
1965			sizeof(*frm->dw_frame_interval);
1966		memcpy(*dest, frm->dw_frame_interval, sz);
1967		*dest += sz;
1968		if (frm->fmt_type == UVCG_UNCOMPRESSED)
1969			h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
1970				frm->frame.b_frame_interval_type);
1971		else if (frm->fmt_type == UVCG_MJPEG)
1972			h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
1973				frm->frame.b_frame_interval_type);
1974	}
1975	break;
1976	}
1977
1978	return 0;
1979}
1980
1981static int uvcg_streaming_class_allow_link(struct config_item *src,
1982					   struct config_item *target)
1983{
1984	struct config_item *streaming, *header;
1985	struct f_uvc_opts *opts;
1986	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
1987	struct uvc_descriptor_header ***class_array, **cl_arr;
1988	struct uvcg_streaming_header *target_hdr;
1989	void *data, *data_save;
1990	size_t size = 0, count = 0;
1991	int ret = -EINVAL;
1992
1993	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1994
1995	streaming = src->ci_parent->ci_parent;
1996	header = config_group_find_item(to_config_group(streaming), "header");
1997	if (!header || target->ci_parent != header)
1998		goto out;
1999
2000	opts = to_f_uvc_opts(streaming->ci_parent);
2001
2002	mutex_lock(&opts->lock);
2003
2004	class_array = __uvcg_get_stream_class_arr(src, opts);
2005	if (!class_array || *class_array || opts->refcnt) {
2006		ret = -EBUSY;
2007		goto unlock;
2008	}
2009
2010	target_hdr = to_uvcg_streaming_header(target);
2011	ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
2012	if (ret)
2013		goto unlock;
2014
2015	count += 2; /* color_matching, NULL */
2016	*class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
2017	if (!*class_array) {
2018		ret = -ENOMEM;
2019		goto unlock;
2020	}
2021
2022	data = data_save = kzalloc(size, GFP_KERNEL);
2023	if (!data) {
2024		kfree(*class_array);
2025		*class_array = NULL;
2026		ret = PTR_ERR(data);
2027		goto unlock;
2028	}
2029	cl_arr = *class_array;
2030	ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
2031				   __uvcg_fill_strm);
2032	if (ret) {
2033		kfree(*class_array);
2034		*class_array = NULL;
2035		/*
2036		 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
2037		 * might have advanced the "data", so use a backup copy
2038		 */
2039		kfree(data_save);
2040		goto unlock;
2041	}
2042	*cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;
2043
2044	++target_hdr->linked;
2045	ret = 0;
2046
2047unlock:
2048	mutex_unlock(&opts->lock);
2049out:
 
2050	mutex_unlock(su_mutex);
2051	return ret;
2052}
2053
2054static int uvcg_streaming_class_drop_link(struct config_item *src,
2055					  struct config_item *target)
2056{
2057	struct config_item *streaming, *header;
2058	struct f_uvc_opts *opts;
2059	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2060	struct uvc_descriptor_header ***class_array;
2061	struct uvcg_streaming_header *target_hdr;
2062	int ret = -EINVAL;
2063
2064	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2065
2066	streaming = src->ci_parent->ci_parent;
2067	header = config_group_find_item(to_config_group(streaming), "header");
2068	if (!header || target->ci_parent != header)
2069		goto out;
2070
2071	opts = to_f_uvc_opts(streaming->ci_parent);
2072
2073	mutex_lock(&opts->lock);
2074
2075	class_array = __uvcg_get_stream_class_arr(src, opts);
2076	if (!class_array || !*class_array)
2077		goto unlock;
2078
2079	if (opts->refcnt) {
2080		ret = -EBUSY;
2081		goto unlock;
2082	}
2083
2084	target_hdr = to_uvcg_streaming_header(target);
2085	--target_hdr->linked;
2086	kfree(**class_array);
2087	kfree(*class_array);
2088	*class_array = NULL;
2089	ret = 0;
2090
2091unlock:
2092	mutex_unlock(&opts->lock);
2093out:
 
2094	mutex_unlock(su_mutex);
2095	return ret;
2096}
2097
2098static struct configfs_item_operations uvcg_streaming_class_item_ops = {
 
2099	.allow_link	= uvcg_streaming_class_allow_link,
2100	.drop_link	= uvcg_streaming_class_drop_link,
2101};
2102
2103static struct config_item_type uvcg_streaming_class_type = {
2104	.ct_item_ops	= &uvcg_streaming_class_item_ops,
2105	.ct_owner	= THIS_MODULE,
2106};
2107
2108/* streaming/class */
2109static struct uvcg_streaming_class_grp {
2110	struct config_group	group;
2111} uvcg_streaming_class_grp;
 
 
 
 
 
 
 
 
 
 
 
 
 
2112
2113static struct config_item_type uvcg_streaming_class_grp_type = {
2114	.ct_owner = THIS_MODULE,
2115};
 
2116
2117/* streaming */
2118static struct uvcg_streaming_grp {
2119	struct config_group	group;
2120} uvcg_streaming_grp;
2121
2122static struct config_item_type uvcg_streaming_grp_type = {
2123	.ct_owner = THIS_MODULE,
 
 
 
 
 
2124};
2125
2126static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
 
 
 
 
 
2127{
2128	return container_of(to_config_group(item), struct f_uvc_opts,
2129			    func_inst.group);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2130}
2131
2132static void uvc_attr_release(struct config_item *item)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2133{
2134	struct f_uvc_opts *opts = to_f_uvc_opts(item);
2135
 
2136	usb_put_function_instance(&opts->func_inst);
2137}
2138
2139static struct configfs_item_operations uvc_item_ops = {
2140	.release		= uvc_attr_release,
2141};
2142
2143#define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit)		\
2144static ssize_t f_uvc_opts_##cname##_show(				\
2145	struct config_item *item, char *page)				\
2146{									\
2147	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2148	int result;							\
2149									\
2150	mutex_lock(&opts->lock);					\
2151	result = sprintf(page, "%d\n", conv(opts->cname));		\
2152	mutex_unlock(&opts->lock);					\
2153									\
2154	return result;							\
2155}									\
2156									\
2157static ssize_t								\
2158f_uvc_opts_##cname##_store(struct config_item *item,			\
2159			   const char *page, size_t len)		\
2160{									\
2161	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
 
2162	int ret;							\
2163	uxx num;							\
2164									\
2165	mutex_lock(&opts->lock);					\
2166	if (opts->refcnt) {						\
2167		ret = -EBUSY;						\
2168		goto end;						\
2169	}								\
2170									\
2171	ret = str2u(page, 0, &num);					\
2172	if (ret)							\
2173		goto end;						\
2174									\
2175	if (num > limit) {						\
2176		ret = -EINVAL;						\
2177		goto end;						\
2178	}								\
2179	opts->cname = vnoc(num);					\
2180	ret = len;							\
2181end:									\
2182	mutex_unlock(&opts->lock);					\
2183	return ret;							\
2184}									\
2185									\
2186UVC_ATTR(f_uvc_opts_, cname, aname)
2187
2188#define identity_conv(x) (x)
2189
2190UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv,
2191	       16);
2192UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu,
2193	       3072);
2194UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
2195	       15);
2196
2197#undef identity_conv
2198
2199#undef UVCG_OPTS_ATTR
2200
2201static struct configfs_attribute *uvc_attrs[] = {
2202	&f_uvc_opts_attr_streaming_interval,
2203	&f_uvc_opts_attr_streaming_maxpacket,
2204	&f_uvc_opts_attr_streaming_maxburst,
2205	NULL,
2206};
2207
2208static struct config_item_type uvc_func_type = {
2209	.ct_item_ops	= &uvc_item_ops,
2210	.ct_attrs	= uvc_attrs,
2211	.ct_owner	= THIS_MODULE,
 
 
 
 
 
 
 
 
2212};
2213
2214int uvcg_attach_configfs(struct f_uvc_opts *opts)
2215{
2216	config_group_init_type_name(&uvcg_control_header_grp.group,
2217				    "header",
2218				    &uvcg_control_header_grp_type);
2219
2220	config_group_init_type_name(&uvcg_default_processing.group,
2221			"default", &uvcg_default_processing_type);
2222	config_group_init_type_name(&uvcg_processing_grp.group,
2223			"processing", &uvcg_processing_grp_type);
2224	configfs_add_default_group(&uvcg_default_processing.group,
2225			&uvcg_processing_grp.group);
2226
2227	config_group_init_type_name(&uvcg_default_camera.group,
2228			"default", &uvcg_default_camera_type);
2229	config_group_init_type_name(&uvcg_camera_grp.group,
2230			"camera", &uvcg_camera_grp_type);
2231	configfs_add_default_group(&uvcg_default_camera.group,
2232			&uvcg_camera_grp.group);
2233
2234	config_group_init_type_name(&uvcg_default_output.group,
2235			"default", &uvcg_default_output_type);
2236	config_group_init_type_name(&uvcg_output_grp.group,
2237			"output", &uvcg_output_grp_type);
2238	configfs_add_default_group(&uvcg_default_output.group,
2239			&uvcg_output_grp.group);
2240
2241	config_group_init_type_name(&uvcg_terminal_grp.group,
2242			"terminal", &uvcg_terminal_grp_type);
2243	configfs_add_default_group(&uvcg_camera_grp.group,
2244			&uvcg_terminal_grp.group);
2245	configfs_add_default_group(&uvcg_output_grp.group,
2246			&uvcg_terminal_grp.group);
2247
2248	config_group_init_type_name(&uvcg_control_class_fs.group,
2249			"fs", &uvcg_control_class_type);
2250	config_group_init_type_name(&uvcg_control_class_ss.group,
2251			"ss", &uvcg_control_class_type);
2252	config_group_init_type_name(&uvcg_control_class_grp.group,
2253			"class",
2254			&uvcg_control_class_grp_type);
2255	configfs_add_default_group(&uvcg_control_class_fs.group,
2256			&uvcg_control_class_grp.group);
2257	configfs_add_default_group(&uvcg_control_class_ss.group,
2258			&uvcg_control_class_grp.group);
2259
2260	config_group_init_type_name(&uvcg_control_grp.group,
2261			"control",
2262			&uvcg_control_grp_type);
2263	configfs_add_default_group(&uvcg_control_header_grp.group,
2264			&uvcg_control_grp.group);
2265	configfs_add_default_group(&uvcg_processing_grp.group,
2266			&uvcg_control_grp.group);
2267	configfs_add_default_group(&uvcg_terminal_grp.group,
2268			&uvcg_control_grp.group);
2269	configfs_add_default_group(&uvcg_control_class_grp.group,
2270			&uvcg_control_grp.group);
2271
2272	config_group_init_type_name(&uvcg_streaming_header_grp.group,
2273				    "header",
2274				    &uvcg_streaming_header_grp_type);
2275	config_group_init_type_name(&uvcg_uncompressed_grp.group,
2276				    "uncompressed",
2277				    &uvcg_uncompressed_grp_type);
2278	config_group_init_type_name(&uvcg_mjpeg_grp.group,
2279				    "mjpeg",
2280				    &uvcg_mjpeg_grp_type);
2281	config_group_init_type_name(&uvcg_default_color_matching.group,
2282				    "default",
2283				    &uvcg_default_color_matching_type);
2284	config_group_init_type_name(&uvcg_color_matching_grp.group,
2285			"color_matching",
2286			&uvcg_color_matching_grp_type);
2287	configfs_add_default_group(&uvcg_default_color_matching.group,
2288			&uvcg_color_matching_grp.group);
2289
2290	config_group_init_type_name(&uvcg_streaming_class_fs.group,
2291			"fs", &uvcg_streaming_class_type);
2292	config_group_init_type_name(&uvcg_streaming_class_hs.group,
2293			"hs", &uvcg_streaming_class_type);
2294	config_group_init_type_name(&uvcg_streaming_class_ss.group,
2295			"ss", &uvcg_streaming_class_type);
2296	config_group_init_type_name(&uvcg_streaming_class_grp.group,
2297			"class", &uvcg_streaming_class_grp_type);
2298	configfs_add_default_group(&uvcg_streaming_class_fs.group,
2299			&uvcg_streaming_class_grp.group);
2300	configfs_add_default_group(&uvcg_streaming_class_hs.group,
2301			&uvcg_streaming_class_grp.group);
2302	configfs_add_default_group(&uvcg_streaming_class_ss.group,
2303			&uvcg_streaming_class_grp.group);
2304
2305	config_group_init_type_name(&uvcg_streaming_grp.group,
2306			"streaming", &uvcg_streaming_grp_type);
2307	configfs_add_default_group(&uvcg_streaming_header_grp.group,
2308			&uvcg_streaming_grp.group);
2309	configfs_add_default_group(&uvcg_uncompressed_grp.group,
2310			&uvcg_streaming_grp.group);
2311	configfs_add_default_group(&uvcg_mjpeg_grp.group,
2312			&uvcg_streaming_grp.group);
2313	configfs_add_default_group(&uvcg_color_matching_grp.group,
2314			&uvcg_streaming_grp.group);
2315	configfs_add_default_group(&uvcg_streaming_class_grp.group,
2316			&uvcg_streaming_grp.group);
2317
2318	config_group_init_type_name(&opts->func_inst.group,
2319			"",
2320			&uvc_func_type);
2321	configfs_add_default_group(&uvcg_control_grp.group,
2322			&opts->func_inst.group);
2323	configfs_add_default_group(&uvcg_streaming_grp.group,
2324			&opts->func_inst.group);
2325
2326	return 0;
 
 
 
 
 
2327}