linux/drivers/usb/gadget/function/uvc_configfs.c
<<
>>
Prefs
   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 <andrzej.p@samsung.com>
  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) \
  21static 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) \
  30static 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
  37static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
  38
  39/* control/header/<NAME> */
  40DECLARE_UVC_HEADER_DESCRIPTOR(1);
  41
  42struct uvcg_control_header {
  43        struct config_item              item;
  44        struct UVC_HEADER_DESCRIPTOR(1) desc;
  45        unsigned                        linked;
  46};
  47
  48static 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) \
  54static 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                                                                        \
  76static ssize_t                                                          \
  77uvcg_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;                                                      \
 108end:                                                                    \
 109        mutex_unlock(&opts->lock);                                      \
 110        mutex_unlock(su_mutex);                                         \
 111        return ret;                                                     \
 112}                                                                       \
 113                                                                        \
 114UVC_ATTR(uvcg_control_header_, cname, aname)
 115
 116UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16,
 117                   0xffff);
 118
 119UVCG_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
 124static 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
 130static struct config_item_type uvcg_control_header_type = {
 131        .ct_attrs       = uvcg_control_header_attrs,
 132        .ct_owner       = THIS_MODULE,
 133};
 134
 135static 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
 155static 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 */
 164static struct uvcg_control_header_grp {
 165        struct config_group     group;
 166} uvcg_control_header_grp;
 167
 168static 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
 173static 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 */
 179static struct uvcg_default_processing {
 180        struct config_group     group;
 181} uvcg_default_processing;
 182
 183static 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)                \
 191static 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                                                                        \
 215UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
 216
 217#define identity_conv(x) (x)
 218
 219UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv);
 220UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv);
 221UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu);
 222UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv);
 223
 224#undef identity_conv
 225
 226#undef UVCG_DEFAULT_PROCESSING_ATTR
 227
 228static 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
 257UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls);
 258
 259static 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
 268static 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 */
 276static struct uvcg_processing_grp {
 277        struct config_group     group;
 278} uvcg_processing_grp;
 279
 280static struct config_item_type uvcg_processing_grp_type = {
 281        .ct_owner = THIS_MODULE,
 282};
 283
 284/* control/terminal/camera/default */
 285static struct uvcg_default_camera {
 286        struct config_group     group;
 287} uvcg_default_camera;
 288
 289static 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)                    \
 297static 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                                                                        \
 323UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
 324
 325#define identity_conv(x) (x)
 326
 327UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv);
 328UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
 329UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
 330UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv);
 331UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin,
 332                         le16_to_cpu);
 333UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax,
 334                         le16_to_cpu);
 335UVCG_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
 342static 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
 371UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls);
 372
 373static 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
 385static 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 */
 393static struct uvcg_camera_grp {
 394        struct config_group     group;
 395} uvcg_camera_grp;
 396
 397static struct config_item_type uvcg_camera_grp_type = {
 398        .ct_owner = THIS_MODULE,
 399};
 400
 401/* control/terminal/output/default */
 402static struct uvcg_default_output {
 403        struct config_group     group;
 404} uvcg_default_output;
 405
 406static 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)                    \
 414static 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                                                                        \
 440UVC_ATTR_RO(uvcg_default_output_, cname, aname)
 441
 442#define identity_conv(x) (x)
 443
 444UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv);
 445UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
 446UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
 447UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv);
 448UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv);
 449
 450#undef identity_conv
 451
 452#undef UVCG_DEFAULT_OUTPUT_ATTR
 453
 454static 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
 463static 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 */
 471static struct uvcg_output_grp {
 472        struct config_group     group;
 473} uvcg_output_grp;
 474
 475static struct config_item_type uvcg_output_grp_type = {
 476        .ct_owner = THIS_MODULE,
 477};
 478
 479/* control/terminal */
 480static struct uvcg_terminal_grp {
 481        struct config_group     group;
 482} uvcg_terminal_grp;
 483
 484static struct config_item_type uvcg_terminal_grp_type = {
 485        .ct_owner = THIS_MODULE,
 486};
 487
 488/* control/class/{fs} */
 489static struct uvcg_control_class {
 490        struct config_group     group;
 491} uvcg_control_class_fs, uvcg_control_class_ss;
 492
 493
 494static 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
 509static 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
 543unlock:
 544        mutex_unlock(&opts->lock);
 545out:
 546        mutex_unlock(su_mutex);
 547        return ret;
 548}
 549
 550static 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
 578unlock:
 579        mutex_unlock(&opts->lock);
 580out:
 581        mutex_unlock(su_mutex);
 582}
 583
 584static 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
 589static 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 */
 595static struct uvcg_control_class_grp {
 596        struct config_group     group;
 597} uvcg_control_class_grp;
 598
 599static struct config_item_type uvcg_control_class_grp_type = {
 600        .ct_owner = THIS_MODULE,
 601};
 602
 603/* control */
 604static struct uvcg_control_grp {
 605        struct config_group     group;
 606} uvcg_control_grp;
 607
 608static struct config_item_type uvcg_control_grp_type = {
 609        .ct_owner = THIS_MODULE,
 610};
 611
 612/* streaming/uncompressed */
 613static struct uvcg_uncompressed_grp {
 614        struct config_group     group;
 615} uvcg_uncompressed_grp;
 616
 617/* streaming/mjpeg */
 618static struct uvcg_mjpeg_grp {
 619        struct config_group     group;
 620} uvcg_mjpeg_grp;
 621
 622static struct config_item *fmt_parent[] = {
 623        &uvcg_uncompressed_grp.group.cg_item,
 624        &uvcg_mjpeg_grp.group.cg_item,
 625};
 626
 627enum uvcg_format_type {
 628        UVCG_UNCOMPRESSED = 0,
 629        UVCG_MJPEG,
 630};
 631
 632struct 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
 640static 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
 645static 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
 671static 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;
 697end:
 698        mutex_unlock(&opts->lock);
 699        mutex_unlock(su_mutex);
 700        return ret;
 701}
 702
 703struct uvcg_format_ptr {
 704        struct uvcg_format      *fmt;
 705        struct list_head        entry;
 706};
 707
 708/* streaming/header/<NAME> */
 709struct 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
 717static 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
 722static 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
 767out:
 768        mutex_unlock(&opts->lock);
 769        mutex_unlock(su_mutex);
 770        return ret;
 771}
 772
 773static 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
 803out:
 804        mutex_unlock(&opts->lock);
 805        mutex_unlock(su_mutex);
 806}
 807
 808static 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)                  \
 814static 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                                                                        \
 836UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
 837
 838#define identity_conv(x) (x)
 839
 840UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv);
 841UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv);
 842UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod,
 843                           identity_conv);
 844UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv);
 845UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv);
 846
 847#undef identity_conv
 848
 849#undef UVCG_STREAMING_HEADER_ATTR
 850
 851static 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
 860static 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
 866static 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
 886static 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 */
 895static struct uvcg_streaming_header_grp {
 896        struct config_group     group;
 897} uvcg_streaming_header_grp;
 898
 899static 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
 904static 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> */
 910struct 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
 930static 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) \
 936static 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                                                                        \
 957static 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;                                                      \
 986end:                                                                    \
 987        mutex_unlock(&opts->lock);                                      \
 988        mutex_unlock(su_mutex);                                         \
 989        return ret;                                                     \
 990}                                                                       \
 991                                                                        \
 992UVC_ATTR(uvcg_frame_, cname, aname);
 993
 994#define noop_conversion(x) (x)
 995
 996UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
 997                noop_conversion, 8);
 998UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
 999UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16);
1000UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32);
1001UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32);
1002UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize,
1003                le32_to_cpu, cpu_to_le32, 32);
1004UVCG_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
1011static 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
1038static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
1039{
1040        ++*((int *)priv);
1041        return 0;
1042}
1043
1044static 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
1060static 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
1089static 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
1133end:
1134        mutex_unlock(&opts->lock);
1135        mutex_unlock(su_mutex);
1136        return ret;
1137}
1138
1139UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
1140
1141static 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
1153static struct config_item_type uvcg_frame_type = {
1154        .ct_attrs       = uvcg_frame_attrs,
1155        .ct_owner       = THIS_MODULE,
1156};
1157
1158static 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
1203static 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> */
1221struct uvcg_uncompressed {
1222        struct uvcg_format              fmt;
1223        struct uvc_format_uncompressed  desc;
1224};
1225
1226static 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
1233static struct configfs_group_operations uvcg_uncompressed_group_ops = {
1234        .make_item              = uvcg_frame_make,
1235        .drop_item              = uvcg_frame_drop,
1236};
1237
1238static 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
1260static 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
1284end:
1285        mutex_unlock(&opts->lock);
1286        mutex_unlock(su_mutex);
1287        return ret;
1288}
1289
1290UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
1291
1292#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv)                   \
1293static 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                                                                        \
1315UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
1316
1317#define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv)                      \
1318static 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                                                                        \
1340static ssize_t                                                          \
1341uvcg_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;                                                      \
1372end:                                                                    \
1373        mutex_unlock(&opts->lock);                                      \
1374        mutex_unlock(su_mutex);                                         \
1375        return ret;                                                     \
1376}                                                                       \
1377                                                                        \
1378UVC_ATTR(uvcg_uncompressed_, cname, aname);
1379
1380#define identity_conv(x) (x)
1381
1382UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv);
1383UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex,
1384                       identity_conv);
1385UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1386UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1387UVCG_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
1394static inline ssize_t
1395uvcg_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
1401static inline ssize_t
1402uvcg_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
1409UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
1410
1411static 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
1422static 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
1428static 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
1459static 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
1467static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
1468        .make_group             = uvcg_uncompressed_make,
1469        .drop_item              = uvcg_uncompressed_drop,
1470};
1471
1472static 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> */
1478struct uvcg_mjpeg {
1479        struct uvcg_format              fmt;
1480        struct uvc_format_mjpeg         desc;
1481};
1482
1483static 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
1490static 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)                          \
1496static 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                                                                        \
1517UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
1518
1519#define UVCG_MJPEG_ATTR(cname, aname, conv)                             \
1520static 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                                                                        \
1541static ssize_t                                                          \
1542uvcg_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;                                                      \
1573end:                                                                    \
1574        mutex_unlock(&opts->lock);                                      \
1575        mutex_unlock(su_mutex);                                         \
1576        return ret;                                                     \
1577}                                                                       \
1578                                                                        \
1579UVC_ATTR(uvcg_mjpeg_, cname, aname)
1580
1581#define identity_conv(x) (x)
1582
1583UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex,
1584                       identity_conv);
1585UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv);
1586UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
1587UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
1588UVCG_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
1595static inline ssize_t
1596uvcg_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
1602static inline ssize_t
1603uvcg_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
1610UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
1611
1612static 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
1622static 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
1628static 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
1653static 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
1661static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
1662        .make_group             = uvcg_mjpeg_make,
1663        .drop_item              = uvcg_mjpeg_drop,
1664};
1665
1666static 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 */
1672static struct uvcg_default_color_matching {
1673        struct config_group     group;
1674} uvcg_default_color_matching;
1675
1676static 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)            \
1684static 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                                                                        \
1709UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
1710
1711#define identity_conv(x) (x)
1712
1713UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries,
1714                                 identity_conv);
1715UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
1716                                 bTransferCharacteristics, identity_conv);
1717UVCG_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
1724static 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
1731static 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 */
1739static struct uvcg_color_matching_grp {
1740        struct config_group     group;
1741} uvcg_color_matching_grp;
1742
1743static struct config_item_type uvcg_color_matching_grp_type = {
1744        .ct_owner = THIS_MODULE,
1745};
1746
1747/* streaming/class/{fs|hs|ss} */
1748static struct uvcg_streaming_class {
1749        struct config_group     group;
1750} uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss;
1751
1752
1753static 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
1771enum 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 */
1796static 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 */
1837static 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 */
1893static 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
1971static 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
2037unlock:
2038        mutex_unlock(&opts->lock);
2039out:
2040        mutex_unlock(su_mutex);
2041        return ret;
2042}
2043
2044static 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
2077unlock:
2078        mutex_unlock(&opts->lock);
2079out:
2080        mutex_unlock(su_mutex);
2081}
2082
2083static 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
2088static 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 */
2094static struct uvcg_streaming_class_grp {
2095        struct config_group     group;
2096} uvcg_streaming_class_grp;
2097
2098static struct config_item_type uvcg_streaming_class_grp_type = {
2099        .ct_owner = THIS_MODULE,
2100};
2101
2102/* streaming */
2103static struct uvcg_streaming_grp {
2104        struct config_group     group;
2105} uvcg_streaming_grp;
2106
2107static struct config_item_type uvcg_streaming_grp_type = {
2108        .ct_owner = THIS_MODULE,
2109};
2110
2111static 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
2117static 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
2124static 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)            \
2129static 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                                                                        \
2142static ssize_t                                                          \
2143f_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;                                                      \
2166end:                                                                    \
2167        mutex_unlock(&opts->lock);                                      \
2168        return ret;                                                     \
2169}                                                                       \
2170                                                                        \
2171UVC_ATTR(f_uvc_opts_, cname, aname)
2172
2173#define identity_conv(x) (x)
2174
2175UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv,
2176               16);
2177UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu,
2178               3072);
2179UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
2180               15);
2181
2182#undef identity_conv
2183
2184#undef UVCG_OPTS_ATTR
2185
2186static 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
2193static 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
2199int 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}
2313