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