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