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