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