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