• 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 "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(i_terminal, iTerminal, 8);
487 
488 #undef UVCG_DEFAULT_OUTPUT_ATTR
489 
uvcg_default_output_b_source_id_show(struct config_item * item,char * page)490 static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item,
491 						    char *page)
492 {
493 	struct config_group *group = to_config_group(item);
494 	struct f_uvc_opts *opts;
495 	struct config_item *opts_item;
496 	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
497 	struct uvc_output_terminal_descriptor *cd;
498 	int result;
499 
500 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
501 
502 	opts_item = group->cg_item.ci_parent->ci_parent->
503 			ci_parent->ci_parent;
504 	opts = to_f_uvc_opts(opts_item);
505 	cd = &opts->uvc_output_terminal;
506 
507 	mutex_lock(&opts->lock);
508 	result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID));
509 	mutex_unlock(&opts->lock);
510 
511 	mutex_unlock(su_mutex);
512 
513 	return result;
514 }
515 
uvcg_default_output_b_source_id_store(struct config_item * item,const char * page,size_t len)516 static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,
517 						     const char *page, size_t len)
518 {
519 	struct config_group *group = to_config_group(item);
520 	struct f_uvc_opts *opts;
521 	struct config_item *opts_item;
522 	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
523 	struct uvc_output_terminal_descriptor *cd;
524 	int result;
525 	u8 num;
526 
527 	result = kstrtou8(page, 0, &num);
528 	if (result)
529 		return result;
530 
531 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
532 
533 	opts_item = group->cg_item.ci_parent->ci_parent->
534 			ci_parent->ci_parent;
535 	opts = to_f_uvc_opts(opts_item);
536 	cd = &opts->uvc_output_terminal;
537 
538 	mutex_lock(&opts->lock);
539 	cd->bSourceID = num;
540 	mutex_unlock(&opts->lock);
541 
542 	mutex_unlock(su_mutex);
543 
544 	return len;
545 }
546 UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID);
547 
548 static struct configfs_attribute *uvcg_default_output_attrs[] = {
549 	&uvcg_default_output_attr_b_terminal_id,
550 	&uvcg_default_output_attr_w_terminal_type,
551 	&uvcg_default_output_attr_b_assoc_terminal,
552 	&uvcg_default_output_attr_b_source_id,
553 	&uvcg_default_output_attr_i_terminal,
554 	NULL,
555 };
556 
557 static const struct uvcg_config_group_type uvcg_default_output_type = {
558 	.type = {
559 		.ct_item_ops	= &uvcg_config_item_ops,
560 		.ct_attrs	= uvcg_default_output_attrs,
561 		.ct_owner	= THIS_MODULE,
562 	},
563 	.name = "default",
564 };
565 
566 /* -----------------------------------------------------------------------------
567  * control/terminal/output
568  */
569 
570 static const struct uvcg_config_group_type uvcg_output_grp_type = {
571 	.type = {
572 		.ct_item_ops	= &uvcg_config_item_ops,
573 		.ct_owner	= THIS_MODULE,
574 	},
575 	.name = "output",
576 	.children = (const struct uvcg_config_group_type*[]) {
577 		&uvcg_default_output_type,
578 		NULL,
579 	},
580 };
581 
582 /* -----------------------------------------------------------------------------
583  * control/terminal
584  */
585 
586 static const struct uvcg_config_group_type uvcg_terminal_grp_type = {
587 	.type = {
588 		.ct_item_ops	= &uvcg_config_item_ops,
589 		.ct_owner	= THIS_MODULE,
590 	},
591 	.name = "terminal",
592 	.children = (const struct uvcg_config_group_type*[]) {
593 		&uvcg_camera_grp_type,
594 		&uvcg_output_grp_type,
595 		NULL,
596 	},
597 };
598 
599 /* -----------------------------------------------------------------------------
600  * control/class/{fs|ss}
601  */
602 
603 struct uvcg_control_class_group {
604 	struct config_group group;
605 	const char *name;
606 };
607 
608 static inline struct uvc_descriptor_header
uvcg_get_ctl_class_arr(struct config_item * i,struct f_uvc_opts * o)609 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
610 {
611 	struct uvcg_control_class_group *group =
612 		container_of(i, struct uvcg_control_class_group,
613 			     group.cg_item);
614 
615 	if (!strcmp(group->name, "fs"))
616 		return o->uvc_fs_control_cls;
617 
618 	if (!strcmp(group->name, "ss"))
619 		return o->uvc_ss_control_cls;
620 
621 	return NULL;
622 }
623 
uvcg_control_class_allow_link(struct config_item * src,struct config_item * target)624 static int uvcg_control_class_allow_link(struct config_item *src,
625 					 struct config_item *target)
626 {
627 	struct config_item *control, *header;
628 	struct f_uvc_opts *opts;
629 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
630 	struct uvc_descriptor_header **class_array;
631 	struct uvcg_control_header *target_hdr;
632 	int ret = -EINVAL;
633 
634 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
635 
636 	control = src->ci_parent->ci_parent;
637 	header = config_group_find_item(to_config_group(control), "header");
638 	if (!header || target->ci_parent != header)
639 		goto out;
640 
641 	opts = to_f_uvc_opts(control->ci_parent);
642 
643 	mutex_lock(&opts->lock);
644 
645 	class_array = uvcg_get_ctl_class_arr(src, opts);
646 	if (!class_array)
647 		goto unlock;
648 	if (opts->refcnt || class_array[0]) {
649 		ret = -EBUSY;
650 		goto unlock;
651 	}
652 
653 	target_hdr = to_uvcg_control_header(target);
654 	++target_hdr->linked;
655 	class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc;
656 	ret = 0;
657 
658 unlock:
659 	mutex_unlock(&opts->lock);
660 out:
661 	config_item_put(header);
662 	mutex_unlock(su_mutex);
663 	return ret;
664 }
665 
uvcg_control_class_drop_link(struct config_item * src,struct config_item * target)666 static void uvcg_control_class_drop_link(struct config_item *src,
667 					struct config_item *target)
668 {
669 	struct config_item *control, *header;
670 	struct f_uvc_opts *opts;
671 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
672 	struct uvc_descriptor_header **class_array;
673 	struct uvcg_control_header *target_hdr;
674 
675 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
676 
677 	control = src->ci_parent->ci_parent;
678 	header = config_group_find_item(to_config_group(control), "header");
679 	if (!header || target->ci_parent != header)
680 		goto out;
681 
682 	opts = to_f_uvc_opts(control->ci_parent);
683 
684 	mutex_lock(&opts->lock);
685 
686 	class_array = uvcg_get_ctl_class_arr(src, opts);
687 	if (!class_array || opts->refcnt)
688 		goto unlock;
689 
690 	target_hdr = to_uvcg_control_header(target);
691 	--target_hdr->linked;
692 	class_array[0] = NULL;
693 
694 unlock:
695 	mutex_unlock(&opts->lock);
696 out:
697 	config_item_put(header);
698 	mutex_unlock(su_mutex);
699 }
700 
701 static struct configfs_item_operations uvcg_control_class_item_ops = {
702 	.release	= uvcg_config_item_release,
703 	.allow_link	= uvcg_control_class_allow_link,
704 	.drop_link	= uvcg_control_class_drop_link,
705 };
706 
707 static const struct config_item_type uvcg_control_class_type = {
708 	.ct_item_ops	= &uvcg_control_class_item_ops,
709 	.ct_owner	= THIS_MODULE,
710 };
711 
712 /* -----------------------------------------------------------------------------
713  * control/class
714  */
715 
uvcg_control_class_create_children(struct config_group * parent)716 static int uvcg_control_class_create_children(struct config_group *parent)
717 {
718 	static const char * const names[] = { "fs", "ss" };
719 	unsigned int i;
720 
721 	for (i = 0; i < ARRAY_SIZE(names); ++i) {
722 		struct uvcg_control_class_group *group;
723 
724 		group = kzalloc(sizeof(*group), GFP_KERNEL);
725 		if (!group)
726 			return -ENOMEM;
727 
728 		group->name = names[i];
729 
730 		config_group_init_type_name(&group->group, group->name,
731 					    &uvcg_control_class_type);
732 		configfs_add_default_group(&group->group, parent);
733 	}
734 
735 	return 0;
736 }
737 
738 static const struct uvcg_config_group_type uvcg_control_class_grp_type = {
739 	.type = {
740 		.ct_item_ops	= &uvcg_config_item_ops,
741 		.ct_owner	= THIS_MODULE,
742 	},
743 	.name = "class",
744 	.create_children = uvcg_control_class_create_children,
745 };
746 
747 /* -----------------------------------------------------------------------------
748  * control
749  */
750 
uvcg_default_control_b_interface_number_show(struct config_item * item,char * page)751 static ssize_t uvcg_default_control_b_interface_number_show(
752 	struct config_item *item, char *page)
753 {
754 	struct config_group *group = to_config_group(item);
755 	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
756 	struct config_item *opts_item;
757 	struct f_uvc_opts *opts;
758 	int result = 0;
759 
760 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
761 
762 	opts_item = item->ci_parent;
763 	opts = to_f_uvc_opts(opts_item);
764 
765 	mutex_lock(&opts->lock);
766 	result += sprintf(page, "%u\n", opts->control_interface);
767 	mutex_unlock(&opts->lock);
768 
769 	mutex_unlock(su_mutex);
770 
771 	return result;
772 }
773 
774 UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber);
775 
776 static struct configfs_attribute *uvcg_default_control_attrs[] = {
777 	&uvcg_default_control_attr_b_interface_number,
778 	NULL,
779 };
780 
781 static const struct uvcg_config_group_type uvcg_control_grp_type = {
782 	.type = {
783 		.ct_item_ops	= &uvcg_config_item_ops,
784 		.ct_attrs	= uvcg_default_control_attrs,
785 		.ct_owner	= THIS_MODULE,
786 	},
787 	.name = "control",
788 	.children = (const struct uvcg_config_group_type*[]) {
789 		&uvcg_control_header_grp_type,
790 		&uvcg_processing_grp_type,
791 		&uvcg_terminal_grp_type,
792 		&uvcg_control_class_grp_type,
793 		NULL,
794 	},
795 };
796 
797 /* -----------------------------------------------------------------------------
798  * streaming/uncompressed
799  * streaming/mjpeg
800  */
801 
802 static const char * const uvcg_format_names[] = {
803 	"uncompressed",
804 	"mjpeg",
805 };
806 
uvcg_format_bma_controls_show(struct uvcg_format * f,char * page)807 static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
808 {
809 	struct f_uvc_opts *opts;
810 	struct config_item *opts_item;
811 	struct mutex *su_mutex = &f->group.cg_subsys->su_mutex;
812 	int result, i;
813 	char *pg = page;
814 
815 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
816 
817 	opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent;
818 	opts = to_f_uvc_opts(opts_item);
819 
820 	mutex_lock(&opts->lock);
821 	result = sprintf(pg, "0x");
822 	pg += result;
823 	for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) {
824 		result += sprintf(pg, "%x\n", f->bmaControls[i]);
825 		pg = page + result;
826 	}
827 	mutex_unlock(&opts->lock);
828 
829 	mutex_unlock(su_mutex);
830 	return result;
831 }
832 
uvcg_format_bma_controls_store(struct uvcg_format * ch,const char * page,size_t len)833 static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch,
834 					      const char *page, size_t len)
835 {
836 	struct f_uvc_opts *opts;
837 	struct config_item *opts_item;
838 	struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex;
839 	int ret = -EINVAL;
840 
841 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
842 
843 	opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent;
844 	opts = to_f_uvc_opts(opts_item);
845 
846 	mutex_lock(&opts->lock);
847 	if (ch->linked || opts->refcnt) {
848 		ret = -EBUSY;
849 		goto end;
850 	}
851 
852 	if (len < 4 || *page != '0' ||
853 	    (*(page + 1) != 'x' && *(page + 1) != 'X'))
854 		goto end;
855 	ret = hex2bin(ch->bmaControls, page + 2, 1);
856 	if (ret < 0)
857 		goto end;
858 	ret = len;
859 end:
860 	mutex_unlock(&opts->lock);
861 	mutex_unlock(su_mutex);
862 	return ret;
863 }
864 
865 /* -----------------------------------------------------------------------------
866  * streaming/header/<NAME>
867  * streaming/header
868  */
869 
870 static void uvcg_format_set_indices(struct config_group *fmt);
871 
uvcg_streaming_header_allow_link(struct config_item * src,struct config_item * target)872 static int uvcg_streaming_header_allow_link(struct config_item *src,
873 					    struct config_item *target)
874 {
875 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
876 	struct config_item *opts_item;
877 	struct f_uvc_opts *opts;
878 	struct uvcg_streaming_header *src_hdr;
879 	struct uvcg_format *target_fmt = NULL;
880 	struct uvcg_format_ptr *format_ptr;
881 	int i, ret = -EINVAL;
882 
883 	src_hdr = to_uvcg_streaming_header(src);
884 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
885 
886 	opts_item = src->ci_parent->ci_parent->ci_parent;
887 	opts = to_f_uvc_opts(opts_item);
888 
889 	mutex_lock(&opts->lock);
890 
891 	if (src_hdr->linked) {
892 		ret = -EBUSY;
893 		goto out;
894 	}
895 
896 	/*
897 	 * Linking is only allowed to direct children of the format nodes
898 	 * (streaming/uncompressed or streaming/mjpeg nodes). First check that
899 	 * the grand-parent of the target matches the grand-parent of the source
900 	 * (the streaming node), and then verify that the target parent is a
901 	 * format node.
902 	 */
903 	if (src->ci_parent->ci_parent != target->ci_parent->ci_parent)
904 		goto out;
905 
906 	for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) {
907 		if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i]))
908 			break;
909 	}
910 
911 	if (i == ARRAY_SIZE(uvcg_format_names))
912 		goto out;
913 
914 	target_fmt = container_of(to_config_group(target), struct uvcg_format,
915 				  group);
916 
917 	uvcg_format_set_indices(to_config_group(target));
918 
919 	format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
920 	if (!format_ptr) {
921 		ret = -ENOMEM;
922 		goto out;
923 	}
924 	ret = 0;
925 	format_ptr->fmt = target_fmt;
926 	list_add_tail(&format_ptr->entry, &src_hdr->formats);
927 	++src_hdr->num_fmt;
928 	++target_fmt->linked;
929 
930 out:
931 	mutex_unlock(&opts->lock);
932 	mutex_unlock(su_mutex);
933 	return ret;
934 }
935 
uvcg_streaming_header_drop_link(struct config_item * src,struct config_item * target)936 static void uvcg_streaming_header_drop_link(struct config_item *src,
937 					   struct config_item *target)
938 {
939 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
940 	struct config_item *opts_item;
941 	struct f_uvc_opts *opts;
942 	struct uvcg_streaming_header *src_hdr;
943 	struct uvcg_format *target_fmt = NULL;
944 	struct uvcg_format_ptr *format_ptr, *tmp;
945 
946 	src_hdr = to_uvcg_streaming_header(src);
947 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
948 
949 	opts_item = src->ci_parent->ci_parent->ci_parent;
950 	opts = to_f_uvc_opts(opts_item);
951 
952 	mutex_lock(&opts->lock);
953 	target_fmt = container_of(to_config_group(target), struct uvcg_format,
954 				  group);
955 
956 	list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
957 		if (format_ptr->fmt == target_fmt) {
958 			list_del(&format_ptr->entry);
959 			kfree(format_ptr);
960 			--src_hdr->num_fmt;
961 			break;
962 		}
963 
964 	--target_fmt->linked;
965 
966 	mutex_unlock(&opts->lock);
967 	mutex_unlock(su_mutex);
968 }
969 
970 static struct configfs_item_operations uvcg_streaming_header_item_ops = {
971 	.release	= uvcg_config_item_release,
972 	.allow_link	= uvcg_streaming_header_allow_link,
973 	.drop_link	= uvcg_streaming_header_drop_link,
974 };
975 
976 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits)			\
977 static ssize_t uvcg_streaming_header_##cname##_show(			\
978 	struct config_item *item, char *page)				\
979 {									\
980 	struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
981 	struct f_uvc_opts *opts;					\
982 	struct config_item *opts_item;					\
983 	struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
984 	int result;							\
985 									\
986 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
987 									\
988 	opts_item = sh->item.ci_parent->ci_parent->ci_parent;		\
989 	opts = to_f_uvc_opts(opts_item);				\
990 									\
991 	mutex_lock(&opts->lock);					\
992 	result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\
993 	mutex_unlock(&opts->lock);					\
994 									\
995 	mutex_unlock(su_mutex);						\
996 	return result;							\
997 }									\
998 									\
999 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
1000 
1001 UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, 8);
1002 UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, 8);
1003 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 8);
1004 UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, 8);
1005 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, 8);
1006 
1007 #undef UVCG_STREAMING_HEADER_ATTR
1008 
1009 static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
1010 	&uvcg_streaming_header_attr_bm_info,
1011 	&uvcg_streaming_header_attr_b_terminal_link,
1012 	&uvcg_streaming_header_attr_b_still_capture_method,
1013 	&uvcg_streaming_header_attr_b_trigger_support,
1014 	&uvcg_streaming_header_attr_b_trigger_usage,
1015 	NULL,
1016 };
1017 
1018 static const struct config_item_type uvcg_streaming_header_type = {
1019 	.ct_item_ops	= &uvcg_streaming_header_item_ops,
1020 	.ct_attrs	= uvcg_streaming_header_attrs,
1021 	.ct_owner	= THIS_MODULE,
1022 };
1023 
1024 static struct config_item
uvcg_streaming_header_make(struct config_group * group,const char * name)1025 *uvcg_streaming_header_make(struct config_group *group, const char *name)
1026 {
1027 	struct uvcg_streaming_header *h;
1028 
1029 	h = kzalloc(sizeof(*h), GFP_KERNEL);
1030 	if (!h)
1031 		return ERR_PTR(-ENOMEM);
1032 
1033 	INIT_LIST_HEAD(&h->formats);
1034 	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1035 	h->desc.bDescriptorSubType	= UVC_VS_INPUT_HEADER;
1036 	h->desc.bTerminalLink		= 3;
1037 	h->desc.bControlSize		= UVCG_STREAMING_CONTROL_SIZE;
1038 
1039 	config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
1040 
1041 	return &h->item;
1042 }
1043 
1044 static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
1045 	.make_item		= uvcg_streaming_header_make,
1046 };
1047 
1048 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = {
1049 	.type = {
1050 		.ct_item_ops	= &uvcg_config_item_ops,
1051 		.ct_group_ops	= &uvcg_streaming_header_grp_ops,
1052 		.ct_owner	= THIS_MODULE,
1053 	},
1054 	.name = "header",
1055 };
1056 
1057 /* -----------------------------------------------------------------------------
1058  * streaming/<mode>/<format>/<NAME>
1059  */
1060 
1061 #define UVCG_FRAME_ATTR(cname, aname, bits) \
1062 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
1063 {									\
1064 	struct uvcg_frame *f = to_uvcg_frame(item);			\
1065 	struct f_uvc_opts *opts;					\
1066 	struct config_item *opts_item;					\
1067 	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1068 	int result;							\
1069 									\
1070 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1071 									\
1072 	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1073 	opts = to_f_uvc_opts(opts_item);				\
1074 									\
1075 	mutex_lock(&opts->lock);					\
1076 	result = sprintf(page, "%u\n", f->frame.cname);			\
1077 	mutex_unlock(&opts->lock);					\
1078 									\
1079 	mutex_unlock(su_mutex);						\
1080 	return result;							\
1081 }									\
1082 									\
1083 static ssize_t  uvcg_frame_##cname##_store(struct config_item *item,	\
1084 					   const char *page, size_t len)\
1085 {									\
1086 	struct uvcg_frame *f = to_uvcg_frame(item);			\
1087 	struct f_uvc_opts *opts;					\
1088 	struct config_item *opts_item;					\
1089 	struct uvcg_format *fmt;					\
1090 	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
1091 	typeof(f->frame.cname) num;					\
1092 	int ret;							\
1093 									\
1094 	ret = kstrtou##bits(page, 0, &num);				\
1095 	if (ret)							\
1096 		return ret;						\
1097 									\
1098 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1099 									\
1100 	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
1101 	opts = to_f_uvc_opts(opts_item);				\
1102 	fmt = to_uvcg_format(f->item.ci_parent);			\
1103 									\
1104 	mutex_lock(&opts->lock);					\
1105 	if (fmt->linked || opts->refcnt) {				\
1106 		ret = -EBUSY;						\
1107 		goto end;						\
1108 	}								\
1109 									\
1110 	f->frame.cname = num;						\
1111 	ret = len;							\
1112 end:									\
1113 	mutex_unlock(&opts->lock);					\
1114 	mutex_unlock(su_mutex);						\
1115 	return ret;							\
1116 }									\
1117 									\
1118 UVC_ATTR(uvcg_frame_, cname, aname);
1119 
uvcg_frame_b_frame_index_show(struct config_item * item,char * page)1120 static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item,
1121 					     char *page)
1122 {
1123 	struct uvcg_frame *f = to_uvcg_frame(item);
1124 	struct uvcg_format *fmt;
1125 	struct f_uvc_opts *opts;
1126 	struct config_item *opts_item;
1127 	struct config_item *fmt_item;
1128 	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;
1129 	int result;
1130 
1131 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1132 
1133 	fmt_item = f->item.ci_parent;
1134 	fmt = to_uvcg_format(fmt_item);
1135 
1136 	if (!fmt->linked) {
1137 		result = -EBUSY;
1138 		goto out;
1139 	}
1140 
1141 	opts_item = fmt_item->ci_parent->ci_parent->ci_parent;
1142 	opts = to_f_uvc_opts(opts_item);
1143 
1144 	mutex_lock(&opts->lock);
1145 	result = sprintf(page, "%u\n", f->frame.b_frame_index);
1146 	mutex_unlock(&opts->lock);
1147 
1148 out:
1149 	mutex_unlock(su_mutex);
1150 	return result;
1151 }
1152 
1153 UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex);
1154 
1155 UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, 8);
1156 UVCG_FRAME_ATTR(w_width, wWidth, 16);
1157 UVCG_FRAME_ATTR(w_height, wHeight, 16);
1158 UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
1159 UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
1160 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
1161 UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
1162 
1163 #undef UVCG_FRAME_ATTR
1164 
uvcg_frame_dw_frame_interval_show(struct config_item * item,char * page)1165 static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
1166 						 char *page)
1167 {
1168 	struct uvcg_frame *frm = to_uvcg_frame(item);
1169 	struct f_uvc_opts *opts;
1170 	struct config_item *opts_item;
1171 	struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
1172 	int result, i;
1173 	char *pg = page;
1174 
1175 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1176 
1177 	opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
1178 	opts = to_f_uvc_opts(opts_item);
1179 
1180 	mutex_lock(&opts->lock);
1181 	for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
1182 		result += sprintf(pg, "%u\n", frm->dw_frame_interval[i]);
1183 		pg = page + result;
1184 	}
1185 	mutex_unlock(&opts->lock);
1186 
1187 	mutex_unlock(su_mutex);
1188 	return result;
1189 }
1190 
__uvcg_count_frm_intrv(char * buf,void * priv)1191 static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1192 {
1193 	++*((int *)priv);
1194 	return 0;
1195 }
1196 
__uvcg_fill_frm_intrv(char * buf,void * priv)1197 static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
1198 {
1199 	u32 num, **interv;
1200 	int ret;
1201 
1202 	ret = kstrtou32(buf, 0, &num);
1203 	if (ret)
1204 		return ret;
1205 
1206 	interv = priv;
1207 	**interv = num;
1208 	++*interv;
1209 
1210 	return 0;
1211 }
1212 
__uvcg_iter_frm_intrv(const char * page,size_t len,int (* fun)(char *,void *),void * priv)1213 static int __uvcg_iter_frm_intrv(const char *page, size_t len,
1214 				 int (*fun)(char *, void *), void *priv)
1215 {
1216 	/* sign, base 2 representation, newline, terminator */
1217 	char buf[1 + sizeof(u32) * 8 + 1 + 1];
1218 	const char *pg = page;
1219 	int i, ret;
1220 
1221 	if (!fun)
1222 		return -EINVAL;
1223 
1224 	while (pg - page < len) {
1225 		i = 0;
1226 		while (i < sizeof(buf) && (pg - page < len) &&
1227 				*pg != '\0' && *pg != '\n')
1228 			buf[i++] = *pg++;
1229 		if (i == sizeof(buf))
1230 			return -EINVAL;
1231 		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
1232 			++pg;
1233 		buf[i] = '\0';
1234 		ret = fun(buf, priv);
1235 		if (ret)
1236 			return ret;
1237 	}
1238 
1239 	return 0;
1240 }
1241 
uvcg_frame_dw_frame_interval_store(struct config_item * item,const char * page,size_t len)1242 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
1243 						  const char *page, size_t len)
1244 {
1245 	struct uvcg_frame *ch = to_uvcg_frame(item);
1246 	struct f_uvc_opts *opts;
1247 	struct config_item *opts_item;
1248 	struct uvcg_format *fmt;
1249 	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
1250 	int ret = 0, n = 0;
1251 	u32 *frm_intrv, *tmp;
1252 
1253 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1254 
1255 	opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
1256 	opts = to_f_uvc_opts(opts_item);
1257 	fmt = to_uvcg_format(ch->item.ci_parent);
1258 
1259 	mutex_lock(&opts->lock);
1260 	if (fmt->linked || opts->refcnt) {
1261 		ret = -EBUSY;
1262 		goto end;
1263 	}
1264 
1265 	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
1266 	if (ret)
1267 		goto end;
1268 
1269 	tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
1270 	if (!frm_intrv) {
1271 		ret = -ENOMEM;
1272 		goto end;
1273 	}
1274 
1275 	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
1276 	if (ret) {
1277 		kfree(frm_intrv);
1278 		goto end;
1279 	}
1280 
1281 	kfree(ch->dw_frame_interval);
1282 	ch->dw_frame_interval = frm_intrv;
1283 	ch->frame.b_frame_interval_type = n;
1284 	sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval),
1285 	     uvcg_config_compare_u32, NULL);
1286 	ret = len;
1287 
1288 end:
1289 	mutex_unlock(&opts->lock);
1290 	mutex_unlock(su_mutex);
1291 	return ret;
1292 }
1293 
1294 UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
1295 
1296 static struct configfs_attribute *uvcg_frame_attrs[] = {
1297 	&uvcg_frame_attr_b_frame_index,
1298 	&uvcg_frame_attr_bm_capabilities,
1299 	&uvcg_frame_attr_w_width,
1300 	&uvcg_frame_attr_w_height,
1301 	&uvcg_frame_attr_dw_min_bit_rate,
1302 	&uvcg_frame_attr_dw_max_bit_rate,
1303 	&uvcg_frame_attr_dw_max_video_frame_buffer_size,
1304 	&uvcg_frame_attr_dw_default_frame_interval,
1305 	&uvcg_frame_attr_dw_frame_interval,
1306 	NULL,
1307 };
1308 
1309 static const struct config_item_type uvcg_frame_type = {
1310 	.ct_item_ops	= &uvcg_config_item_ops,
1311 	.ct_attrs	= uvcg_frame_attrs,
1312 	.ct_owner	= THIS_MODULE,
1313 };
1314 
uvcg_frame_make(struct config_group * group,const char * name)1315 static struct config_item *uvcg_frame_make(struct config_group *group,
1316 					   const char *name)
1317 {
1318 	struct uvcg_frame *h;
1319 	struct uvcg_format *fmt;
1320 	struct f_uvc_opts *opts;
1321 	struct config_item *opts_item;
1322 	struct uvcg_frame_ptr *frame_ptr;
1323 
1324 	h = kzalloc(sizeof(*h), GFP_KERNEL);
1325 	if (!h)
1326 		return ERR_PTR(-ENOMEM);
1327 
1328 	h->frame.b_descriptor_type		= USB_DT_CS_INTERFACE;
1329 	h->frame.b_frame_index			= 1;
1330 	h->frame.w_width			= 640;
1331 	h->frame.w_height			= 360;
1332 	h->frame.dw_min_bit_rate		= 18432000;
1333 	h->frame.dw_max_bit_rate		= 55296000;
1334 	h->frame.dw_max_video_frame_buffer_size	= 460800;
1335 	h->frame.dw_default_frame_interval	= 666666;
1336 
1337 	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1338 	opts = to_f_uvc_opts(opts_item);
1339 
1340 	mutex_lock(&opts->lock);
1341 	fmt = to_uvcg_format(&group->cg_item);
1342 	if (fmt->type == UVCG_UNCOMPRESSED) {
1343 		h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
1344 		h->fmt_type = UVCG_UNCOMPRESSED;
1345 	} else if (fmt->type == UVCG_MJPEG) {
1346 		h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
1347 		h->fmt_type = UVCG_MJPEG;
1348 	} else {
1349 		mutex_unlock(&opts->lock);
1350 		kfree(h);
1351 		return ERR_PTR(-EINVAL);
1352 	}
1353 
1354 	frame_ptr = kzalloc(sizeof(*frame_ptr), GFP_KERNEL);
1355 	if (!frame_ptr) {
1356 		mutex_unlock(&opts->lock);
1357 		kfree(h);
1358 		return ERR_PTR(-ENOMEM);
1359 	}
1360 
1361 	frame_ptr->frm = h;
1362 	list_add_tail(&frame_ptr->entry, &fmt->frames);
1363 	++fmt->num_frames;
1364 	mutex_unlock(&opts->lock);
1365 
1366 	config_item_init_type_name(&h->item, name, &uvcg_frame_type);
1367 
1368 	return &h->item;
1369 }
1370 
uvcg_frame_drop(struct config_group * group,struct config_item * item)1371 static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
1372 {
1373 	struct uvcg_format *fmt;
1374 	struct f_uvc_opts *opts;
1375 	struct config_item *opts_item;
1376 	struct uvcg_frame *target_frm = NULL;
1377 	struct uvcg_frame_ptr *frame_ptr, *tmp;
1378 
1379 	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
1380 	opts = to_f_uvc_opts(opts_item);
1381 
1382 	mutex_lock(&opts->lock);
1383 	target_frm = container_of(item, struct uvcg_frame, item);
1384 	fmt = to_uvcg_format(&group->cg_item);
1385 
1386 	list_for_each_entry_safe(frame_ptr, tmp, &fmt->frames, entry)
1387 		if (frame_ptr->frm == target_frm) {
1388 			list_del(&frame_ptr->entry);
1389 			kfree(frame_ptr);
1390 			--fmt->num_frames;
1391 			break;
1392 		}
1393 	mutex_unlock(&opts->lock);
1394 
1395 	config_item_put(item);
1396 }
1397 
uvcg_format_set_indices(struct config_group * fmt)1398 static void uvcg_format_set_indices(struct config_group *fmt)
1399 {
1400 	struct config_item *ci;
1401 	unsigned int i = 1;
1402 
1403 	list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
1404 		struct uvcg_frame *frm;
1405 
1406 		if (ci->ci_type != &uvcg_frame_type)
1407 			continue;
1408 
1409 		frm = to_uvcg_frame(ci);
1410 		frm->frame.b_frame_index = i++;
1411 	}
1412 }
1413 
1414 /* -----------------------------------------------------------------------------
1415  * streaming/uncompressed/<NAME>
1416  */
1417 
1418 static struct configfs_group_operations uvcg_uncompressed_group_ops = {
1419 	.make_item		= uvcg_frame_make,
1420 	.drop_item		= uvcg_frame_drop,
1421 };
1422 
uvcg_uncompressed_guid_format_show(struct config_item * item,char * page)1423 static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
1424 							char *page)
1425 {
1426 	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1427 	struct f_uvc_opts *opts;
1428 	struct config_item *opts_item;
1429 	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1430 
1431 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1432 
1433 	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1434 	opts = to_f_uvc_opts(opts_item);
1435 
1436 	mutex_lock(&opts->lock);
1437 	memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
1438 	mutex_unlock(&opts->lock);
1439 
1440 	mutex_unlock(su_mutex);
1441 
1442 	return sizeof(ch->desc.guidFormat);
1443 }
1444 
uvcg_uncompressed_guid_format_store(struct config_item * item,const char * page,size_t len)1445 static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
1446 						   const char *page, size_t len)
1447 {
1448 	struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
1449 	struct f_uvc_opts *opts;
1450 	struct config_item *opts_item;
1451 	struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
1452 	int ret;
1453 
1454 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
1455 
1456 	opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
1457 	opts = to_f_uvc_opts(opts_item);
1458 
1459 	mutex_lock(&opts->lock);
1460 	if (ch->fmt.linked || opts->refcnt) {
1461 		ret = -EBUSY;
1462 		goto end;
1463 	}
1464 
1465 	memcpy(ch->desc.guidFormat, page,
1466 	       min(sizeof(ch->desc.guidFormat), len));
1467 	ret = sizeof(ch->desc.guidFormat);
1468 
1469 end:
1470 	mutex_unlock(&opts->lock);
1471 	mutex_unlock(su_mutex);
1472 	return ret;
1473 }
1474 
1475 UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
1476 
1477 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits)			\
1478 static ssize_t uvcg_uncompressed_##cname##_show(			\
1479 	struct config_item *item, char *page)				\
1480 {									\
1481 	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1482 	struct f_uvc_opts *opts;					\
1483 	struct config_item *opts_item;					\
1484 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1485 	int result;							\
1486 									\
1487 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1488 									\
1489 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1490 	opts = to_f_uvc_opts(opts_item);				\
1491 									\
1492 	mutex_lock(&opts->lock);					\
1493 	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1494 	mutex_unlock(&opts->lock);					\
1495 									\
1496 	mutex_unlock(su_mutex);						\
1497 	return result;							\
1498 }									\
1499 									\
1500 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
1501 
1502 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits)			\
1503 static ssize_t uvcg_uncompressed_##cname##_show(			\
1504 	struct config_item *item, char *page)				\
1505 {									\
1506 	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1507 	struct f_uvc_opts *opts;					\
1508 	struct config_item *opts_item;					\
1509 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1510 	int result;							\
1511 									\
1512 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1513 									\
1514 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1515 	opts = to_f_uvc_opts(opts_item);				\
1516 									\
1517 	mutex_lock(&opts->lock);					\
1518 	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1519 	mutex_unlock(&opts->lock);					\
1520 									\
1521 	mutex_unlock(su_mutex);						\
1522 	return result;							\
1523 }									\
1524 									\
1525 static ssize_t								\
1526 uvcg_uncompressed_##cname##_store(struct config_item *item,		\
1527 				    const char *page, size_t len)	\
1528 {									\
1529 	struct uvcg_uncompressed *u = to_uvcg_uncompressed(item);	\
1530 	struct f_uvc_opts *opts;					\
1531 	struct config_item *opts_item;					\
1532 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1533 	int ret;							\
1534 	u8 num;								\
1535 									\
1536 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1537 									\
1538 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1539 	opts = to_f_uvc_opts(opts_item);				\
1540 									\
1541 	mutex_lock(&opts->lock);					\
1542 	if (u->fmt.linked || opts->refcnt) {				\
1543 		ret = -EBUSY;						\
1544 		goto end;						\
1545 	}								\
1546 									\
1547 	ret = kstrtou8(page, 0, &num);					\
1548 	if (ret)							\
1549 		goto end;						\
1550 									\
1551 	/* index values in uvc are never 0 */				\
1552 	if (!num) {							\
1553 		ret = -EINVAL;						\
1554 		goto end;						\
1555 	}								\
1556 									\
1557 	u->desc.aname = num;						\
1558 	ret = len;							\
1559 end:									\
1560 	mutex_unlock(&opts->lock);					\
1561 	mutex_unlock(su_mutex);						\
1562 	return ret;							\
1563 }									\
1564 									\
1565 UVC_ATTR(uvcg_uncompressed_, cname, aname);
1566 
1567 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8);
1568 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8);
1569 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
1570 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
1571 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
1572 UVCG_UNCOMPRESSED_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
1573 
1574 #undef UVCG_UNCOMPRESSED_ATTR
1575 #undef UVCG_UNCOMPRESSED_ATTR_RO
1576 
1577 static inline ssize_t
uvcg_uncompressed_bma_controls_show(struct config_item * item,char * page)1578 uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
1579 {
1580 	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1581 	return uvcg_format_bma_controls_show(&unc->fmt, page);
1582 }
1583 
1584 static inline ssize_t
uvcg_uncompressed_bma_controls_store(struct config_item * item,const char * page,size_t len)1585 uvcg_uncompressed_bma_controls_store(struct config_item *item,
1586 				     const char *page, size_t len)
1587 {
1588 	struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
1589 	return uvcg_format_bma_controls_store(&unc->fmt, page, len);
1590 }
1591 
1592 UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
1593 
1594 static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
1595 	&uvcg_uncompressed_attr_b_format_index,
1596 	&uvcg_uncompressed_attr_guid_format,
1597 	&uvcg_uncompressed_attr_b_bits_per_pixel,
1598 	&uvcg_uncompressed_attr_b_default_frame_index,
1599 	&uvcg_uncompressed_attr_b_aspect_ratio_x,
1600 	&uvcg_uncompressed_attr_b_aspect_ratio_y,
1601 	&uvcg_uncompressed_attr_bm_interlace_flags,
1602 	&uvcg_uncompressed_attr_bma_controls,
1603 	NULL,
1604 };
1605 
1606 static const struct config_item_type uvcg_uncompressed_type = {
1607 	.ct_item_ops	= &uvcg_config_item_ops,
1608 	.ct_group_ops	= &uvcg_uncompressed_group_ops,
1609 	.ct_attrs	= uvcg_uncompressed_attrs,
1610 	.ct_owner	= THIS_MODULE,
1611 };
1612 
uvcg_uncompressed_make(struct config_group * group,const char * name)1613 static struct config_group *uvcg_uncompressed_make(struct config_group *group,
1614 						   const char *name)
1615 {
1616 	static char guid[] = {
1617 		'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
1618 		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
1619 	};
1620 	struct uvcg_uncompressed *h;
1621 
1622 	h = kzalloc(sizeof(*h), GFP_KERNEL);
1623 	if (!h)
1624 		return ERR_PTR(-ENOMEM);
1625 
1626 	h->desc.bLength			= UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
1627 	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1628 	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED;
1629 	memcpy(h->desc.guidFormat, guid, sizeof(guid));
1630 	h->desc.bBitsPerPixel		= 16;
1631 	h->desc.bDefaultFrameIndex	= 1;
1632 	h->desc.bAspectRatioX		= 0;
1633 	h->desc.bAspectRatioY		= 0;
1634 	h->desc.bmInterlaceFlags	= 0;
1635 	h->desc.bCopyProtect		= 0;
1636 
1637 	INIT_LIST_HEAD(&h->fmt.frames);
1638 	h->fmt.type = UVCG_UNCOMPRESSED;
1639 	config_group_init_type_name(&h->fmt.group, name,
1640 				    &uvcg_uncompressed_type);
1641 
1642 	return &h->fmt.group;
1643 }
1644 
1645 static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
1646 	.make_group		= uvcg_uncompressed_make,
1647 };
1648 
1649 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = {
1650 	.type = {
1651 		.ct_item_ops	= &uvcg_config_item_ops,
1652 		.ct_group_ops	= &uvcg_uncompressed_grp_ops,
1653 		.ct_owner	= THIS_MODULE,
1654 	},
1655 	.name = "uncompressed",
1656 };
1657 
1658 /* -----------------------------------------------------------------------------
1659  * streaming/mjpeg/<NAME>
1660  */
1661 
1662 static struct configfs_group_operations uvcg_mjpeg_group_ops = {
1663 	.make_item		= uvcg_frame_make,
1664 	.drop_item		= uvcg_frame_drop,
1665 };
1666 
1667 #define UVCG_MJPEG_ATTR_RO(cname, aname, bits)				\
1668 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1669 {									\
1670 	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1671 	struct f_uvc_opts *opts;					\
1672 	struct config_item *opts_item;					\
1673 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1674 	int result;							\
1675 									\
1676 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1677 									\
1678 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1679 	opts = to_f_uvc_opts(opts_item);				\
1680 									\
1681 	mutex_lock(&opts->lock);					\
1682 	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1683 	mutex_unlock(&opts->lock);					\
1684 									\
1685 	mutex_unlock(su_mutex);						\
1686 	return result;							\
1687 }									\
1688 									\
1689 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
1690 
1691 #define UVCG_MJPEG_ATTR(cname, aname, bits)				\
1692 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
1693 {									\
1694 	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1695 	struct f_uvc_opts *opts;					\
1696 	struct config_item *opts_item;					\
1697 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1698 	int result;							\
1699 									\
1700 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1701 									\
1702 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1703 	opts = to_f_uvc_opts(opts_item);				\
1704 									\
1705 	mutex_lock(&opts->lock);					\
1706 	result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\
1707 	mutex_unlock(&opts->lock);					\
1708 									\
1709 	mutex_unlock(su_mutex);						\
1710 	return result;							\
1711 }									\
1712 									\
1713 static ssize_t								\
1714 uvcg_mjpeg_##cname##_store(struct config_item *item,			\
1715 			   const char *page, size_t len)		\
1716 {									\
1717 	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);			\
1718 	struct f_uvc_opts *opts;					\
1719 	struct config_item *opts_item;					\
1720 	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
1721 	int ret;							\
1722 	u8 num;								\
1723 									\
1724 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1725 									\
1726 	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
1727 	opts = to_f_uvc_opts(opts_item);				\
1728 									\
1729 	mutex_lock(&opts->lock);					\
1730 	if (u->fmt.linked || opts->refcnt) {				\
1731 		ret = -EBUSY;						\
1732 		goto end;						\
1733 	}								\
1734 									\
1735 	ret = kstrtou8(page, 0, &num);					\
1736 	if (ret)							\
1737 		goto end;						\
1738 									\
1739 	/* index values in uvc are never 0 */				\
1740 	if (!num) {							\
1741 		ret = -EINVAL;						\
1742 		goto end;						\
1743 	}								\
1744 									\
1745 	u->desc.aname = num;						\
1746 	ret = len;							\
1747 end:									\
1748 	mutex_unlock(&opts->lock);					\
1749 	mutex_unlock(su_mutex);						\
1750 	return ret;							\
1751 }									\
1752 									\
1753 UVC_ATTR(uvcg_mjpeg_, cname, aname)
1754 
1755 UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8);
1756 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
1757 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8);
1758 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
1759 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
1760 UVCG_MJPEG_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
1761 
1762 #undef UVCG_MJPEG_ATTR
1763 #undef UVCG_MJPEG_ATTR_RO
1764 
1765 static inline ssize_t
uvcg_mjpeg_bma_controls_show(struct config_item * item,char * page)1766 uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
1767 {
1768 	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1769 	return uvcg_format_bma_controls_show(&u->fmt, page);
1770 }
1771 
1772 static inline ssize_t
uvcg_mjpeg_bma_controls_store(struct config_item * item,const char * page,size_t len)1773 uvcg_mjpeg_bma_controls_store(struct config_item *item,
1774 				     const char *page, size_t len)
1775 {
1776 	struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
1777 	return uvcg_format_bma_controls_store(&u->fmt, page, len);
1778 }
1779 
1780 UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
1781 
1782 static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
1783 	&uvcg_mjpeg_attr_b_format_index,
1784 	&uvcg_mjpeg_attr_b_default_frame_index,
1785 	&uvcg_mjpeg_attr_bm_flags,
1786 	&uvcg_mjpeg_attr_b_aspect_ratio_x,
1787 	&uvcg_mjpeg_attr_b_aspect_ratio_y,
1788 	&uvcg_mjpeg_attr_bm_interlace_flags,
1789 	&uvcg_mjpeg_attr_bma_controls,
1790 	NULL,
1791 };
1792 
1793 static const struct config_item_type uvcg_mjpeg_type = {
1794 	.ct_item_ops	= &uvcg_config_item_ops,
1795 	.ct_group_ops	= &uvcg_mjpeg_group_ops,
1796 	.ct_attrs	= uvcg_mjpeg_attrs,
1797 	.ct_owner	= THIS_MODULE,
1798 };
1799 
uvcg_mjpeg_make(struct config_group * group,const char * name)1800 static struct config_group *uvcg_mjpeg_make(struct config_group *group,
1801 						   const char *name)
1802 {
1803 	struct uvcg_mjpeg *h;
1804 
1805 	h = kzalloc(sizeof(*h), GFP_KERNEL);
1806 	if (!h)
1807 		return ERR_PTR(-ENOMEM);
1808 
1809 	h->desc.bLength			= UVC_DT_FORMAT_MJPEG_SIZE;
1810 	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
1811 	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG;
1812 	h->desc.bDefaultFrameIndex	= 1;
1813 	h->desc.bAspectRatioX		= 0;
1814 	h->desc.bAspectRatioY		= 0;
1815 	h->desc.bmInterlaceFlags	= 0;
1816 	h->desc.bCopyProtect		= 0;
1817 
1818 	INIT_LIST_HEAD(&h->fmt.frames);
1819 	h->fmt.type = UVCG_MJPEG;
1820 	config_group_init_type_name(&h->fmt.group, name,
1821 				    &uvcg_mjpeg_type);
1822 
1823 	return &h->fmt.group;
1824 }
1825 
1826 static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
1827 	.make_group		= uvcg_mjpeg_make,
1828 };
1829 
1830 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
1831 	.type = {
1832 		.ct_item_ops	= &uvcg_config_item_ops,
1833 		.ct_group_ops	= &uvcg_mjpeg_grp_ops,
1834 		.ct_owner	= THIS_MODULE,
1835 	},
1836 	.name = "mjpeg",
1837 };
1838 
1839 /* -----------------------------------------------------------------------------
1840  * streaming/color_matching/default
1841  */
1842 
1843 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, bits)		\
1844 static ssize_t uvcg_default_color_matching_##cname##_show(		\
1845 	struct config_item *item, char *page)				\
1846 {									\
1847 	struct config_group *group = to_config_group(item);		\
1848 	struct f_uvc_opts *opts;					\
1849 	struct config_item *opts_item;					\
1850 	struct mutex *su_mutex = &group->cg_subsys->su_mutex;		\
1851 	struct uvc_color_matching_descriptor *cd;			\
1852 	int result;							\
1853 									\
1854 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
1855 									\
1856 	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;	\
1857 	opts = to_f_uvc_opts(opts_item);				\
1858 	cd = &opts->uvc_color_matching;					\
1859 									\
1860 	mutex_lock(&opts->lock);					\
1861 	result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname));	\
1862 	mutex_unlock(&opts->lock);					\
1863 									\
1864 	mutex_unlock(su_mutex);						\
1865 	return result;							\
1866 }									\
1867 									\
1868 UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
1869 
1870 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8);
1871 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
1872 				 bTransferCharacteristics, 8);
1873 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8);
1874 
1875 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
1876 
1877 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
1878 	&uvcg_default_color_matching_attr_b_color_primaries,
1879 	&uvcg_default_color_matching_attr_b_transfer_characteristics,
1880 	&uvcg_default_color_matching_attr_b_matrix_coefficients,
1881 	NULL,
1882 };
1883 
1884 static const struct uvcg_config_group_type uvcg_default_color_matching_type = {
1885 	.type = {
1886 		.ct_item_ops	= &uvcg_config_item_ops,
1887 		.ct_attrs	= uvcg_default_color_matching_attrs,
1888 		.ct_owner	= THIS_MODULE,
1889 	},
1890 	.name = "default",
1891 };
1892 
1893 /* -----------------------------------------------------------------------------
1894  * streaming/color_matching
1895  */
1896 
1897 static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
1898 	.type = {
1899 		.ct_item_ops	= &uvcg_config_item_ops,
1900 		.ct_owner	= THIS_MODULE,
1901 	},
1902 	.name = "color_matching",
1903 	.children = (const struct uvcg_config_group_type*[]) {
1904 		&uvcg_default_color_matching_type,
1905 		NULL,
1906 	},
1907 };
1908 
1909 /* -----------------------------------------------------------------------------
1910  * streaming/class/{fs|hs|ss}
1911  */
1912 
1913 struct uvcg_streaming_class_group {
1914 	struct config_group group;
1915 	const char *name;
1916 };
1917 
1918 static inline struct uvc_descriptor_header
__uvcg_get_stream_class_arr(struct config_item * i,struct f_uvc_opts * o)1919 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
1920 {
1921 	struct uvcg_streaming_class_group *group =
1922 		container_of(i, struct uvcg_streaming_class_group,
1923 			     group.cg_item);
1924 
1925 	if (!strcmp(group->name, "fs"))
1926 		return &o->uvc_fs_streaming_cls;
1927 
1928 	if (!strcmp(group->name, "hs"))
1929 		return &o->uvc_hs_streaming_cls;
1930 
1931 	if (!strcmp(group->name, "ss"))
1932 		return &o->uvc_ss_streaming_cls;
1933 
1934 	return NULL;
1935 }
1936 
1937 enum uvcg_strm_type {
1938 	UVCG_HEADER = 0,
1939 	UVCG_FORMAT,
1940 	UVCG_FRAME
1941 };
1942 
1943 /*
1944  * Iterate over a hierarchy of streaming descriptors' config items.
1945  * The items are created by the user with configfs.
1946  *
1947  * It "processes" the header pointed to by @priv1, then for each format
1948  * that follows the header "processes" the format itself and then for
1949  * each frame inside a format "processes" the frame.
1950  *
1951  * As a "processing" function the @fun is used.
1952  *
1953  * __uvcg_iter_strm_cls() is used in two context: first, to calculate
1954  * the amount of memory needed for an array of streaming descriptors
1955  * and second, to actually fill the array.
1956  *
1957  * @h: streaming header pointer
1958  * @priv2: an "inout" parameter (the caller might want to see the changes to it)
1959  * @priv3: an "inout" parameter (the caller might want to see the changes to it)
1960  * @fun: callback function for processing each level of the hierarchy
1961  */
__uvcg_iter_strm_cls(struct uvcg_streaming_header * h,void * priv2,void * priv3,int (* fun)(void *,void *,void *,int,enum uvcg_strm_type type))1962 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
1963 	void *priv2, void *priv3,
1964 	int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
1965 {
1966 	struct uvcg_format_ptr *f;
1967 	struct config_group *grp;
1968 	struct config_item *item;
1969 	struct uvcg_frame *frm;
1970 	int ret, i, j;
1971 
1972 	if (!fun)
1973 		return -EINVAL;
1974 
1975 	i = j = 0;
1976 	ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
1977 	if (ret)
1978 		return ret;
1979 	list_for_each_entry(f, &h->formats, entry) {
1980 		ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
1981 		if (ret)
1982 			return ret;
1983 		grp = &f->fmt->group;
1984 		list_for_each_entry(item, &grp->cg_children, ci_entry) {
1985 			frm = to_uvcg_frame(item);
1986 			ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
1987 			if (ret)
1988 				return ret;
1989 		}
1990 	}
1991 
1992 	return ret;
1993 }
1994 
1995 /*
1996  * Count how many bytes are needed for an array of streaming descriptors.
1997  *
1998  * @priv1: pointer to a header, format or frame
1999  * @priv2: inout parameter, accumulated size of the array
2000  * @priv3: inout parameter, accumulated number of the array elements
2001  * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
2002  */
__uvcg_cnt_strm(void * priv1,void * priv2,void * priv3,int n,enum uvcg_strm_type type)2003 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
2004 			   enum uvcg_strm_type type)
2005 {
2006 	size_t *size = priv2;
2007 	size_t *count = priv3;
2008 
2009 	switch (type) {
2010 	case UVCG_HEADER: {
2011 		struct uvcg_streaming_header *h = priv1;
2012 
2013 		*size += sizeof(h->desc);
2014 		/* bmaControls */
2015 		*size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
2016 	}
2017 	break;
2018 	case UVCG_FORMAT: {
2019 		struct uvcg_format *fmt = priv1;
2020 
2021 		if (fmt->type == UVCG_UNCOMPRESSED) {
2022 			struct uvcg_uncompressed *u =
2023 				container_of(fmt, struct uvcg_uncompressed,
2024 					     fmt);
2025 
2026 			*size += sizeof(u->desc);
2027 		} else if (fmt->type == UVCG_MJPEG) {
2028 			struct uvcg_mjpeg *m =
2029 				container_of(fmt, struct uvcg_mjpeg, fmt);
2030 
2031 			*size += sizeof(m->desc);
2032 		} else {
2033 			return -EINVAL;
2034 		}
2035 	}
2036 	break;
2037 	case UVCG_FRAME: {
2038 		struct uvcg_frame *frm = priv1;
2039 		int sz = sizeof(frm->dw_frame_interval);
2040 
2041 		*size += sizeof(frm->frame);
2042 		*size += frm->frame.b_frame_interval_type * sz;
2043 	}
2044 	break;
2045 	}
2046 
2047 	++*count;
2048 
2049 	return 0;
2050 }
2051 
2052 /*
2053  * Fill an array of streaming descriptors.
2054  *
2055  * @priv1: pointer to a header, format or frame
2056  * @priv2: inout parameter, pointer into a block of memory
2057  * @priv3: inout parameter, pointer to a 2-dimensional array
2058  */
__uvcg_fill_strm(void * priv1,void * priv2,void * priv3,int n,enum uvcg_strm_type type)2059 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
2060 			    enum uvcg_strm_type type)
2061 {
2062 	void **dest = priv2;
2063 	struct uvc_descriptor_header ***array = priv3;
2064 	size_t sz;
2065 
2066 	**array = *dest;
2067 	++*array;
2068 
2069 	switch (type) {
2070 	case UVCG_HEADER: {
2071 		struct uvc_input_header_descriptor *ihdr = *dest;
2072 		struct uvcg_streaming_header *h = priv1;
2073 		struct uvcg_format_ptr *f;
2074 
2075 		memcpy(*dest, &h->desc, sizeof(h->desc));
2076 		*dest += sizeof(h->desc);
2077 		sz = UVCG_STREAMING_CONTROL_SIZE;
2078 		list_for_each_entry(f, &h->formats, entry) {
2079 			memcpy(*dest, f->fmt->bmaControls, sz);
2080 			*dest += sz;
2081 		}
2082 		ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
2083 		ihdr->bNumFormats = h->num_fmt;
2084 	}
2085 	break;
2086 	case UVCG_FORMAT: {
2087 		struct uvcg_format *fmt = priv1;
2088 
2089 		if (fmt->type == UVCG_UNCOMPRESSED) {
2090 			struct uvcg_uncompressed *u =
2091 				container_of(fmt, struct uvcg_uncompressed,
2092 					     fmt);
2093 
2094 			u->desc.bFormatIndex = n + 1;
2095 			u->desc.bNumFrameDescriptors = fmt->num_frames;
2096 			memcpy(*dest, &u->desc, sizeof(u->desc));
2097 			*dest += sizeof(u->desc);
2098 		} else if (fmt->type == UVCG_MJPEG) {
2099 			struct uvcg_mjpeg *m =
2100 				container_of(fmt, struct uvcg_mjpeg, fmt);
2101 
2102 			m->desc.bFormatIndex = n + 1;
2103 			m->desc.bNumFrameDescriptors = fmt->num_frames;
2104 			memcpy(*dest, &m->desc, sizeof(m->desc));
2105 			*dest += sizeof(m->desc);
2106 		} else {
2107 			return -EINVAL;
2108 		}
2109 	}
2110 	break;
2111 	case UVCG_FRAME: {
2112 		struct uvcg_frame *frm = priv1;
2113 		struct uvc_descriptor_header *h = *dest;
2114 
2115 		sz = sizeof(frm->frame);
2116 		memcpy(*dest, &frm->frame, sz);
2117 		*dest += sz;
2118 		sz = frm->frame.b_frame_interval_type *
2119 			sizeof(*frm->dw_frame_interval);
2120 		memcpy(*dest, frm->dw_frame_interval, sz);
2121 		*dest += sz;
2122 		if (frm->fmt_type == UVCG_UNCOMPRESSED)
2123 			h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
2124 				frm->frame.b_frame_interval_type);
2125 		else if (frm->fmt_type == UVCG_MJPEG)
2126 			h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
2127 				frm->frame.b_frame_interval_type);
2128 	}
2129 	break;
2130 	}
2131 
2132 	return 0;
2133 }
2134 
uvcg_streaming_class_allow_link(struct config_item * src,struct config_item * target)2135 static int uvcg_streaming_class_allow_link(struct config_item *src,
2136 					   struct config_item *target)
2137 {
2138 	struct config_item *streaming, *header;
2139 	struct f_uvc_opts *opts;
2140 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2141 	struct uvc_descriptor_header ***class_array, **cl_arr;
2142 	struct uvcg_streaming_header *target_hdr;
2143 	void *data, *data_save;
2144 	size_t size = 0, count = 0;
2145 	int ret = -EINVAL;
2146 
2147 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2148 
2149 	streaming = src->ci_parent->ci_parent;
2150 	header = config_group_find_item(to_config_group(streaming), "header");
2151 	if (!header || target->ci_parent != header)
2152 		goto out;
2153 
2154 	opts = to_f_uvc_opts(streaming->ci_parent);
2155 
2156 	mutex_lock(&opts->lock);
2157 
2158 	class_array = __uvcg_get_stream_class_arr(src, opts);
2159 	if (!class_array || *class_array || opts->refcnt) {
2160 		ret = -EBUSY;
2161 		goto unlock;
2162 	}
2163 
2164 	target_hdr = to_uvcg_streaming_header(target);
2165 	ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
2166 	if (ret)
2167 		goto unlock;
2168 
2169 	count += 2; /* color_matching, NULL */
2170 	*class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
2171 	if (!*class_array) {
2172 		ret = -ENOMEM;
2173 		goto unlock;
2174 	}
2175 
2176 	data = data_save = kzalloc(size, GFP_KERNEL);
2177 	if (!data) {
2178 		kfree(*class_array);
2179 		*class_array = NULL;
2180 		ret = -ENOMEM;
2181 		goto unlock;
2182 	}
2183 	cl_arr = *class_array;
2184 	ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
2185 				   __uvcg_fill_strm);
2186 	if (ret) {
2187 		kfree(*class_array);
2188 		*class_array = NULL;
2189 		/*
2190 		 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
2191 		 * might have advanced the "data", so use a backup copy
2192 		 */
2193 		kfree(data_save);
2194 		goto unlock;
2195 	}
2196 	*cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;
2197 
2198 	++target_hdr->linked;
2199 	ret = 0;
2200 
2201 unlock:
2202 	mutex_unlock(&opts->lock);
2203 out:
2204 	config_item_put(header);
2205 	mutex_unlock(su_mutex);
2206 	return ret;
2207 }
2208 
uvcg_streaming_class_drop_link(struct config_item * src,struct config_item * target)2209 static void uvcg_streaming_class_drop_link(struct config_item *src,
2210 					  struct config_item *target)
2211 {
2212 	struct config_item *streaming, *header;
2213 	struct f_uvc_opts *opts;
2214 	struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
2215 	struct uvc_descriptor_header ***class_array;
2216 	struct uvcg_streaming_header *target_hdr;
2217 
2218 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2219 
2220 	streaming = src->ci_parent->ci_parent;
2221 	header = config_group_find_item(to_config_group(streaming), "header");
2222 	if (!header || target->ci_parent != header)
2223 		goto out;
2224 
2225 	opts = to_f_uvc_opts(streaming->ci_parent);
2226 
2227 	mutex_lock(&opts->lock);
2228 
2229 	class_array = __uvcg_get_stream_class_arr(src, opts);
2230 	if (!class_array || !*class_array)
2231 		goto unlock;
2232 
2233 	if (opts->refcnt)
2234 		goto unlock;
2235 
2236 	target_hdr = to_uvcg_streaming_header(target);
2237 	--target_hdr->linked;
2238 	kfree(**class_array);
2239 	kfree(*class_array);
2240 	*class_array = NULL;
2241 
2242 unlock:
2243 	mutex_unlock(&opts->lock);
2244 out:
2245 	config_item_put(header);
2246 	mutex_unlock(su_mutex);
2247 }
2248 
2249 static struct configfs_item_operations uvcg_streaming_class_item_ops = {
2250 	.release	= uvcg_config_item_release,
2251 	.allow_link	= uvcg_streaming_class_allow_link,
2252 	.drop_link	= uvcg_streaming_class_drop_link,
2253 };
2254 
2255 static const struct config_item_type uvcg_streaming_class_type = {
2256 	.ct_item_ops	= &uvcg_streaming_class_item_ops,
2257 	.ct_owner	= THIS_MODULE,
2258 };
2259 
2260 /* -----------------------------------------------------------------------------
2261  * streaming/class
2262  */
2263 
uvcg_streaming_class_create_children(struct config_group * parent)2264 static int uvcg_streaming_class_create_children(struct config_group *parent)
2265 {
2266 	static const char * const names[] = { "fs", "hs", "ss" };
2267 	unsigned int i;
2268 
2269 	for (i = 0; i < ARRAY_SIZE(names); ++i) {
2270 		struct uvcg_streaming_class_group *group;
2271 
2272 		group = kzalloc(sizeof(*group), GFP_KERNEL);
2273 		if (!group)
2274 			return -ENOMEM;
2275 
2276 		group->name = names[i];
2277 
2278 		config_group_init_type_name(&group->group, group->name,
2279 					    &uvcg_streaming_class_type);
2280 		configfs_add_default_group(&group->group, parent);
2281 	}
2282 
2283 	return 0;
2284 }
2285 
2286 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = {
2287 	.type = {
2288 		.ct_item_ops	= &uvcg_config_item_ops,
2289 		.ct_owner	= THIS_MODULE,
2290 	},
2291 	.name = "class",
2292 	.create_children = uvcg_streaming_class_create_children,
2293 };
2294 
2295 /* -----------------------------------------------------------------------------
2296  * streaming
2297  */
2298 
uvcg_default_streaming_b_interface_number_show(struct config_item * item,char * page)2299 static ssize_t uvcg_default_streaming_b_interface_number_show(
2300 	struct config_item *item, char *page)
2301 {
2302 	struct config_group *group = to_config_group(item);
2303 	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
2304 	struct config_item *opts_item;
2305 	struct f_uvc_opts *opts;
2306 	int result = 0;
2307 
2308 	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
2309 
2310 	opts_item = item->ci_parent;
2311 	opts = to_f_uvc_opts(opts_item);
2312 
2313 	mutex_lock(&opts->lock);
2314 	result += sprintf(page, "%u\n", opts->streaming_interface);
2315 	mutex_unlock(&opts->lock);
2316 
2317 	mutex_unlock(su_mutex);
2318 
2319 	return result;
2320 }
2321 
2322 UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber);
2323 
2324 static struct configfs_attribute *uvcg_default_streaming_attrs[] = {
2325 	&uvcg_default_streaming_attr_b_interface_number,
2326 	NULL,
2327 };
2328 
2329 static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
2330 	.type = {
2331 		.ct_item_ops	= &uvcg_config_item_ops,
2332 		.ct_attrs	= uvcg_default_streaming_attrs,
2333 		.ct_owner	= THIS_MODULE,
2334 	},
2335 	.name = "streaming",
2336 	.children = (const struct uvcg_config_group_type*[]) {
2337 		&uvcg_streaming_header_grp_type,
2338 		&uvcg_uncompressed_grp_type,
2339 		&uvcg_mjpeg_grp_type,
2340 		&uvcg_color_matching_grp_type,
2341 		&uvcg_streaming_class_grp_type,
2342 		NULL,
2343 	},
2344 };
2345 
2346 /* -----------------------------------------------------------------------------
2347  * UVC function
2348  */
2349 
uvc_func_item_release(struct config_item * item)2350 static void uvc_func_item_release(struct config_item *item)
2351 {
2352 	struct f_uvc_opts *opts = to_f_uvc_opts(item);
2353 
2354 	uvcg_config_remove_children(to_config_group(item));
2355 	usb_put_function_instance(&opts->func_inst);
2356 }
2357 
2358 static struct configfs_item_operations uvc_func_item_ops = {
2359 	.release	= uvc_func_item_release,
2360 };
2361 
2362 #define UVCG_OPTS_ATTR(cname, aname, limit)				\
2363 static ssize_t f_uvc_opts_##cname##_show(				\
2364 	struct config_item *item, char *page)				\
2365 {									\
2366 	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2367 	int result;							\
2368 									\
2369 	mutex_lock(&opts->lock);					\
2370 	result = sprintf(page, "%u\n", opts->cname);			\
2371 	mutex_unlock(&opts->lock);					\
2372 									\
2373 	return result;							\
2374 }									\
2375 									\
2376 static ssize_t								\
2377 f_uvc_opts_##cname##_store(struct config_item *item,			\
2378 			   const char *page, size_t len)		\
2379 {									\
2380 	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2381 	unsigned int num;						\
2382 	int ret;							\
2383 									\
2384 	mutex_lock(&opts->lock);					\
2385 	if (opts->refcnt) {						\
2386 		ret = -EBUSY;						\
2387 		goto end;						\
2388 	}								\
2389 									\
2390 	ret = kstrtouint(page, 0, &num);				\
2391 	if (ret)							\
2392 		goto end;						\
2393 									\
2394 	if (num > limit) {						\
2395 		ret = -EINVAL;						\
2396 		goto end;						\
2397 	}								\
2398 	opts->cname = num;						\
2399 	ret = len;							\
2400 end:									\
2401 	mutex_unlock(&opts->lock);					\
2402 	return ret;							\
2403 }									\
2404 									\
2405 UVC_ATTR(f_uvc_opts_, cname, cname)
2406 
2407 UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16);
2408 UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072);
2409 UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15);
2410 
2411 #undef UVCG_OPTS_ATTR
2412 
2413 #define UVCG_OPTS_STRING_ATTR(cname, aname)				\
2414 static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\
2415 					 char *page)			\
2416 {									\
2417 	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2418 	int result;							\
2419 									\
2420 	mutex_lock(&opts->lock);					\
2421 	result = snprintf(page, sizeof(opts->aname), "%s", opts->aname);\
2422 	mutex_unlock(&opts->lock);					\
2423 									\
2424 	return result;							\
2425 }									\
2426 									\
2427 static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\
2428 					  const char *page, size_t len)	\
2429 {									\
2430 	struct f_uvc_opts *opts = to_f_uvc_opts(item);			\
2431 	int size = min(sizeof(opts->aname), len + 1);			\
2432 	int ret = 0;							\
2433 									\
2434 	mutex_lock(&opts->lock);					\
2435 	if (opts->refcnt) {						\
2436 		ret = -EBUSY;						\
2437 		goto end;						\
2438 	}								\
2439 									\
2440 	ret = strscpy(opts->aname, page, size);				\
2441 	if (ret == -E2BIG)						\
2442 		ret = size - 1;						\
2443 									\
2444 end:									\
2445 	mutex_unlock(&opts->lock);					\
2446 	return ret;							\
2447 }									\
2448 									\
2449 UVC_ATTR(f_uvc_opts_string_, cname, aname)
2450 
2451 UVCG_OPTS_STRING_ATTR(function_name, function_name);
2452 
2453 #undef UVCG_OPTS_STRING_ATTR
2454 
2455 static struct configfs_attribute *uvc_attrs[] = {
2456 	&f_uvc_opts_attr_streaming_interval,
2457 	&f_uvc_opts_attr_streaming_maxpacket,
2458 	&f_uvc_opts_attr_streaming_maxburst,
2459 	&f_uvc_opts_string_attr_function_name,
2460 	NULL,
2461 };
2462 
2463 static const struct uvcg_config_group_type uvc_func_type = {
2464 	.type = {
2465 		.ct_item_ops	= &uvc_func_item_ops,
2466 		.ct_attrs	= uvc_attrs,
2467 		.ct_owner	= THIS_MODULE,
2468 	},
2469 	.name = "",
2470 	.children = (const struct uvcg_config_group_type*[]) {
2471 		&uvcg_control_grp_type,
2472 		&uvcg_streaming_grp_type,
2473 		NULL,
2474 	},
2475 };
2476 
uvcg_attach_configfs(struct f_uvc_opts * opts)2477 int uvcg_attach_configfs(struct f_uvc_opts *opts)
2478 {
2479 	int ret;
2480 
2481 	config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
2482 				    &uvc_func_type.type);
2483 
2484 	ret = uvcg_config_create_children(&opts->func_inst.group,
2485 					  &uvc_func_type);
2486 	if (ret < 0)
2487 		config_group_put(&opts->func_inst.group);
2488 
2489 	return ret;
2490 }
2491