Linux Audio

Check our new training course

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