1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * uvc_configfs.c 4 * 5 * Configfs support for the uvc function. 6 * 7 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 8 * http://www.samsung.com 9 * 10 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 11 */ 12 13 #include "uvc_configfs.h" 14 15 #include <linux/hex.h> 16 #include <linux/sort.h> 17 #include <linux/usb/uvc.h> 18 #include <linux/usb/video.h> 19 20 /* ----------------------------------------------------------------------------- 21 * Global Utility Structures and Macros 22 */ 23 24 #define UVC_ATTR(prefix, cname, aname) \ 25 static struct configfs_attribute prefix##attr_##cname = { \ 26 .ca_name = __stringify(aname), \ 27 .ca_mode = S_IRUGO | S_IWUGO, \ 28 .ca_owner = THIS_MODULE, \ 29 .show = prefix##cname##_show, \ 30 .store = prefix##cname##_store, \ 31 } 32 33 #define UVC_ATTR_RO(prefix, cname, aname) \ 34 static struct configfs_attribute prefix##attr_##cname = { \ 35 .ca_name = __stringify(aname), \ 36 .ca_mode = S_IRUGO, \ 37 .ca_owner = THIS_MODULE, \ 38 .show = prefix##cname##_show, \ 39 } 40 41 #define le8_to_cpu(x) (x) 42 #define cpu_to_le8(x) (x) 43 44 static int uvcg_config_compare_u32(const void *l, const void *r) 45 { 46 u32 li = *(const u32 *)l; 47 u32 ri = *(const u32 *)r; 48 49 return li < ri ? -1 : li == ri ? 0 : 1; 50 } 51 52 static inline int __uvcg_count_item_entries(char *buf, void *priv, unsigned int size) 53 { 54 ++*((int *)priv); 55 return 0; 56 } 57 58 static inline int __uvcg_fill_item_entries(char *buf, void *priv, unsigned int size) 59 { 60 unsigned int num; 61 u8 **values; 62 int ret; 63 64 ret = kstrtouint(buf, 0, &num); 65 if (ret) 66 return ret; 67 68 if (num != (num & GENMASK((size * 8) - 1, 0))) 69 return -ERANGE; 70 71 values = priv; 72 memcpy(*values, &num, size); 73 *values += size; 74 75 return 0; 76 } 77 78 static int __uvcg_iter_item_entries(const char *page, size_t len, 79 int (*fun)(char *, void *, unsigned int), 80 void *priv, unsigned int size) 81 { 82 /* sign, base 2 representation, newline, terminator */ 83 unsigned int bufsize = 1 + size * 8 + 1 + 1; 84 const char *pg = page; 85 int i, ret = 0; 86 char *buf; 87 88 if (!fun) 89 return -EINVAL; 90 91 buf = kzalloc(bufsize, GFP_KERNEL); 92 if (!buf) 93 return -ENOMEM; 94 95 while (pg - page < len) { 96 i = 0; 97 while (i < bufsize && (pg - page < len) && 98 *pg != '\0' && *pg != '\n') 99 buf[i++] = *pg++; 100 if (i == bufsize) { 101 ret = -EINVAL; 102 goto out_free_buf; 103 } 104 while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 105 ++pg; 106 buf[i] = '\0'; 107 ret = fun(buf, priv, size); 108 if (ret) 109 goto out_free_buf; 110 } 111 112 out_free_buf: 113 kfree(buf); 114 return ret; 115 } 116 117 struct uvcg_config_group_type { 118 struct config_item_type type; 119 const char *name; 120 const struct uvcg_config_group_type **children; 121 int (*create_children)(struct config_group *group); 122 }; 123 124 static void uvcg_config_item_release(struct config_item *item) 125 { 126 struct config_group *group = to_config_group(item); 127 128 kfree(group); 129 } 130 131 static struct configfs_item_operations uvcg_config_item_ops = { 132 .release = uvcg_config_item_release, 133 }; 134 135 static int uvcg_config_create_group(struct config_group *parent, 136 const struct uvcg_config_group_type *type); 137 138 static int uvcg_config_create_children(struct config_group *group, 139 const struct uvcg_config_group_type *type) 140 { 141 const struct uvcg_config_group_type **child; 142 int ret; 143 144 if (type->create_children) 145 return type->create_children(group); 146 147 for (child = type->children; child && *child; ++child) { 148 ret = uvcg_config_create_group(group, *child); 149 if (ret < 0) 150 return ret; 151 } 152 153 return 0; 154 } 155 156 static int uvcg_config_create_group(struct config_group *parent, 157 const struct uvcg_config_group_type *type) 158 { 159 struct config_group *group; 160 161 group = kzalloc(sizeof(*group), GFP_KERNEL); 162 if (!group) 163 return -ENOMEM; 164 165 config_group_init_type_name(group, type->name, &type->type); 166 configfs_add_default_group(group, parent); 167 168 return uvcg_config_create_children(group, type); 169 } 170 171 static void uvcg_config_remove_children(struct config_group *group) 172 { 173 struct config_group *child, *n; 174 175 list_for_each_entry_safe(child, n, &group->default_groups, group_entry) { 176 list_del(&child->group_entry); 177 uvcg_config_remove_children(child); 178 config_item_put(&child->cg_item); 179 } 180 } 181 182 /* ----------------------------------------------------------------------------- 183 * control/header/<NAME> 184 * control/header 185 */ 186 187 #define UVCG_CTRL_HDR_ATTR(cname, aname, bits, limit) \ 188 static ssize_t uvcg_control_header_##cname##_show( \ 189 struct config_item *item, char *page) \ 190 { \ 191 struct uvcg_control_header *ch = to_uvcg_control_header(item); \ 192 struct f_uvc_opts *opts; \ 193 struct config_item *opts_item; \ 194 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ 195 int result; \ 196 \ 197 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 198 \ 199 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 200 opts = to_f_uvc_opts(opts_item); \ 201 \ 202 mutex_lock(&opts->lock); \ 203 result = sprintf(page, "%u\n", le##bits##_to_cpu(ch->desc.aname));\ 204 mutex_unlock(&opts->lock); \ 205 \ 206 mutex_unlock(su_mutex); \ 207 return result; \ 208 } \ 209 \ 210 static ssize_t \ 211 uvcg_control_header_##cname##_store(struct config_item *item, \ 212 const char *page, size_t len) \ 213 { \ 214 struct uvcg_control_header *ch = to_uvcg_control_header(item); \ 215 struct f_uvc_opts *opts; \ 216 struct config_item *opts_item; \ 217 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ 218 int ret; \ 219 u##bits num; \ 220 \ 221 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 222 \ 223 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 224 opts = to_f_uvc_opts(opts_item); \ 225 \ 226 mutex_lock(&opts->lock); \ 227 if (ch->linked || opts->refcnt) { \ 228 ret = -EBUSY; \ 229 goto end; \ 230 } \ 231 \ 232 ret = kstrtou##bits(page, 0, &num); \ 233 if (ret) \ 234 goto end; \ 235 \ 236 if (num > limit) { \ 237 ret = -EINVAL; \ 238 goto end; \ 239 } \ 240 ch->desc.aname = cpu_to_le##bits(num); \ 241 ret = len; \ 242 end: \ 243 mutex_unlock(&opts->lock); \ 244 mutex_unlock(su_mutex); \ 245 return ret; \ 246 } \ 247 \ 248 UVC_ATTR(uvcg_control_header_, cname, aname) 249 250 UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, 16, 0xffff); 251 252 UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, 32, 0x7fffffff); 253 254 #undef UVCG_CTRL_HDR_ATTR 255 256 static struct configfs_attribute *uvcg_control_header_attrs[] = { 257 &uvcg_control_header_attr_bcd_uvc, 258 &uvcg_control_header_attr_dw_clock_frequency, 259 NULL, 260 }; 261 262 static const struct config_item_type uvcg_control_header_type = { 263 .ct_item_ops = &uvcg_config_item_ops, 264 .ct_attrs = uvcg_control_header_attrs, 265 .ct_owner = THIS_MODULE, 266 }; 267 268 static struct config_item *uvcg_control_header_make(struct config_group *group, 269 const char *name) 270 { 271 struct uvcg_control_header *h; 272 273 h = kzalloc(sizeof(*h), GFP_KERNEL); 274 if (!h) 275 return ERR_PTR(-ENOMEM); 276 277 h->desc.bLength = UVC_DT_HEADER_SIZE(1); 278 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 279 h->desc.bDescriptorSubType = UVC_VC_HEADER; 280 h->desc.bcdUVC = cpu_to_le16(0x0110); 281 h->desc.dwClockFrequency = cpu_to_le32(48000000); 282 283 config_item_init_type_name(&h->item, name, &uvcg_control_header_type); 284 285 return &h->item; 286 } 287 288 static struct configfs_group_operations uvcg_control_header_grp_ops = { 289 .make_item = uvcg_control_header_make, 290 }; 291 292 static const struct uvcg_config_group_type uvcg_control_header_grp_type = { 293 .type = { 294 .ct_item_ops = &uvcg_config_item_ops, 295 .ct_group_ops = &uvcg_control_header_grp_ops, 296 .ct_owner = THIS_MODULE, 297 }, 298 .name = "header", 299 }; 300 301 /* ----------------------------------------------------------------------------- 302 * control/processing/default 303 */ 304 305 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, bits) \ 306 static ssize_t uvcg_default_processing_##cname##_show( \ 307 struct config_item *item, char *page) \ 308 { \ 309 struct config_group *group = to_config_group(item); \ 310 struct f_uvc_opts *opts; \ 311 struct config_item *opts_item; \ 312 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 313 struct uvc_processing_unit_descriptor *pd; \ 314 int result; \ 315 \ 316 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 317 \ 318 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 319 opts = to_f_uvc_opts(opts_item); \ 320 pd = &opts->uvc_processing; \ 321 \ 322 mutex_lock(&opts->lock); \ 323 result = sprintf(page, "%u\n", le##bits##_to_cpu(pd->aname)); \ 324 mutex_unlock(&opts->lock); \ 325 \ 326 mutex_unlock(su_mutex); \ 327 return result; \ 328 } \ 329 \ 330 UVC_ATTR_RO(uvcg_default_processing_, cname, aname) 331 332 UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, 8); 333 UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, 8); 334 UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, 16); 335 UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, 8); 336 337 #undef UVCG_DEFAULT_PROCESSING_ATTR 338 339 static ssize_t uvcg_default_processing_bm_controls_store( 340 struct config_item *item, const char *page, size_t len) 341 { 342 struct config_group *group = to_config_group(item); 343 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 344 struct uvc_processing_unit_descriptor *pd; 345 struct config_item *opts_item; 346 struct f_uvc_opts *opts; 347 u8 *bm_controls, *tmp; 348 unsigned int i; 349 int ret, n = 0; 350 351 mutex_lock(su_mutex); 352 353 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 354 opts = to_f_uvc_opts(opts_item); 355 pd = &opts->uvc_processing; 356 357 mutex_lock(&opts->lock); 358 if (opts->refcnt) { 359 ret = -EBUSY; 360 goto unlock; 361 } 362 363 ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, 364 sizeof(u8)); 365 if (ret) 366 goto unlock; 367 368 if (n > pd->bControlSize) { 369 ret = -EINVAL; 370 goto unlock; 371 } 372 373 tmp = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL); 374 if (!bm_controls) { 375 ret = -ENOMEM; 376 goto unlock; 377 } 378 379 ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, 380 sizeof(u8)); 381 if (ret) 382 goto free_mem; 383 384 for (i = 0; i < n; i++) 385 pd->bmControls[i] = bm_controls[i]; 386 387 ret = len; 388 389 free_mem: 390 kfree(bm_controls); 391 unlock: 392 mutex_unlock(&opts->lock); 393 mutex_unlock(su_mutex); 394 return ret; 395 } 396 397 static ssize_t uvcg_default_processing_bm_controls_show( 398 struct config_item *item, char *page) 399 { 400 struct config_group *group = to_config_group(item); 401 struct f_uvc_opts *opts; 402 struct config_item *opts_item; 403 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 404 struct uvc_processing_unit_descriptor *pd; 405 int result, i; 406 char *pg = page; 407 408 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 409 410 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 411 opts = to_f_uvc_opts(opts_item); 412 pd = &opts->uvc_processing; 413 414 mutex_lock(&opts->lock); 415 for (result = 0, i = 0; i < pd->bControlSize; ++i) { 416 result += sprintf(pg, "%u\n", pd->bmControls[i]); 417 pg = page + result; 418 } 419 mutex_unlock(&opts->lock); 420 421 mutex_unlock(su_mutex); 422 423 return result; 424 } 425 426 UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls); 427 428 static struct configfs_attribute *uvcg_default_processing_attrs[] = { 429 &uvcg_default_processing_attr_b_unit_id, 430 &uvcg_default_processing_attr_b_source_id, 431 &uvcg_default_processing_attr_w_max_multiplier, 432 &uvcg_default_processing_attr_bm_controls, 433 &uvcg_default_processing_attr_i_processing, 434 NULL, 435 }; 436 437 static const struct uvcg_config_group_type uvcg_default_processing_type = { 438 .type = { 439 .ct_item_ops = &uvcg_config_item_ops, 440 .ct_attrs = uvcg_default_processing_attrs, 441 .ct_owner = THIS_MODULE, 442 }, 443 .name = "default", 444 }; 445 446 /* ----------------------------------------------------------------------------- 447 * control/processing 448 */ 449 450 static const struct uvcg_config_group_type uvcg_processing_grp_type = { 451 .type = { 452 .ct_item_ops = &uvcg_config_item_ops, 453 .ct_owner = THIS_MODULE, 454 }, 455 .name = "processing", 456 .children = (const struct uvcg_config_group_type*[]) { 457 &uvcg_default_processing_type, 458 NULL, 459 }, 460 }; 461 462 /* ----------------------------------------------------------------------------- 463 * control/terminal/camera/default 464 */ 465 466 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, bits) \ 467 static ssize_t uvcg_default_camera_##cname##_show( \ 468 struct config_item *item, char *page) \ 469 { \ 470 struct config_group *group = to_config_group(item); \ 471 struct f_uvc_opts *opts; \ 472 struct config_item *opts_item; \ 473 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 474 struct uvc_camera_terminal_descriptor *cd; \ 475 int result; \ 476 \ 477 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 478 \ 479 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> \ 480 ci_parent; \ 481 opts = to_f_uvc_opts(opts_item); \ 482 cd = &opts->uvc_camera_terminal; \ 483 \ 484 mutex_lock(&opts->lock); \ 485 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 486 mutex_unlock(&opts->lock); \ 487 \ 488 mutex_unlock(su_mutex); \ 489 \ 490 return result; \ 491 } \ 492 \ 493 UVC_ATTR_RO(uvcg_default_camera_, cname, aname) 494 495 UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, 8); 496 UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, 16); 497 UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, 8); 498 UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, 8); 499 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin, 500 16); 501 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax, 502 16); 503 UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength, 504 16); 505 506 #undef UVCG_DEFAULT_CAMERA_ATTR 507 508 static ssize_t uvcg_default_camera_bm_controls_store( 509 struct config_item *item, const char *page, size_t len) 510 { 511 struct config_group *group = to_config_group(item); 512 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 513 struct uvc_camera_terminal_descriptor *cd; 514 struct config_item *opts_item; 515 struct f_uvc_opts *opts; 516 u8 *bm_controls, *tmp; 517 unsigned int i; 518 int ret, n = 0; 519 520 mutex_lock(su_mutex); 521 522 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> 523 ci_parent; 524 opts = to_f_uvc_opts(opts_item); 525 cd = &opts->uvc_camera_terminal; 526 527 mutex_lock(&opts->lock); 528 if (opts->refcnt) { 529 ret = -EBUSY; 530 goto unlock; 531 } 532 533 ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, 534 sizeof(u8)); 535 if (ret) 536 goto unlock; 537 538 if (n > cd->bControlSize) { 539 ret = -EINVAL; 540 goto unlock; 541 } 542 543 tmp = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL); 544 if (!bm_controls) { 545 ret = -ENOMEM; 546 goto unlock; 547 } 548 549 ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, 550 sizeof(u8)); 551 if (ret) 552 goto free_mem; 553 554 for (i = 0; i < n; i++) 555 cd->bmControls[i] = bm_controls[i]; 556 557 ret = len; 558 559 free_mem: 560 kfree(bm_controls); 561 unlock: 562 mutex_unlock(&opts->lock); 563 mutex_unlock(su_mutex); 564 return ret; 565 } 566 567 static ssize_t uvcg_default_camera_bm_controls_show( 568 struct config_item *item, char *page) 569 { 570 struct config_group *group = to_config_group(item); 571 struct f_uvc_opts *opts; 572 struct config_item *opts_item; 573 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 574 struct uvc_camera_terminal_descriptor *cd; 575 int result, i; 576 char *pg = page; 577 578 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 579 580 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> 581 ci_parent; 582 opts = to_f_uvc_opts(opts_item); 583 cd = &opts->uvc_camera_terminal; 584 585 mutex_lock(&opts->lock); 586 for (result = 0, i = 0; i < cd->bControlSize; ++i) { 587 result += sprintf(pg, "%u\n", cd->bmControls[i]); 588 pg = page + result; 589 } 590 mutex_unlock(&opts->lock); 591 592 mutex_unlock(su_mutex); 593 return result; 594 } 595 596 UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls); 597 598 static struct configfs_attribute *uvcg_default_camera_attrs[] = { 599 &uvcg_default_camera_attr_b_terminal_id, 600 &uvcg_default_camera_attr_w_terminal_type, 601 &uvcg_default_camera_attr_b_assoc_terminal, 602 &uvcg_default_camera_attr_i_terminal, 603 &uvcg_default_camera_attr_w_objective_focal_length_min, 604 &uvcg_default_camera_attr_w_objective_focal_length_max, 605 &uvcg_default_camera_attr_w_ocular_focal_length, 606 &uvcg_default_camera_attr_bm_controls, 607 NULL, 608 }; 609 610 static const struct uvcg_config_group_type uvcg_default_camera_type = { 611 .type = { 612 .ct_item_ops = &uvcg_config_item_ops, 613 .ct_attrs = uvcg_default_camera_attrs, 614 .ct_owner = THIS_MODULE, 615 }, 616 .name = "default", 617 }; 618 619 /* ----------------------------------------------------------------------------- 620 * control/terminal/camera 621 */ 622 623 static const struct uvcg_config_group_type uvcg_camera_grp_type = { 624 .type = { 625 .ct_item_ops = &uvcg_config_item_ops, 626 .ct_owner = THIS_MODULE, 627 }, 628 .name = "camera", 629 .children = (const struct uvcg_config_group_type*[]) { 630 &uvcg_default_camera_type, 631 NULL, 632 }, 633 }; 634 635 /* ----------------------------------------------------------------------------- 636 * control/terminal/output/default 637 */ 638 639 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, bits) \ 640 static ssize_t uvcg_default_output_##cname##_show( \ 641 struct config_item *item, char *page) \ 642 { \ 643 struct config_group *group = to_config_group(item); \ 644 struct f_uvc_opts *opts; \ 645 struct config_item *opts_item; \ 646 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 647 struct uvc_output_terminal_descriptor *cd; \ 648 int result; \ 649 \ 650 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 651 \ 652 opts_item = group->cg_item.ci_parent->ci_parent-> \ 653 ci_parent->ci_parent; \ 654 opts = to_f_uvc_opts(opts_item); \ 655 cd = &opts->uvc_output_terminal; \ 656 \ 657 mutex_lock(&opts->lock); \ 658 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 659 mutex_unlock(&opts->lock); \ 660 \ 661 mutex_unlock(su_mutex); \ 662 \ 663 return result; \ 664 } \ 665 \ 666 UVC_ATTR_RO(uvcg_default_output_, cname, aname) 667 668 UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8); 669 UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16); 670 UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8); 671 UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8); 672 673 #undef UVCG_DEFAULT_OUTPUT_ATTR 674 675 static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item, 676 char *page) 677 { 678 struct config_group *group = to_config_group(item); 679 struct f_uvc_opts *opts; 680 struct config_item *opts_item; 681 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 682 struct uvc_output_terminal_descriptor *cd; 683 int result; 684 685 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 686 687 opts_item = group->cg_item.ci_parent->ci_parent-> 688 ci_parent->ci_parent; 689 opts = to_f_uvc_opts(opts_item); 690 cd = &opts->uvc_output_terminal; 691 692 mutex_lock(&opts->lock); 693 result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID)); 694 mutex_unlock(&opts->lock); 695 696 mutex_unlock(su_mutex); 697 698 return result; 699 } 700 701 static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, 702 const char *page, size_t len) 703 { 704 struct config_group *group = to_config_group(item); 705 struct f_uvc_opts *opts; 706 struct config_item *opts_item; 707 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 708 struct uvc_output_terminal_descriptor *cd; 709 int result; 710 u8 num; 711 712 result = kstrtou8(page, 0, &num); 713 if (result) 714 return result; 715 716 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 717 718 opts_item = group->cg_item.ci_parent->ci_parent-> 719 ci_parent->ci_parent; 720 opts = to_f_uvc_opts(opts_item); 721 cd = &opts->uvc_output_terminal; 722 723 mutex_lock(&opts->lock); 724 cd->bSourceID = num; 725 mutex_unlock(&opts->lock); 726 727 mutex_unlock(su_mutex); 728 729 return len; 730 } 731 UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID); 732 733 static struct configfs_attribute *uvcg_default_output_attrs[] = { 734 &uvcg_default_output_attr_b_terminal_id, 735 &uvcg_default_output_attr_w_terminal_type, 736 &uvcg_default_output_attr_b_assoc_terminal, 737 &uvcg_default_output_attr_b_source_id, 738 &uvcg_default_output_attr_i_terminal, 739 NULL, 740 }; 741 742 static const struct uvcg_config_group_type uvcg_default_output_type = { 743 .type = { 744 .ct_item_ops = &uvcg_config_item_ops, 745 .ct_attrs = uvcg_default_output_attrs, 746 .ct_owner = THIS_MODULE, 747 }, 748 .name = "default", 749 }; 750 751 /* ----------------------------------------------------------------------------- 752 * control/terminal/output 753 */ 754 755 static const struct uvcg_config_group_type uvcg_output_grp_type = { 756 .type = { 757 .ct_item_ops = &uvcg_config_item_ops, 758 .ct_owner = THIS_MODULE, 759 }, 760 .name = "output", 761 .children = (const struct uvcg_config_group_type*[]) { 762 &uvcg_default_output_type, 763 NULL, 764 }, 765 }; 766 767 /* ----------------------------------------------------------------------------- 768 * control/terminal 769 */ 770 771 static const struct uvcg_config_group_type uvcg_terminal_grp_type = { 772 .type = { 773 .ct_item_ops = &uvcg_config_item_ops, 774 .ct_owner = THIS_MODULE, 775 }, 776 .name = "terminal", 777 .children = (const struct uvcg_config_group_type*[]) { 778 &uvcg_camera_grp_type, 779 &uvcg_output_grp_type, 780 NULL, 781 }, 782 }; 783 784 /* ----------------------------------------------------------------------------- 785 * control/extensions 786 */ 787 788 #define UVCG_EXTENSION_ATTR(cname, aname, ro...) \ 789 static ssize_t uvcg_extension_##cname##_show(struct config_item *item, \ 790 char *page) \ 791 { \ 792 struct config_group *group = to_config_group(item->ci_parent); \ 793 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 794 struct uvcg_extension *xu = to_uvcg_extension(item); \ 795 struct config_item *opts_item; \ 796 struct f_uvc_opts *opts; \ 797 int ret; \ 798 \ 799 mutex_lock(su_mutex); \ 800 \ 801 opts_item = item->ci_parent->ci_parent->ci_parent; \ 802 opts = to_f_uvc_opts(opts_item); \ 803 \ 804 mutex_lock(&opts->lock); \ 805 ret = sprintf(page, "%u\n", xu->desc.aname); \ 806 mutex_unlock(&opts->lock); \ 807 \ 808 mutex_unlock(su_mutex); \ 809 \ 810 return ret; \ 811 } \ 812 UVC_ATTR##ro(uvcg_extension_, cname, aname) 813 814 UVCG_EXTENSION_ATTR(b_length, bLength, _RO); 815 UVCG_EXTENSION_ATTR(b_unit_id, bUnitID, _RO); 816 UVCG_EXTENSION_ATTR(i_extension, iExtension, _RO); 817 818 static ssize_t uvcg_extension_b_num_controls_store(struct config_item *item, 819 const char *page, size_t len) 820 { 821 struct config_group *group = to_config_group(item->ci_parent); 822 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 823 struct uvcg_extension *xu = to_uvcg_extension(item); 824 struct config_item *opts_item; 825 struct f_uvc_opts *opts; 826 int ret; 827 u8 num; 828 829 ret = kstrtou8(page, 0, &num); 830 if (ret) 831 return ret; 832 833 mutex_lock(su_mutex); 834 835 opts_item = item->ci_parent->ci_parent->ci_parent; 836 opts = to_f_uvc_opts(opts_item); 837 838 mutex_lock(&opts->lock); 839 xu->desc.bNumControls = num; 840 mutex_unlock(&opts->lock); 841 842 mutex_unlock(su_mutex); 843 844 return len; 845 } 846 UVCG_EXTENSION_ATTR(b_num_controls, bNumControls); 847 848 /* 849 * In addition to storing bNrInPins, this function needs to realloc the 850 * memory for the baSourceID array and additionally expand bLength. 851 */ 852 static ssize_t uvcg_extension_b_nr_in_pins_store(struct config_item *item, 853 const char *page, size_t len) 854 { 855 struct config_group *group = to_config_group(item->ci_parent); 856 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 857 struct uvcg_extension *xu = to_uvcg_extension(item); 858 struct config_item *opts_item; 859 struct f_uvc_opts *opts; 860 void *tmp_buf; 861 int ret; 862 u8 num; 863 864 ret = kstrtou8(page, 0, &num); 865 if (ret) 866 return ret; 867 868 mutex_lock(su_mutex); 869 870 opts_item = item->ci_parent->ci_parent->ci_parent; 871 opts = to_f_uvc_opts(opts_item); 872 873 mutex_lock(&opts->lock); 874 875 if (num == xu->desc.bNrInPins) { 876 ret = len; 877 goto unlock; 878 } 879 880 tmp_buf = krealloc_array(xu->desc.baSourceID, num, sizeof(u8), 881 GFP_KERNEL | __GFP_ZERO); 882 if (!tmp_buf) { 883 ret = -ENOMEM; 884 goto unlock; 885 } 886 887 xu->desc.baSourceID = tmp_buf; 888 xu->desc.bNrInPins = num; 889 xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins, 890 xu->desc.bControlSize); 891 892 ret = len; 893 894 unlock: 895 mutex_unlock(&opts->lock); 896 mutex_unlock(su_mutex); 897 return ret; 898 } 899 UVCG_EXTENSION_ATTR(b_nr_in_pins, bNrInPins); 900 901 /* 902 * In addition to storing bControlSize, this function needs to realloc the 903 * memory for the bmControls array and additionally expand bLength. 904 */ 905 static ssize_t uvcg_extension_b_control_size_store(struct config_item *item, 906 const char *page, size_t len) 907 { 908 struct config_group *group = to_config_group(item->ci_parent); 909 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 910 struct uvcg_extension *xu = to_uvcg_extension(item); 911 struct config_item *opts_item; 912 struct f_uvc_opts *opts; 913 void *tmp_buf; 914 int ret; 915 u8 num; 916 917 ret = kstrtou8(page, 0, &num); 918 if (ret) 919 return ret; 920 921 mutex_lock(su_mutex); 922 923 opts_item = item->ci_parent->ci_parent->ci_parent; 924 opts = to_f_uvc_opts(opts_item); 925 926 mutex_lock(&opts->lock); 927 928 if (num == xu->desc.bControlSize) { 929 ret = len; 930 goto unlock; 931 } 932 933 tmp_buf = krealloc_array(xu->desc.bmControls, num, sizeof(u8), 934 GFP_KERNEL | __GFP_ZERO); 935 if (!tmp_buf) { 936 ret = -ENOMEM; 937 goto unlock; 938 } 939 940 xu->desc.bmControls = tmp_buf; 941 xu->desc.bControlSize = num; 942 xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins, 943 xu->desc.bControlSize); 944 945 ret = len; 946 947 unlock: 948 mutex_unlock(&opts->lock); 949 mutex_unlock(su_mutex); 950 return ret; 951 } 952 953 UVCG_EXTENSION_ATTR(b_control_size, bControlSize); 954 955 static ssize_t uvcg_extension_guid_extension_code_show(struct config_item *item, 956 char *page) 957 { 958 struct config_group *group = to_config_group(item->ci_parent); 959 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 960 struct uvcg_extension *xu = to_uvcg_extension(item); 961 struct config_item *opts_item; 962 struct f_uvc_opts *opts; 963 964 mutex_lock(su_mutex); 965 966 opts_item = item->ci_parent->ci_parent->ci_parent; 967 opts = to_f_uvc_opts(opts_item); 968 969 mutex_lock(&opts->lock); 970 memcpy(page, xu->desc.guidExtensionCode, sizeof(xu->desc.guidExtensionCode)); 971 mutex_unlock(&opts->lock); 972 973 mutex_unlock(su_mutex); 974 975 return sizeof(xu->desc.guidExtensionCode); 976 } 977 978 static ssize_t uvcg_extension_guid_extension_code_store(struct config_item *item, 979 const char *page, size_t len) 980 { 981 struct config_group *group = to_config_group(item->ci_parent); 982 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 983 struct uvcg_extension *xu = to_uvcg_extension(item); 984 struct config_item *opts_item; 985 struct f_uvc_opts *opts; 986 int ret; 987 988 mutex_lock(su_mutex); 989 990 opts_item = item->ci_parent->ci_parent->ci_parent; 991 opts = to_f_uvc_opts(opts_item); 992 993 mutex_lock(&opts->lock); 994 memcpy(xu->desc.guidExtensionCode, page, 995 min(sizeof(xu->desc.guidExtensionCode), len)); 996 mutex_unlock(&opts->lock); 997 998 mutex_unlock(su_mutex); 999 1000 ret = sizeof(xu->desc.guidExtensionCode); 1001 1002 return ret; 1003 } 1004 1005 UVC_ATTR(uvcg_extension_, guid_extension_code, guidExtensionCode); 1006 1007 static ssize_t uvcg_extension_ba_source_id_show(struct config_item *item, 1008 char *page) 1009 { 1010 struct config_group *group = to_config_group(item->ci_parent); 1011 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1012 struct uvcg_extension *xu = to_uvcg_extension(item); 1013 struct config_item *opts_item; 1014 struct f_uvc_opts *opts; 1015 char *pg = page; 1016 int ret, i; 1017 1018 mutex_lock(su_mutex); 1019 1020 opts_item = item->ci_parent->ci_parent->ci_parent; 1021 opts = to_f_uvc_opts(opts_item); 1022 1023 mutex_lock(&opts->lock); 1024 for (ret = 0, i = 0; i < xu->desc.bNrInPins; ++i) { 1025 ret += sprintf(pg, "%u\n", xu->desc.baSourceID[i]); 1026 pg = page + ret; 1027 } 1028 mutex_unlock(&opts->lock); 1029 1030 mutex_unlock(su_mutex); 1031 1032 return ret; 1033 } 1034 1035 static ssize_t uvcg_extension_ba_source_id_store(struct config_item *item, 1036 const char *page, size_t len) 1037 { 1038 struct config_group *group = to_config_group(item->ci_parent); 1039 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1040 struct uvcg_extension *xu = to_uvcg_extension(item); 1041 struct config_item *opts_item; 1042 struct f_uvc_opts *opts; 1043 u8 *source_ids, *iter; 1044 int ret, n = 0; 1045 1046 mutex_lock(su_mutex); 1047 1048 opts_item = item->ci_parent->ci_parent->ci_parent; 1049 opts = to_f_uvc_opts(opts_item); 1050 1051 mutex_lock(&opts->lock); 1052 1053 ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, 1054 sizeof(u8)); 1055 if (ret) 1056 goto unlock; 1057 1058 iter = source_ids = kcalloc(n, sizeof(u8), GFP_KERNEL); 1059 if (!source_ids) { 1060 ret = -ENOMEM; 1061 goto unlock; 1062 } 1063 1064 ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &iter, 1065 sizeof(u8)); 1066 if (ret) { 1067 kfree(source_ids); 1068 goto unlock; 1069 } 1070 1071 kfree(xu->desc.baSourceID); 1072 xu->desc.baSourceID = source_ids; 1073 xu->desc.bNrInPins = n; 1074 xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins, 1075 xu->desc.bControlSize); 1076 1077 ret = len; 1078 1079 unlock: 1080 mutex_unlock(&opts->lock); 1081 mutex_unlock(su_mutex); 1082 return ret; 1083 } 1084 UVC_ATTR(uvcg_extension_, ba_source_id, baSourceID); 1085 1086 static ssize_t uvcg_extension_bm_controls_show(struct config_item *item, 1087 char *page) 1088 { 1089 struct config_group *group = to_config_group(item->ci_parent); 1090 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1091 struct uvcg_extension *xu = to_uvcg_extension(item); 1092 struct config_item *opts_item; 1093 struct f_uvc_opts *opts; 1094 char *pg = page; 1095 int ret, i; 1096 1097 mutex_lock(su_mutex); 1098 1099 opts_item = item->ci_parent->ci_parent->ci_parent; 1100 opts = to_f_uvc_opts(opts_item); 1101 1102 mutex_lock(&opts->lock); 1103 for (ret = 0, i = 0; i < xu->desc.bControlSize; ++i) { 1104 ret += sprintf(pg, "0x%02x\n", xu->desc.bmControls[i]); 1105 pg = page + ret; 1106 } 1107 mutex_unlock(&opts->lock); 1108 1109 mutex_unlock(su_mutex); 1110 1111 return ret; 1112 } 1113 1114 static ssize_t uvcg_extension_bm_controls_store(struct config_item *item, 1115 const char *page, size_t len) 1116 { 1117 struct config_group *group = to_config_group(item->ci_parent); 1118 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1119 struct uvcg_extension *xu = to_uvcg_extension(item); 1120 struct config_item *opts_item; 1121 struct f_uvc_opts *opts; 1122 u8 *bm_controls, *iter; 1123 int ret, n = 0; 1124 1125 mutex_lock(su_mutex); 1126 1127 opts_item = item->ci_parent->ci_parent->ci_parent; 1128 opts = to_f_uvc_opts(opts_item); 1129 1130 mutex_lock(&opts->lock); 1131 1132 ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, 1133 sizeof(u8)); 1134 if (ret) 1135 goto unlock; 1136 1137 iter = bm_controls = kcalloc(n, sizeof(u8), GFP_KERNEL); 1138 if (!bm_controls) { 1139 ret = -ENOMEM; 1140 goto unlock; 1141 } 1142 1143 ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &iter, 1144 sizeof(u8)); 1145 if (ret) { 1146 kfree(bm_controls); 1147 goto unlock; 1148 } 1149 1150 kfree(xu->desc.bmControls); 1151 xu->desc.bmControls = bm_controls; 1152 xu->desc.bControlSize = n; 1153 xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(xu->desc.bNrInPins, 1154 xu->desc.bControlSize); 1155 1156 ret = len; 1157 1158 unlock: 1159 mutex_unlock(&opts->lock); 1160 mutex_unlock(su_mutex); 1161 return ret; 1162 } 1163 1164 UVC_ATTR(uvcg_extension_, bm_controls, bmControls); 1165 1166 static struct configfs_attribute *uvcg_extension_attrs[] = { 1167 &uvcg_extension_attr_b_length, 1168 &uvcg_extension_attr_b_unit_id, 1169 &uvcg_extension_attr_b_num_controls, 1170 &uvcg_extension_attr_b_nr_in_pins, 1171 &uvcg_extension_attr_b_control_size, 1172 &uvcg_extension_attr_guid_extension_code, 1173 &uvcg_extension_attr_ba_source_id, 1174 &uvcg_extension_attr_bm_controls, 1175 &uvcg_extension_attr_i_extension, 1176 NULL, 1177 }; 1178 1179 static void uvcg_extension_release(struct config_item *item) 1180 { 1181 struct uvcg_extension *xu = container_of(item, struct uvcg_extension, item); 1182 1183 kfree(xu); 1184 } 1185 1186 static int uvcg_extension_allow_link(struct config_item *src, struct config_item *tgt) 1187 { 1188 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1189 struct uvcg_extension *xu = to_uvcg_extension(src); 1190 struct config_item *gadget_item; 1191 struct gadget_string *string; 1192 struct config_item *strings; 1193 int ret = 0; 1194 1195 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1196 1197 /* Validate that the target of the link is an entry in strings/<langid> */ 1198 gadget_item = src->ci_parent->ci_parent->ci_parent->ci_parent->ci_parent; 1199 strings = config_group_find_item(to_config_group(gadget_item), "strings"); 1200 if (!strings || tgt->ci_parent->ci_parent != strings) { 1201 ret = -EINVAL; 1202 goto put_strings; 1203 } 1204 1205 string = to_gadget_string(tgt); 1206 xu->string_descriptor_index = string->usb_string.id; 1207 1208 put_strings: 1209 config_item_put(strings); 1210 mutex_unlock(su_mutex); 1211 1212 return ret; 1213 } 1214 1215 static void uvcg_extension_drop_link(struct config_item *src, struct config_item *tgt) 1216 { 1217 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1218 struct uvcg_extension *xu = to_uvcg_extension(src); 1219 struct config_item *opts_item; 1220 struct f_uvc_opts *opts; 1221 1222 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1223 1224 opts_item = src->ci_parent->ci_parent->ci_parent; 1225 opts = to_f_uvc_opts(opts_item); 1226 1227 mutex_lock(&opts->lock); 1228 1229 xu->string_descriptor_index = 0; 1230 1231 mutex_unlock(&opts->lock); 1232 1233 mutex_unlock(su_mutex); 1234 } 1235 1236 static struct configfs_item_operations uvcg_extension_item_ops = { 1237 .release = uvcg_extension_release, 1238 .allow_link = uvcg_extension_allow_link, 1239 .drop_link = uvcg_extension_drop_link, 1240 }; 1241 1242 static const struct config_item_type uvcg_extension_type = { 1243 .ct_item_ops = &uvcg_extension_item_ops, 1244 .ct_attrs = uvcg_extension_attrs, 1245 .ct_owner = THIS_MODULE, 1246 }; 1247 1248 static void uvcg_extension_drop(struct config_group *group, struct config_item *item) 1249 { 1250 struct uvcg_extension *xu = container_of(item, struct uvcg_extension, item); 1251 struct config_item *opts_item; 1252 struct f_uvc_opts *opts; 1253 1254 opts_item = group->cg_item.ci_parent->ci_parent; 1255 opts = to_f_uvc_opts(opts_item); 1256 1257 mutex_lock(&opts->lock); 1258 1259 config_item_put(item); 1260 list_del(&xu->list); 1261 kfree(xu->desc.baSourceID); 1262 kfree(xu->desc.bmControls); 1263 1264 mutex_unlock(&opts->lock); 1265 } 1266 1267 static struct config_item *uvcg_extension_make(struct config_group *group, const char *name) 1268 { 1269 struct config_item *opts_item; 1270 struct uvcg_extension *xu; 1271 struct f_uvc_opts *opts; 1272 1273 opts_item = group->cg_item.ci_parent->ci_parent; 1274 opts = to_f_uvc_opts(opts_item); 1275 1276 xu = kzalloc(sizeof(*xu), GFP_KERNEL); 1277 if (!xu) 1278 return ERR_PTR(-ENOMEM); 1279 1280 xu->desc.bLength = UVC_DT_EXTENSION_UNIT_SIZE(0, 0); 1281 xu->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1282 xu->desc.bDescriptorSubType = UVC_VC_EXTENSION_UNIT; 1283 xu->desc.bNumControls = 0; 1284 xu->desc.bNrInPins = 0; 1285 xu->desc.baSourceID = NULL; 1286 xu->desc.bControlSize = 0; 1287 xu->desc.bmControls = NULL; 1288 1289 mutex_lock(&opts->lock); 1290 1291 xu->desc.bUnitID = ++opts->last_unit_id; 1292 1293 config_item_init_type_name(&xu->item, name, &uvcg_extension_type); 1294 list_add_tail(&xu->list, &opts->extension_units); 1295 1296 mutex_unlock(&opts->lock); 1297 1298 return &xu->item; 1299 } 1300 1301 static struct configfs_group_operations uvcg_extensions_grp_ops = { 1302 .make_item = uvcg_extension_make, 1303 .drop_item = uvcg_extension_drop, 1304 }; 1305 1306 static const struct uvcg_config_group_type uvcg_extensions_grp_type = { 1307 .type = { 1308 .ct_item_ops = &uvcg_config_item_ops, 1309 .ct_group_ops = &uvcg_extensions_grp_ops, 1310 .ct_owner = THIS_MODULE, 1311 }, 1312 .name = "extensions", 1313 }; 1314 1315 /* ----------------------------------------------------------------------------- 1316 * control/class/{fs|ss} 1317 */ 1318 1319 struct uvcg_control_class_group { 1320 struct config_group group; 1321 const char *name; 1322 }; 1323 1324 static inline struct uvc_descriptor_header 1325 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o) 1326 { 1327 struct uvcg_control_class_group *group = 1328 container_of(i, struct uvcg_control_class_group, 1329 group.cg_item); 1330 1331 if (!strcmp(group->name, "fs")) 1332 return o->uvc_fs_control_cls; 1333 1334 if (!strcmp(group->name, "ss")) 1335 return o->uvc_ss_control_cls; 1336 1337 return NULL; 1338 } 1339 1340 static int uvcg_control_class_allow_link(struct config_item *src, 1341 struct config_item *target) 1342 { 1343 struct config_item *control, *header; 1344 struct f_uvc_opts *opts; 1345 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1346 struct uvc_descriptor_header **class_array; 1347 struct uvcg_control_header *target_hdr; 1348 int ret = -EINVAL; 1349 1350 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1351 1352 control = src->ci_parent->ci_parent; 1353 header = config_group_find_item(to_config_group(control), "header"); 1354 if (!header || target->ci_parent != header) 1355 goto out; 1356 1357 opts = to_f_uvc_opts(control->ci_parent); 1358 1359 mutex_lock(&opts->lock); 1360 1361 class_array = uvcg_get_ctl_class_arr(src, opts); 1362 if (!class_array) 1363 goto unlock; 1364 if (opts->refcnt || class_array[0]) { 1365 ret = -EBUSY; 1366 goto unlock; 1367 } 1368 1369 target_hdr = to_uvcg_control_header(target); 1370 ++target_hdr->linked; 1371 class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc; 1372 ret = 0; 1373 1374 unlock: 1375 mutex_unlock(&opts->lock); 1376 out: 1377 config_item_put(header); 1378 mutex_unlock(su_mutex); 1379 return ret; 1380 } 1381 1382 static void uvcg_control_class_drop_link(struct config_item *src, 1383 struct config_item *target) 1384 { 1385 struct config_item *control, *header; 1386 struct f_uvc_opts *opts; 1387 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1388 struct uvc_descriptor_header **class_array; 1389 struct uvcg_control_header *target_hdr; 1390 1391 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1392 1393 control = src->ci_parent->ci_parent; 1394 header = config_group_find_item(to_config_group(control), "header"); 1395 if (!header || target->ci_parent != header) 1396 goto out; 1397 1398 opts = to_f_uvc_opts(control->ci_parent); 1399 1400 mutex_lock(&opts->lock); 1401 1402 class_array = uvcg_get_ctl_class_arr(src, opts); 1403 if (!class_array || opts->refcnt) 1404 goto unlock; 1405 1406 target_hdr = to_uvcg_control_header(target); 1407 --target_hdr->linked; 1408 class_array[0] = NULL; 1409 1410 unlock: 1411 mutex_unlock(&opts->lock); 1412 out: 1413 config_item_put(header); 1414 mutex_unlock(su_mutex); 1415 } 1416 1417 static struct configfs_item_operations uvcg_control_class_item_ops = { 1418 .release = uvcg_config_item_release, 1419 .allow_link = uvcg_control_class_allow_link, 1420 .drop_link = uvcg_control_class_drop_link, 1421 }; 1422 1423 static const struct config_item_type uvcg_control_class_type = { 1424 .ct_item_ops = &uvcg_control_class_item_ops, 1425 .ct_owner = THIS_MODULE, 1426 }; 1427 1428 /* ----------------------------------------------------------------------------- 1429 * control/class 1430 */ 1431 1432 static int uvcg_control_class_create_children(struct config_group *parent) 1433 { 1434 static const char * const names[] = { "fs", "ss" }; 1435 unsigned int i; 1436 1437 for (i = 0; i < ARRAY_SIZE(names); ++i) { 1438 struct uvcg_control_class_group *group; 1439 1440 group = kzalloc(sizeof(*group), GFP_KERNEL); 1441 if (!group) 1442 return -ENOMEM; 1443 1444 group->name = names[i]; 1445 1446 config_group_init_type_name(&group->group, group->name, 1447 &uvcg_control_class_type); 1448 configfs_add_default_group(&group->group, parent); 1449 } 1450 1451 return 0; 1452 } 1453 1454 static const struct uvcg_config_group_type uvcg_control_class_grp_type = { 1455 .type = { 1456 .ct_item_ops = &uvcg_config_item_ops, 1457 .ct_owner = THIS_MODULE, 1458 }, 1459 .name = "class", 1460 .create_children = uvcg_control_class_create_children, 1461 }; 1462 1463 /* ----------------------------------------------------------------------------- 1464 * control 1465 */ 1466 1467 static ssize_t uvcg_default_control_b_interface_number_show( 1468 struct config_item *item, char *page) 1469 { 1470 struct config_group *group = to_config_group(item); 1471 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1472 struct config_item *opts_item; 1473 struct f_uvc_opts *opts; 1474 int result = 0; 1475 1476 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1477 1478 opts_item = item->ci_parent; 1479 opts = to_f_uvc_opts(opts_item); 1480 1481 mutex_lock(&opts->lock); 1482 result += sprintf(page, "%u\n", opts->control_interface); 1483 mutex_unlock(&opts->lock); 1484 1485 mutex_unlock(su_mutex); 1486 1487 return result; 1488 } 1489 1490 UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber); 1491 1492 static ssize_t uvcg_default_control_enable_interrupt_ep_show( 1493 struct config_item *item, char *page) 1494 { 1495 struct config_group *group = to_config_group(item); 1496 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1497 struct config_item *opts_item; 1498 struct f_uvc_opts *opts; 1499 int result = 0; 1500 1501 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1502 1503 opts_item = item->ci_parent; 1504 opts = to_f_uvc_opts(opts_item); 1505 1506 mutex_lock(&opts->lock); 1507 result += sprintf(page, "%u\n", opts->enable_interrupt_ep); 1508 mutex_unlock(&opts->lock); 1509 1510 mutex_unlock(su_mutex); 1511 1512 return result; 1513 } 1514 1515 static ssize_t uvcg_default_control_enable_interrupt_ep_store( 1516 struct config_item *item, const char *page, size_t len) 1517 { 1518 struct config_group *group = to_config_group(item); 1519 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 1520 struct config_item *opts_item; 1521 struct f_uvc_opts *opts; 1522 ssize_t ret; 1523 u8 num; 1524 1525 ret = kstrtou8(page, 0, &num); 1526 if (ret) 1527 return ret; 1528 1529 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1530 1531 opts_item = item->ci_parent; 1532 opts = to_f_uvc_opts(opts_item); 1533 1534 mutex_lock(&opts->lock); 1535 opts->enable_interrupt_ep = num; 1536 mutex_unlock(&opts->lock); 1537 1538 mutex_unlock(su_mutex); 1539 1540 return len; 1541 } 1542 UVC_ATTR(uvcg_default_control_, enable_interrupt_ep, enable_interrupt_ep); 1543 1544 static struct configfs_attribute *uvcg_default_control_attrs[] = { 1545 &uvcg_default_control_attr_b_interface_number, 1546 &uvcg_default_control_attr_enable_interrupt_ep, 1547 NULL, 1548 }; 1549 1550 static const struct uvcg_config_group_type uvcg_control_grp_type = { 1551 .type = { 1552 .ct_item_ops = &uvcg_config_item_ops, 1553 .ct_attrs = uvcg_default_control_attrs, 1554 .ct_owner = THIS_MODULE, 1555 }, 1556 .name = "control", 1557 .children = (const struct uvcg_config_group_type*[]) { 1558 &uvcg_control_header_grp_type, 1559 &uvcg_processing_grp_type, 1560 &uvcg_terminal_grp_type, 1561 &uvcg_control_class_grp_type, 1562 &uvcg_extensions_grp_type, 1563 NULL, 1564 }, 1565 }; 1566 1567 /* ----------------------------------------------------------------------------- 1568 * streaming/uncompressed 1569 * streaming/mjpeg 1570 * streaming/framebased 1571 */ 1572 1573 static const char * const uvcg_format_names[] = { 1574 "uncompressed", 1575 "mjpeg", 1576 "framebased", 1577 }; 1578 1579 static struct uvcg_color_matching * 1580 uvcg_format_get_default_color_match(struct config_item *streaming) 1581 { 1582 struct config_item *color_matching_item, *cm_default; 1583 struct uvcg_color_matching *color_match; 1584 1585 color_matching_item = config_group_find_item(to_config_group(streaming), 1586 "color_matching"); 1587 if (!color_matching_item) 1588 return NULL; 1589 1590 cm_default = config_group_find_item(to_config_group(color_matching_item), 1591 "default"); 1592 config_item_put(color_matching_item); 1593 if (!cm_default) 1594 return NULL; 1595 1596 color_match = to_uvcg_color_matching(to_config_group(cm_default)); 1597 config_item_put(cm_default); 1598 1599 return color_match; 1600 } 1601 1602 static int uvcg_format_allow_link(struct config_item *src, struct config_item *tgt) 1603 { 1604 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1605 struct uvcg_color_matching *color_matching_desc; 1606 struct config_item *streaming, *color_matching; 1607 struct uvcg_format *fmt; 1608 int ret = 0; 1609 1610 mutex_lock(su_mutex); 1611 1612 streaming = src->ci_parent->ci_parent; 1613 color_matching = config_group_find_item(to_config_group(streaming), "color_matching"); 1614 if (!color_matching || color_matching != tgt->ci_parent) { 1615 ret = -EINVAL; 1616 goto out_put_cm; 1617 } 1618 1619 fmt = to_uvcg_format(src); 1620 1621 /* 1622 * There's always a color matching descriptor associated with the format 1623 * but without a symlink it should only ever be the default one. If it's 1624 * not the default, there's already a symlink and we should bail out. 1625 */ 1626 color_matching_desc = uvcg_format_get_default_color_match(streaming); 1627 if (fmt->color_matching != color_matching_desc) { 1628 ret = -EBUSY; 1629 goto out_put_cm; 1630 } 1631 1632 color_matching_desc->refcnt--; 1633 1634 color_matching_desc = to_uvcg_color_matching(to_config_group(tgt)); 1635 fmt->color_matching = color_matching_desc; 1636 color_matching_desc->refcnt++; 1637 1638 out_put_cm: 1639 config_item_put(color_matching); 1640 mutex_unlock(su_mutex); 1641 1642 return ret; 1643 } 1644 1645 static void uvcg_format_drop_link(struct config_item *src, struct config_item *tgt) 1646 { 1647 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1648 struct uvcg_color_matching *color_matching_desc; 1649 struct config_item *streaming; 1650 struct uvcg_format *fmt; 1651 1652 mutex_lock(su_mutex); 1653 1654 color_matching_desc = to_uvcg_color_matching(to_config_group(tgt)); 1655 color_matching_desc->refcnt--; 1656 1657 streaming = src->ci_parent->ci_parent; 1658 color_matching_desc = uvcg_format_get_default_color_match(streaming); 1659 1660 fmt = to_uvcg_format(src); 1661 fmt->color_matching = color_matching_desc; 1662 color_matching_desc->refcnt++; 1663 1664 mutex_unlock(su_mutex); 1665 } 1666 1667 static struct configfs_item_operations uvcg_format_item_operations = { 1668 .release = uvcg_config_item_release, 1669 .allow_link = uvcg_format_allow_link, 1670 .drop_link = uvcg_format_drop_link, 1671 }; 1672 1673 static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page) 1674 { 1675 struct f_uvc_opts *opts; 1676 struct config_item *opts_item; 1677 struct mutex *su_mutex = &f->group.cg_subsys->su_mutex; 1678 int result, i; 1679 char *pg = page; 1680 1681 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1682 1683 opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent; 1684 opts = to_f_uvc_opts(opts_item); 1685 1686 mutex_lock(&opts->lock); 1687 result = sprintf(pg, "0x"); 1688 pg += result; 1689 for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) { 1690 result += sprintf(pg, "%x\n", f->bmaControls[i]); 1691 pg = page + result; 1692 } 1693 mutex_unlock(&opts->lock); 1694 1695 mutex_unlock(su_mutex); 1696 return result; 1697 } 1698 1699 static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch, 1700 const char *page, size_t len) 1701 { 1702 struct f_uvc_opts *opts; 1703 struct config_item *opts_item; 1704 struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex; 1705 int ret = -EINVAL; 1706 1707 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1708 1709 opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent; 1710 opts = to_f_uvc_opts(opts_item); 1711 1712 mutex_lock(&opts->lock); 1713 if (ch->linked || opts->refcnt) { 1714 ret = -EBUSY; 1715 goto end; 1716 } 1717 1718 if (len < 4 || *page != '0' || 1719 (*(page + 1) != 'x' && *(page + 1) != 'X')) 1720 goto end; 1721 ret = hex2bin(ch->bmaControls, page + 2, 1); 1722 if (ret < 0) 1723 goto end; 1724 ret = len; 1725 end: 1726 mutex_unlock(&opts->lock); 1727 mutex_unlock(su_mutex); 1728 return ret; 1729 } 1730 1731 /* ----------------------------------------------------------------------------- 1732 * streaming/header/<NAME> 1733 * streaming/header 1734 */ 1735 1736 static void uvcg_format_set_indices(struct config_group *fmt); 1737 1738 static int uvcg_streaming_header_allow_link(struct config_item *src, 1739 struct config_item *target) 1740 { 1741 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1742 struct config_item *opts_item; 1743 struct f_uvc_opts *opts; 1744 struct uvcg_streaming_header *src_hdr; 1745 struct uvcg_format *target_fmt = NULL; 1746 struct uvcg_format_ptr *format_ptr; 1747 int i, ret = -EINVAL; 1748 1749 src_hdr = to_uvcg_streaming_header(src); 1750 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1751 1752 opts_item = src->ci_parent->ci_parent->ci_parent; 1753 opts = to_f_uvc_opts(opts_item); 1754 1755 mutex_lock(&opts->lock); 1756 1757 if (src_hdr->linked) { 1758 ret = -EBUSY; 1759 goto out; 1760 } 1761 1762 /* 1763 * Linking is only allowed to direct children of the format nodes 1764 * (streaming/uncompressed or streaming/mjpeg nodes). First check that 1765 * the grand-parent of the target matches the grand-parent of the source 1766 * (the streaming node), and then verify that the target parent is a 1767 * format node. 1768 */ 1769 if (src->ci_parent->ci_parent != target->ci_parent->ci_parent) 1770 goto out; 1771 1772 for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) { 1773 if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i])) 1774 break; 1775 } 1776 1777 if (i == ARRAY_SIZE(uvcg_format_names)) 1778 goto out; 1779 1780 target_fmt = container_of(to_config_group(target), struct uvcg_format, 1781 group); 1782 1783 if (!target_fmt) 1784 goto out; 1785 1786 uvcg_format_set_indices(to_config_group(target)); 1787 1788 format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); 1789 if (!format_ptr) { 1790 ret = -ENOMEM; 1791 goto out; 1792 } 1793 ret = 0; 1794 format_ptr->fmt = target_fmt; 1795 list_add_tail(&format_ptr->entry, &src_hdr->formats); 1796 ++src_hdr->num_fmt; 1797 ++target_fmt->linked; 1798 1799 out: 1800 mutex_unlock(&opts->lock); 1801 mutex_unlock(su_mutex); 1802 return ret; 1803 } 1804 1805 static void uvcg_streaming_header_drop_link(struct config_item *src, 1806 struct config_item *target) 1807 { 1808 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1809 struct config_item *opts_item; 1810 struct f_uvc_opts *opts; 1811 struct uvcg_streaming_header *src_hdr; 1812 struct uvcg_format *target_fmt = NULL; 1813 struct uvcg_format_ptr *format_ptr, *tmp; 1814 1815 src_hdr = to_uvcg_streaming_header(src); 1816 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1817 1818 opts_item = src->ci_parent->ci_parent->ci_parent; 1819 opts = to_f_uvc_opts(opts_item); 1820 1821 mutex_lock(&opts->lock); 1822 target_fmt = container_of(to_config_group(target), struct uvcg_format, 1823 group); 1824 1825 if (!target_fmt) 1826 goto out; 1827 1828 list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) 1829 if (format_ptr->fmt == target_fmt) { 1830 list_del(&format_ptr->entry); 1831 kfree(format_ptr); 1832 --src_hdr->num_fmt; 1833 break; 1834 } 1835 1836 --target_fmt->linked; 1837 1838 out: 1839 mutex_unlock(&opts->lock); 1840 mutex_unlock(su_mutex); 1841 } 1842 1843 static struct configfs_item_operations uvcg_streaming_header_item_ops = { 1844 .release = uvcg_config_item_release, 1845 .allow_link = uvcg_streaming_header_allow_link, 1846 .drop_link = uvcg_streaming_header_drop_link, 1847 }; 1848 1849 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits) \ 1850 static ssize_t uvcg_streaming_header_##cname##_show( \ 1851 struct config_item *item, char *page) \ 1852 { \ 1853 struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \ 1854 struct f_uvc_opts *opts; \ 1855 struct config_item *opts_item; \ 1856 struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ 1857 int result; \ 1858 \ 1859 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1860 \ 1861 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ 1862 opts = to_f_uvc_opts(opts_item); \ 1863 \ 1864 mutex_lock(&opts->lock); \ 1865 result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\ 1866 mutex_unlock(&opts->lock); \ 1867 \ 1868 mutex_unlock(su_mutex); \ 1869 return result; \ 1870 } \ 1871 \ 1872 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) 1873 1874 UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, 8); 1875 UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, 8); 1876 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 8); 1877 UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, 8); 1878 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, 8); 1879 1880 #undef UVCG_STREAMING_HEADER_ATTR 1881 1882 static struct configfs_attribute *uvcg_streaming_header_attrs[] = { 1883 &uvcg_streaming_header_attr_bm_info, 1884 &uvcg_streaming_header_attr_b_terminal_link, 1885 &uvcg_streaming_header_attr_b_still_capture_method, 1886 &uvcg_streaming_header_attr_b_trigger_support, 1887 &uvcg_streaming_header_attr_b_trigger_usage, 1888 NULL, 1889 }; 1890 1891 static const struct config_item_type uvcg_streaming_header_type = { 1892 .ct_item_ops = &uvcg_streaming_header_item_ops, 1893 .ct_attrs = uvcg_streaming_header_attrs, 1894 .ct_owner = THIS_MODULE, 1895 }; 1896 1897 static struct config_item 1898 *uvcg_streaming_header_make(struct config_group *group, const char *name) 1899 { 1900 struct uvcg_streaming_header *h; 1901 1902 h = kzalloc(sizeof(*h), GFP_KERNEL); 1903 if (!h) 1904 return ERR_PTR(-ENOMEM); 1905 1906 INIT_LIST_HEAD(&h->formats); 1907 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1908 h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER; 1909 h->desc.bTerminalLink = 3; 1910 h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE; 1911 1912 config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); 1913 1914 return &h->item; 1915 } 1916 1917 static struct configfs_group_operations uvcg_streaming_header_grp_ops = { 1918 .make_item = uvcg_streaming_header_make, 1919 }; 1920 1921 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = { 1922 .type = { 1923 .ct_item_ops = &uvcg_config_item_ops, 1924 .ct_group_ops = &uvcg_streaming_header_grp_ops, 1925 .ct_owner = THIS_MODULE, 1926 }, 1927 .name = "header", 1928 }; 1929 1930 /* ----------------------------------------------------------------------------- 1931 * streaming/<mode>/<format>/<NAME> 1932 */ 1933 1934 #define UVCG_FRAME_ATTR(cname, aname, bits) \ 1935 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ 1936 { \ 1937 struct uvcg_frame *f = to_uvcg_frame(item); \ 1938 struct f_uvc_opts *opts; \ 1939 struct config_item *opts_item; \ 1940 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1941 int result; \ 1942 \ 1943 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1944 \ 1945 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1946 opts = to_f_uvc_opts(opts_item); \ 1947 \ 1948 mutex_lock(&opts->lock); \ 1949 result = sprintf(page, "%u\n", f->frame.cname); \ 1950 mutex_unlock(&opts->lock); \ 1951 \ 1952 mutex_unlock(su_mutex); \ 1953 return result; \ 1954 } \ 1955 \ 1956 static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ 1957 const char *page, size_t len)\ 1958 { \ 1959 struct uvcg_frame *f = to_uvcg_frame(item); \ 1960 struct f_uvc_opts *opts; \ 1961 struct config_item *opts_item; \ 1962 struct uvcg_format *fmt; \ 1963 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1964 typeof(f->frame.cname) num; \ 1965 int ret; \ 1966 \ 1967 ret = kstrtou##bits(page, 0, &num); \ 1968 if (ret) \ 1969 return ret; \ 1970 \ 1971 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1972 \ 1973 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1974 opts = to_f_uvc_opts(opts_item); \ 1975 fmt = to_uvcg_format(f->item.ci_parent); \ 1976 \ 1977 mutex_lock(&opts->lock); \ 1978 if (fmt->linked || opts->refcnt) { \ 1979 ret = -EBUSY; \ 1980 goto end; \ 1981 } \ 1982 \ 1983 f->frame.cname = num; \ 1984 ret = len; \ 1985 end: \ 1986 mutex_unlock(&opts->lock); \ 1987 mutex_unlock(su_mutex); \ 1988 return ret; \ 1989 } \ 1990 \ 1991 UVC_ATTR(uvcg_frame_, cname, aname); 1992 1993 static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, 1994 char *page) 1995 { 1996 struct uvcg_frame *f = to_uvcg_frame(item); 1997 struct uvcg_format *fmt; 1998 struct f_uvc_opts *opts; 1999 struct config_item *opts_item; 2000 struct config_item *fmt_item; 2001 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; 2002 int result; 2003 2004 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2005 2006 fmt_item = f->item.ci_parent; 2007 fmt = to_uvcg_format(fmt_item); 2008 2009 if (!fmt->linked) { 2010 result = -EBUSY; 2011 goto out; 2012 } 2013 2014 opts_item = fmt_item->ci_parent->ci_parent->ci_parent; 2015 opts = to_f_uvc_opts(opts_item); 2016 2017 mutex_lock(&opts->lock); 2018 result = sprintf(page, "%u\n", f->frame.b_frame_index); 2019 mutex_unlock(&opts->lock); 2020 2021 out: 2022 mutex_unlock(su_mutex); 2023 return result; 2024 } 2025 2026 UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); 2027 2028 UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, 8); 2029 UVCG_FRAME_ATTR(w_width, wWidth, 16); 2030 UVCG_FRAME_ATTR(w_height, wHeight, 16); 2031 UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32); 2032 UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32); 2033 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32); 2034 UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32); 2035 UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32); 2036 2037 #undef UVCG_FRAME_ATTR 2038 2039 static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, 2040 char *page) 2041 { 2042 struct uvcg_frame *frm = to_uvcg_frame(item); 2043 struct f_uvc_opts *opts; 2044 struct config_item *opts_item; 2045 struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; 2046 int result, i; 2047 char *pg = page; 2048 2049 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2050 2051 opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 2052 opts = to_f_uvc_opts(opts_item); 2053 2054 mutex_lock(&opts->lock); 2055 for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { 2056 result += sprintf(pg, "%u\n", frm->dw_frame_interval[i]); 2057 pg = page + result; 2058 } 2059 mutex_unlock(&opts->lock); 2060 2061 mutex_unlock(su_mutex); 2062 return result; 2063 } 2064 2065 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, 2066 const char *page, size_t len) 2067 { 2068 struct uvcg_frame *ch = to_uvcg_frame(item); 2069 struct f_uvc_opts *opts; 2070 struct config_item *opts_item; 2071 struct uvcg_format *fmt; 2072 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; 2073 int ret = 0, n = 0; 2074 u32 *frm_intrv, *tmp; 2075 2076 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2077 2078 opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; 2079 opts = to_f_uvc_opts(opts_item); 2080 fmt = to_uvcg_format(ch->item.ci_parent); 2081 2082 mutex_lock(&opts->lock); 2083 if (fmt->linked || opts->refcnt) { 2084 ret = -EBUSY; 2085 goto end; 2086 } 2087 2088 ret = __uvcg_iter_item_entries(page, len, __uvcg_count_item_entries, &n, sizeof(u32)); 2089 if (ret) 2090 goto end; 2091 2092 tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 2093 if (!frm_intrv) { 2094 ret = -ENOMEM; 2095 goto end; 2096 } 2097 2098 ret = __uvcg_iter_item_entries(page, len, __uvcg_fill_item_entries, &tmp, sizeof(u32)); 2099 if (ret) { 2100 kfree(frm_intrv); 2101 goto end; 2102 } 2103 2104 kfree(ch->dw_frame_interval); 2105 ch->dw_frame_interval = frm_intrv; 2106 ch->frame.b_frame_interval_type = n; 2107 sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval), 2108 uvcg_config_compare_u32, NULL); 2109 ret = len; 2110 2111 end: 2112 mutex_unlock(&opts->lock); 2113 mutex_unlock(su_mutex); 2114 return ret; 2115 } 2116 2117 UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); 2118 2119 static struct configfs_attribute *uvcg_frame_attrs1[] = { 2120 &uvcg_frame_attr_b_frame_index, 2121 &uvcg_frame_attr_bm_capabilities, 2122 &uvcg_frame_attr_w_width, 2123 &uvcg_frame_attr_w_height, 2124 &uvcg_frame_attr_dw_min_bit_rate, 2125 &uvcg_frame_attr_dw_max_bit_rate, 2126 &uvcg_frame_attr_dw_max_video_frame_buffer_size, 2127 &uvcg_frame_attr_dw_default_frame_interval, 2128 &uvcg_frame_attr_dw_frame_interval, 2129 NULL, 2130 }; 2131 2132 static struct configfs_attribute *uvcg_frame_attrs2[] = { 2133 &uvcg_frame_attr_b_frame_index, 2134 &uvcg_frame_attr_bm_capabilities, 2135 &uvcg_frame_attr_w_width, 2136 &uvcg_frame_attr_w_height, 2137 &uvcg_frame_attr_dw_min_bit_rate, 2138 &uvcg_frame_attr_dw_max_bit_rate, 2139 &uvcg_frame_attr_dw_default_frame_interval, 2140 &uvcg_frame_attr_dw_frame_interval, 2141 &uvcg_frame_attr_dw_bytes_perline, 2142 NULL, 2143 }; 2144 2145 static const struct config_item_type uvcg_frame_type1 = { 2146 .ct_item_ops = &uvcg_config_item_ops, 2147 .ct_attrs = uvcg_frame_attrs1, 2148 .ct_owner = THIS_MODULE, 2149 }; 2150 2151 static const struct config_item_type uvcg_frame_type2 = { 2152 .ct_item_ops = &uvcg_config_item_ops, 2153 .ct_attrs = uvcg_frame_attrs2, 2154 .ct_owner = THIS_MODULE, 2155 }; 2156 2157 static struct config_item *uvcg_frame_make(struct config_group *group, 2158 const char *name) 2159 { 2160 struct uvcg_frame *h; 2161 struct uvcg_format *fmt; 2162 struct f_uvc_opts *opts; 2163 struct config_item *opts_item; 2164 struct uvcg_frame_ptr *frame_ptr; 2165 2166 h = kzalloc(sizeof(*h), GFP_KERNEL); 2167 if (!h) 2168 return ERR_PTR(-ENOMEM); 2169 2170 h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; 2171 h->frame.b_frame_index = 1; 2172 h->frame.w_width = 640; 2173 h->frame.w_height = 360; 2174 h->frame.dw_min_bit_rate = 18432000; 2175 h->frame.dw_max_bit_rate = 55296000; 2176 h->frame.dw_max_video_frame_buffer_size = 460800; 2177 h->frame.dw_default_frame_interval = 666666; 2178 h->frame.dw_bytes_perline = 0; 2179 2180 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 2181 opts = to_f_uvc_opts(opts_item); 2182 2183 mutex_lock(&opts->lock); 2184 fmt = to_uvcg_format(&group->cg_item); 2185 if (fmt->type == UVCG_UNCOMPRESSED) { 2186 h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED; 2187 h->fmt_type = UVCG_UNCOMPRESSED; 2188 } else if (fmt->type == UVCG_MJPEG) { 2189 h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; 2190 h->fmt_type = UVCG_MJPEG; 2191 } else if (fmt->type == UVCG_FRAMEBASED) { 2192 h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED; 2193 h->fmt_type = UVCG_FRAMEBASED; 2194 } else { 2195 mutex_unlock(&opts->lock); 2196 kfree(h); 2197 return ERR_PTR(-EINVAL); 2198 } 2199 2200 frame_ptr = kzalloc(sizeof(*frame_ptr), GFP_KERNEL); 2201 if (!frame_ptr) { 2202 mutex_unlock(&opts->lock); 2203 kfree(h); 2204 return ERR_PTR(-ENOMEM); 2205 } 2206 2207 frame_ptr->frm = h; 2208 list_add_tail(&frame_ptr->entry, &fmt->frames); 2209 ++fmt->num_frames; 2210 mutex_unlock(&opts->lock); 2211 2212 if (fmt->type == UVCG_FRAMEBASED) 2213 config_item_init_type_name(&h->item, name, &uvcg_frame_type2); 2214 else 2215 config_item_init_type_name(&h->item, name, &uvcg_frame_type1); 2216 2217 return &h->item; 2218 } 2219 2220 static void uvcg_frame_drop(struct config_group *group, struct config_item *item) 2221 { 2222 struct uvcg_format *fmt; 2223 struct f_uvc_opts *opts; 2224 struct config_item *opts_item; 2225 struct uvcg_frame *target_frm = NULL; 2226 struct uvcg_frame_ptr *frame_ptr, *tmp; 2227 2228 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 2229 opts = to_f_uvc_opts(opts_item); 2230 2231 mutex_lock(&opts->lock); 2232 target_frm = container_of(item, struct uvcg_frame, item); 2233 fmt = to_uvcg_format(&group->cg_item); 2234 2235 list_for_each_entry_safe(frame_ptr, tmp, &fmt->frames, entry) 2236 if (frame_ptr->frm == target_frm) { 2237 list_del(&frame_ptr->entry); 2238 kfree(frame_ptr); 2239 --fmt->num_frames; 2240 break; 2241 } 2242 mutex_unlock(&opts->lock); 2243 2244 config_item_put(item); 2245 } 2246 2247 static void uvcg_format_set_indices(struct config_group *fmt) 2248 { 2249 struct config_item *ci; 2250 unsigned int i = 1; 2251 2252 list_for_each_entry(ci, &fmt->cg_children, ci_entry) { 2253 struct uvcg_frame *frm; 2254 2255 frm = to_uvcg_frame(ci); 2256 frm->frame.b_frame_index = i++; 2257 } 2258 } 2259 2260 /* ----------------------------------------------------------------------------- 2261 * streaming/uncompressed/<NAME> 2262 */ 2263 2264 static struct configfs_group_operations uvcg_uncompressed_group_ops = { 2265 .make_item = uvcg_frame_make, 2266 .drop_item = uvcg_frame_drop, 2267 }; 2268 2269 static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, 2270 char *page) 2271 { 2272 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 2273 struct f_uvc_opts *opts; 2274 struct config_item *opts_item; 2275 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 2276 2277 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2278 2279 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 2280 opts = to_f_uvc_opts(opts_item); 2281 2282 mutex_lock(&opts->lock); 2283 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 2284 mutex_unlock(&opts->lock); 2285 2286 mutex_unlock(su_mutex); 2287 2288 return sizeof(ch->desc.guidFormat); 2289 } 2290 2291 static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, 2292 const char *page, size_t len) 2293 { 2294 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 2295 struct f_uvc_opts *opts; 2296 struct config_item *opts_item; 2297 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 2298 const struct uvc_format_desc *format; 2299 u8 tmpguidFormat[sizeof(ch->desc.guidFormat)]; 2300 int ret; 2301 2302 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2303 2304 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 2305 opts = to_f_uvc_opts(opts_item); 2306 2307 mutex_lock(&opts->lock); 2308 if (ch->fmt.linked || opts->refcnt) { 2309 ret = -EBUSY; 2310 goto end; 2311 } 2312 2313 memcpy(tmpguidFormat, page, 2314 min(sizeof(tmpguidFormat), len)); 2315 2316 format = uvc_format_by_guid(tmpguidFormat); 2317 if (!format) { 2318 ret = -EINVAL; 2319 goto end; 2320 } 2321 2322 memcpy(ch->desc.guidFormat, tmpguidFormat, 2323 min(sizeof(ch->desc.guidFormat), len)); 2324 ret = sizeof(ch->desc.guidFormat); 2325 2326 end: 2327 mutex_unlock(&opts->lock); 2328 mutex_unlock(su_mutex); 2329 return ret; 2330 } 2331 2332 UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); 2333 2334 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \ 2335 static ssize_t uvcg_uncompressed_##cname##_show( \ 2336 struct config_item *item, char *page) \ 2337 { \ 2338 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 2339 struct f_uvc_opts *opts; \ 2340 struct config_item *opts_item; \ 2341 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2342 int result; \ 2343 \ 2344 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2345 \ 2346 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2347 opts = to_f_uvc_opts(opts_item); \ 2348 \ 2349 mutex_lock(&opts->lock); \ 2350 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2351 mutex_unlock(&opts->lock); \ 2352 \ 2353 mutex_unlock(su_mutex); \ 2354 return result; \ 2355 } \ 2356 \ 2357 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); 2358 2359 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \ 2360 static ssize_t uvcg_uncompressed_##cname##_show( \ 2361 struct config_item *item, char *page) \ 2362 { \ 2363 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 2364 struct f_uvc_opts *opts; \ 2365 struct config_item *opts_item; \ 2366 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2367 int result; \ 2368 \ 2369 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2370 \ 2371 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2372 opts = to_f_uvc_opts(opts_item); \ 2373 \ 2374 mutex_lock(&opts->lock); \ 2375 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2376 mutex_unlock(&opts->lock); \ 2377 \ 2378 mutex_unlock(su_mutex); \ 2379 return result; \ 2380 } \ 2381 \ 2382 static ssize_t \ 2383 uvcg_uncompressed_##cname##_store(struct config_item *item, \ 2384 const char *page, size_t len) \ 2385 { \ 2386 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 2387 struct f_uvc_opts *opts; \ 2388 struct config_item *opts_item; \ 2389 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2390 int ret; \ 2391 u8 num; \ 2392 \ 2393 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2394 \ 2395 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2396 opts = to_f_uvc_opts(opts_item); \ 2397 \ 2398 mutex_lock(&opts->lock); \ 2399 if (u->fmt.linked || opts->refcnt) { \ 2400 ret = -EBUSY; \ 2401 goto end; \ 2402 } \ 2403 \ 2404 ret = kstrtou8(page, 0, &num); \ 2405 if (ret) \ 2406 goto end; \ 2407 \ 2408 /* index values in uvc are never 0 */ \ 2409 if (!num) { \ 2410 ret = -EINVAL; \ 2411 goto end; \ 2412 } \ 2413 \ 2414 u->desc.aname = num; \ 2415 ret = len; \ 2416 end: \ 2417 mutex_unlock(&opts->lock); \ 2418 mutex_unlock(su_mutex); \ 2419 return ret; \ 2420 } \ 2421 \ 2422 UVC_ATTR(uvcg_uncompressed_, cname, aname); 2423 2424 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8); 2425 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8); 2426 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 2427 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 2428 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 2429 UVCG_UNCOMPRESSED_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8); 2430 2431 #undef UVCG_UNCOMPRESSED_ATTR 2432 #undef UVCG_UNCOMPRESSED_ATTR_RO 2433 2434 static inline ssize_t 2435 uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) 2436 { 2437 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 2438 return uvcg_format_bma_controls_show(&unc->fmt, page); 2439 } 2440 2441 static inline ssize_t 2442 uvcg_uncompressed_bma_controls_store(struct config_item *item, 2443 const char *page, size_t len) 2444 { 2445 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 2446 return uvcg_format_bma_controls_store(&unc->fmt, page, len); 2447 } 2448 2449 UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); 2450 2451 static struct configfs_attribute *uvcg_uncompressed_attrs[] = { 2452 &uvcg_uncompressed_attr_b_format_index, 2453 &uvcg_uncompressed_attr_guid_format, 2454 &uvcg_uncompressed_attr_b_bits_per_pixel, 2455 &uvcg_uncompressed_attr_b_default_frame_index, 2456 &uvcg_uncompressed_attr_b_aspect_ratio_x, 2457 &uvcg_uncompressed_attr_b_aspect_ratio_y, 2458 &uvcg_uncompressed_attr_bm_interlace_flags, 2459 &uvcg_uncompressed_attr_bma_controls, 2460 NULL, 2461 }; 2462 2463 static const struct config_item_type uvcg_uncompressed_type = { 2464 .ct_item_ops = &uvcg_format_item_operations, 2465 .ct_group_ops = &uvcg_uncompressed_group_ops, 2466 .ct_attrs = uvcg_uncompressed_attrs, 2467 .ct_owner = THIS_MODULE, 2468 }; 2469 2470 static struct config_group *uvcg_uncompressed_make(struct config_group *group, 2471 const char *name) 2472 { 2473 static char guid[] = { 2474 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 2475 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 2476 }; 2477 struct uvcg_color_matching *color_match; 2478 struct config_item *streaming; 2479 struct uvcg_uncompressed *h; 2480 2481 streaming = group->cg_item.ci_parent; 2482 color_match = uvcg_format_get_default_color_match(streaming); 2483 if (!color_match) 2484 return ERR_PTR(-EINVAL); 2485 2486 h = kzalloc(sizeof(*h), GFP_KERNEL); 2487 if (!h) 2488 return ERR_PTR(-ENOMEM); 2489 2490 h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; 2491 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 2492 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 2493 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 2494 h->desc.bBitsPerPixel = 16; 2495 h->desc.bDefaultFrameIndex = 1; 2496 h->desc.bAspectRatioX = 0; 2497 h->desc.bAspectRatioY = 0; 2498 h->desc.bmInterlaceFlags = 0; 2499 h->desc.bCopyProtect = 0; 2500 2501 INIT_LIST_HEAD(&h->fmt.frames); 2502 h->fmt.type = UVCG_UNCOMPRESSED; 2503 h->fmt.color_matching = color_match; 2504 color_match->refcnt++; 2505 config_group_init_type_name(&h->fmt.group, name, 2506 &uvcg_uncompressed_type); 2507 2508 return &h->fmt.group; 2509 } 2510 2511 static struct configfs_group_operations uvcg_uncompressed_grp_ops = { 2512 .make_group = uvcg_uncompressed_make, 2513 }; 2514 2515 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { 2516 .type = { 2517 .ct_item_ops = &uvcg_config_item_ops, 2518 .ct_group_ops = &uvcg_uncompressed_grp_ops, 2519 .ct_owner = THIS_MODULE, 2520 }, 2521 .name = "uncompressed", 2522 }; 2523 2524 /* ----------------------------------------------------------------------------- 2525 * streaming/mjpeg/<NAME> 2526 */ 2527 2528 static struct configfs_group_operations uvcg_mjpeg_group_ops = { 2529 .make_item = uvcg_frame_make, 2530 .drop_item = uvcg_frame_drop, 2531 }; 2532 2533 #define UVCG_MJPEG_ATTR_RO(cname, aname, bits) \ 2534 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 2535 { \ 2536 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 2537 struct f_uvc_opts *opts; \ 2538 struct config_item *opts_item; \ 2539 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2540 int result; \ 2541 \ 2542 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2543 \ 2544 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2545 opts = to_f_uvc_opts(opts_item); \ 2546 \ 2547 mutex_lock(&opts->lock); \ 2548 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2549 mutex_unlock(&opts->lock); \ 2550 \ 2551 mutex_unlock(su_mutex); \ 2552 return result; \ 2553 } \ 2554 \ 2555 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) 2556 2557 #define UVCG_MJPEG_ATTR(cname, aname, bits) \ 2558 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 2559 { \ 2560 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 2561 struct f_uvc_opts *opts; \ 2562 struct config_item *opts_item; \ 2563 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2564 int result; \ 2565 \ 2566 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2567 \ 2568 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2569 opts = to_f_uvc_opts(opts_item); \ 2570 \ 2571 mutex_lock(&opts->lock); \ 2572 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2573 mutex_unlock(&opts->lock); \ 2574 \ 2575 mutex_unlock(su_mutex); \ 2576 return result; \ 2577 } \ 2578 \ 2579 static ssize_t \ 2580 uvcg_mjpeg_##cname##_store(struct config_item *item, \ 2581 const char *page, size_t len) \ 2582 { \ 2583 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 2584 struct f_uvc_opts *opts; \ 2585 struct config_item *opts_item; \ 2586 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2587 int ret; \ 2588 u8 num; \ 2589 \ 2590 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2591 \ 2592 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2593 opts = to_f_uvc_opts(opts_item); \ 2594 \ 2595 mutex_lock(&opts->lock); \ 2596 if (u->fmt.linked || opts->refcnt) { \ 2597 ret = -EBUSY; \ 2598 goto end; \ 2599 } \ 2600 \ 2601 ret = kstrtou8(page, 0, &num); \ 2602 if (ret) \ 2603 goto end; \ 2604 \ 2605 /* index values in uvc are never 0 */ \ 2606 if (!num) { \ 2607 ret = -EINVAL; \ 2608 goto end; \ 2609 } \ 2610 \ 2611 u->desc.aname = num; \ 2612 ret = len; \ 2613 end: \ 2614 mutex_unlock(&opts->lock); \ 2615 mutex_unlock(su_mutex); \ 2616 return ret; \ 2617 } \ 2618 \ 2619 UVC_ATTR(uvcg_mjpeg_, cname, aname) 2620 2621 UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8); 2622 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 2623 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8); 2624 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 2625 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 2626 UVCG_MJPEG_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8); 2627 2628 #undef UVCG_MJPEG_ATTR 2629 #undef UVCG_MJPEG_ATTR_RO 2630 2631 static inline ssize_t 2632 uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) 2633 { 2634 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 2635 return uvcg_format_bma_controls_show(&u->fmt, page); 2636 } 2637 2638 static inline ssize_t 2639 uvcg_mjpeg_bma_controls_store(struct config_item *item, 2640 const char *page, size_t len) 2641 { 2642 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 2643 return uvcg_format_bma_controls_store(&u->fmt, page, len); 2644 } 2645 2646 UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); 2647 2648 static struct configfs_attribute *uvcg_mjpeg_attrs[] = { 2649 &uvcg_mjpeg_attr_b_format_index, 2650 &uvcg_mjpeg_attr_b_default_frame_index, 2651 &uvcg_mjpeg_attr_bm_flags, 2652 &uvcg_mjpeg_attr_b_aspect_ratio_x, 2653 &uvcg_mjpeg_attr_b_aspect_ratio_y, 2654 &uvcg_mjpeg_attr_bm_interlace_flags, 2655 &uvcg_mjpeg_attr_bma_controls, 2656 NULL, 2657 }; 2658 2659 static const struct config_item_type uvcg_mjpeg_type = { 2660 .ct_item_ops = &uvcg_format_item_operations, 2661 .ct_group_ops = &uvcg_mjpeg_group_ops, 2662 .ct_attrs = uvcg_mjpeg_attrs, 2663 .ct_owner = THIS_MODULE, 2664 }; 2665 2666 static struct config_group *uvcg_mjpeg_make(struct config_group *group, 2667 const char *name) 2668 { 2669 struct uvcg_color_matching *color_match; 2670 struct config_item *streaming; 2671 struct uvcg_mjpeg *h; 2672 2673 streaming = group->cg_item.ci_parent; 2674 color_match = uvcg_format_get_default_color_match(streaming); 2675 if (!color_match) 2676 return ERR_PTR(-EINVAL); 2677 2678 h = kzalloc(sizeof(*h), GFP_KERNEL); 2679 if (!h) 2680 return ERR_PTR(-ENOMEM); 2681 2682 h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; 2683 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 2684 h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; 2685 h->desc.bDefaultFrameIndex = 1; 2686 h->desc.bAspectRatioX = 0; 2687 h->desc.bAspectRatioY = 0; 2688 h->desc.bmInterlaceFlags = 0; 2689 h->desc.bCopyProtect = 0; 2690 2691 INIT_LIST_HEAD(&h->fmt.frames); 2692 h->fmt.type = UVCG_MJPEG; 2693 h->fmt.color_matching = color_match; 2694 color_match->refcnt++; 2695 config_group_init_type_name(&h->fmt.group, name, 2696 &uvcg_mjpeg_type); 2697 2698 return &h->fmt.group; 2699 } 2700 2701 static struct configfs_group_operations uvcg_mjpeg_grp_ops = { 2702 .make_group = uvcg_mjpeg_make, 2703 }; 2704 2705 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { 2706 .type = { 2707 .ct_item_ops = &uvcg_config_item_ops, 2708 .ct_group_ops = &uvcg_mjpeg_grp_ops, 2709 .ct_owner = THIS_MODULE, 2710 }, 2711 .name = "mjpeg", 2712 }; 2713 2714 /* ----------------------------------------------------------------------------- 2715 * streaming/framebased/<NAME> 2716 */ 2717 2718 static struct configfs_group_operations uvcg_framebased_group_ops = { 2719 .make_item = uvcg_frame_make, 2720 .drop_item = uvcg_frame_drop, 2721 }; 2722 2723 #define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits) \ 2724 static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \ 2725 char *page) \ 2726 { \ 2727 struct uvcg_framebased *u = to_uvcg_framebased(item); \ 2728 struct f_uvc_opts *opts; \ 2729 struct config_item *opts_item; \ 2730 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2731 int result; \ 2732 \ 2733 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2734 \ 2735 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2736 opts = to_f_uvc_opts(opts_item); \ 2737 \ 2738 mutex_lock(&opts->lock); \ 2739 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2740 mutex_unlock(&opts->lock); \ 2741 \ 2742 mutex_unlock(su_mutex); \ 2743 return result; \ 2744 } \ 2745 \ 2746 UVC_ATTR_RO(uvcg_framebased_, cname, aname) 2747 2748 #define UVCG_FRAMEBASED_ATTR(cname, aname, bits) \ 2749 static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \ 2750 char *page) \ 2751 { \ 2752 struct uvcg_framebased *u = to_uvcg_framebased(item); \ 2753 struct f_uvc_opts *opts; \ 2754 struct config_item *opts_item; \ 2755 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2756 int result; \ 2757 \ 2758 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2759 \ 2760 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2761 opts = to_f_uvc_opts(opts_item); \ 2762 \ 2763 mutex_lock(&opts->lock); \ 2764 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 2765 mutex_unlock(&opts->lock); \ 2766 \ 2767 mutex_unlock(su_mutex); \ 2768 return result; \ 2769 } \ 2770 \ 2771 static ssize_t \ 2772 uvcg_framebased_##cname##_store(struct config_item *item, \ 2773 const char *page, size_t len) \ 2774 { \ 2775 struct uvcg_framebased *u = to_uvcg_framebased(item); \ 2776 struct f_uvc_opts *opts; \ 2777 struct config_item *opts_item; \ 2778 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 2779 int ret; \ 2780 u8 num; \ 2781 \ 2782 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2783 \ 2784 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 2785 opts = to_f_uvc_opts(opts_item); \ 2786 \ 2787 mutex_lock(&opts->lock); \ 2788 if (u->fmt.linked || opts->refcnt) { \ 2789 ret = -EBUSY; \ 2790 goto end; \ 2791 } \ 2792 \ 2793 ret = kstrtou8(page, 0, &num); \ 2794 if (ret) \ 2795 goto end; \ 2796 \ 2797 if (num > 255) { \ 2798 ret = -EINVAL; \ 2799 goto end; \ 2800 } \ 2801 u->desc.aname = num; \ 2802 ret = len; \ 2803 end: \ 2804 mutex_unlock(&opts->lock); \ 2805 mutex_unlock(su_mutex); \ 2806 return ret; \ 2807 } \ 2808 \ 2809 UVC_ATTR(uvcg_framebased_, cname, aname) 2810 2811 UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8); 2812 UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8); 2813 UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 2814 UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 2815 UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 2816 UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); 2817 2818 #undef UVCG_FRAMEBASED_ATTR 2819 #undef UVCG_FRAMEBASED_ATTR_RO 2820 2821 static ssize_t uvcg_framebased_guid_format_show(struct config_item *item, 2822 char *page) 2823 { 2824 struct uvcg_framebased *ch = to_uvcg_framebased(item); 2825 struct f_uvc_opts *opts; 2826 struct config_item *opts_item; 2827 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 2828 2829 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2830 2831 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 2832 opts = to_f_uvc_opts(opts_item); 2833 2834 mutex_lock(&opts->lock); 2835 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 2836 mutex_unlock(&opts->lock); 2837 2838 mutex_unlock(su_mutex); 2839 2840 return sizeof(ch->desc.guidFormat); 2841 } 2842 2843 static ssize_t uvcg_framebased_guid_format_store(struct config_item *item, 2844 const char *page, size_t len) 2845 { 2846 struct uvcg_framebased *ch = to_uvcg_framebased(item); 2847 struct f_uvc_opts *opts; 2848 struct config_item *opts_item; 2849 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 2850 int ret; 2851 2852 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2853 2854 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 2855 opts = to_f_uvc_opts(opts_item); 2856 2857 mutex_lock(&opts->lock); 2858 if (ch->fmt.linked || opts->refcnt) { 2859 ret = -EBUSY; 2860 goto end; 2861 } 2862 2863 memcpy(ch->desc.guidFormat, page, 2864 min(sizeof(ch->desc.guidFormat), len)); 2865 ret = sizeof(ch->desc.guidFormat); 2866 2867 end: 2868 mutex_unlock(&opts->lock); 2869 mutex_unlock(su_mutex); 2870 return ret; 2871 } 2872 2873 UVC_ATTR(uvcg_framebased_, guid_format, guidFormat); 2874 2875 static inline ssize_t 2876 uvcg_framebased_bma_controls_show(struct config_item *item, char *page) 2877 { 2878 struct uvcg_framebased *u = to_uvcg_framebased(item); 2879 2880 return uvcg_format_bma_controls_show(&u->fmt, page); 2881 } 2882 2883 static inline ssize_t 2884 uvcg_framebased_bma_controls_store(struct config_item *item, 2885 const char *page, size_t len) 2886 { 2887 struct uvcg_framebased *u = to_uvcg_framebased(item); 2888 2889 return uvcg_format_bma_controls_store(&u->fmt, page, len); 2890 } 2891 2892 UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls); 2893 2894 static struct configfs_attribute *uvcg_framebased_attrs[] = { 2895 &uvcg_framebased_attr_b_format_index, 2896 &uvcg_framebased_attr_b_default_frame_index, 2897 &uvcg_framebased_attr_b_bits_per_pixel, 2898 &uvcg_framebased_attr_b_aspect_ratio_x, 2899 &uvcg_framebased_attr_b_aspect_ratio_y, 2900 &uvcg_framebased_attr_bm_interface_flags, 2901 &uvcg_framebased_attr_bma_controls, 2902 &uvcg_framebased_attr_guid_format, 2903 NULL, 2904 }; 2905 2906 static const struct config_item_type uvcg_framebased_type = { 2907 .ct_item_ops = &uvcg_config_item_ops, 2908 .ct_group_ops = &uvcg_framebased_group_ops, 2909 .ct_attrs = uvcg_framebased_attrs, 2910 .ct_owner = THIS_MODULE, 2911 }; 2912 2913 static struct config_group *uvcg_framebased_make(struct config_group *group, 2914 const char *name) 2915 { 2916 static char guid[] = { /*Declear frame based as H264 format*/ 2917 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 2918 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 2919 }; 2920 struct uvcg_color_matching *color_match; 2921 struct config_item *streaming; 2922 struct uvcg_framebased *h; 2923 2924 streaming = group->cg_item.ci_parent; 2925 color_match = uvcg_format_get_default_color_match(streaming); 2926 if (!color_match) 2927 return ERR_PTR(-EINVAL); 2928 2929 h = kzalloc(sizeof(*h), GFP_KERNEL); 2930 if (!h) 2931 return ERR_PTR(-ENOMEM); 2932 2933 h->desc.bLength = UVC_DT_FORMAT_FRAMEBASED_SIZE; 2934 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 2935 h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED; 2936 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 2937 h->desc.bBitsPerPixel = 0; 2938 h->desc.bDefaultFrameIndex = 1; 2939 h->desc.bAspectRatioX = 0; 2940 h->desc.bAspectRatioY = 0; 2941 h->desc.bmInterfaceFlags = 0; 2942 h->desc.bCopyProtect = 0; 2943 h->desc.bVariableSize = 1; 2944 2945 INIT_LIST_HEAD(&h->fmt.frames); 2946 h->fmt.type = UVCG_FRAMEBASED; 2947 2948 h->fmt.color_matching = color_match; 2949 color_match->refcnt++; 2950 config_group_init_type_name(&h->fmt.group, name, 2951 &uvcg_framebased_type); 2952 2953 return &h->fmt.group; 2954 } 2955 2956 static struct configfs_group_operations uvcg_framebased_grp_ops = { 2957 .make_group = uvcg_framebased_make, 2958 }; 2959 2960 static const struct uvcg_config_group_type uvcg_framebased_grp_type = { 2961 .type = { 2962 .ct_item_ops = &uvcg_config_item_ops, 2963 .ct_group_ops = &uvcg_framebased_grp_ops, 2964 .ct_owner = THIS_MODULE, 2965 }, 2966 .name = "framebased", 2967 }; 2968 2969 /* ----------------------------------------------------------------------------- 2970 * streaming/color_matching/default 2971 */ 2972 2973 #define UVCG_COLOR_MATCHING_ATTR(cname, aname, bits) \ 2974 static ssize_t uvcg_color_matching_##cname##_show( \ 2975 struct config_item *item, char *page) \ 2976 { \ 2977 struct config_group *group = to_config_group(item); \ 2978 struct uvcg_color_matching *color_match = \ 2979 to_uvcg_color_matching(group); \ 2980 struct f_uvc_opts *opts; \ 2981 struct config_item *opts_item; \ 2982 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 2983 int result; \ 2984 \ 2985 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 2986 \ 2987 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 2988 opts = to_f_uvc_opts(opts_item); \ 2989 \ 2990 mutex_lock(&opts->lock); \ 2991 result = sprintf(page, "%u\n", \ 2992 le##bits##_to_cpu(color_match->desc.aname)); \ 2993 mutex_unlock(&opts->lock); \ 2994 \ 2995 mutex_unlock(su_mutex); \ 2996 return result; \ 2997 } \ 2998 \ 2999 static ssize_t uvcg_color_matching_##cname##_store( \ 3000 struct config_item *item, const char *page, size_t len) \ 3001 { \ 3002 struct config_group *group = to_config_group(item); \ 3003 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 3004 struct uvcg_color_matching *color_match = \ 3005 to_uvcg_color_matching(group); \ 3006 struct f_uvc_opts *opts; \ 3007 struct config_item *opts_item; \ 3008 int ret; \ 3009 u##bits num; \ 3010 \ 3011 ret = kstrtou##bits(page, 0, &num); \ 3012 if (ret) \ 3013 return ret; \ 3014 \ 3015 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 3016 \ 3017 if (color_match->refcnt) { \ 3018 ret = -EBUSY; \ 3019 goto unlock_su; \ 3020 } \ 3021 \ 3022 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 3023 opts = to_f_uvc_opts(opts_item); \ 3024 \ 3025 mutex_lock(&opts->lock); \ 3026 \ 3027 color_match->desc.aname = num; \ 3028 ret = len; \ 3029 \ 3030 mutex_unlock(&opts->lock); \ 3031 unlock_su: \ 3032 mutex_unlock(su_mutex); \ 3033 \ 3034 return ret; \ 3035 } \ 3036 UVC_ATTR(uvcg_color_matching_, cname, aname) 3037 3038 UVCG_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8); 3039 UVCG_COLOR_MATCHING_ATTR(b_transfer_characteristics, bTransferCharacteristics, 8); 3040 UVCG_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8); 3041 3042 #undef UVCG_COLOR_MATCHING_ATTR 3043 3044 static struct configfs_attribute *uvcg_color_matching_attrs[] = { 3045 &uvcg_color_matching_attr_b_color_primaries, 3046 &uvcg_color_matching_attr_b_transfer_characteristics, 3047 &uvcg_color_matching_attr_b_matrix_coefficients, 3048 NULL, 3049 }; 3050 3051 static void uvcg_color_matching_release(struct config_item *item) 3052 { 3053 struct uvcg_color_matching *color_match = 3054 to_uvcg_color_matching(to_config_group(item)); 3055 3056 kfree(color_match); 3057 } 3058 3059 static struct configfs_item_operations uvcg_color_matching_item_ops = { 3060 .release = uvcg_color_matching_release, 3061 }; 3062 3063 static const struct config_item_type uvcg_color_matching_type = { 3064 .ct_item_ops = &uvcg_color_matching_item_ops, 3065 .ct_attrs = uvcg_color_matching_attrs, 3066 .ct_owner = THIS_MODULE, 3067 }; 3068 3069 /* ----------------------------------------------------------------------------- 3070 * streaming/color_matching 3071 */ 3072 3073 static struct config_group *uvcg_color_matching_make(struct config_group *group, 3074 const char *name) 3075 { 3076 struct uvcg_color_matching *color_match; 3077 3078 color_match = kzalloc(sizeof(*color_match), GFP_KERNEL); 3079 if (!color_match) 3080 return ERR_PTR(-ENOMEM); 3081 3082 color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE; 3083 color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE; 3084 color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT; 3085 3086 config_group_init_type_name(&color_match->group, name, 3087 &uvcg_color_matching_type); 3088 3089 return &color_match->group; 3090 } 3091 3092 static struct configfs_group_operations uvcg_color_matching_grp_group_ops = { 3093 .make_group = uvcg_color_matching_make, 3094 }; 3095 3096 static int uvcg_color_matching_create_children(struct config_group *parent) 3097 { 3098 struct uvcg_color_matching *color_match; 3099 3100 color_match = kzalloc(sizeof(*color_match), GFP_KERNEL); 3101 if (!color_match) 3102 return -ENOMEM; 3103 3104 color_match->desc.bLength = UVC_DT_COLOR_MATCHING_SIZE; 3105 color_match->desc.bDescriptorType = USB_DT_CS_INTERFACE; 3106 color_match->desc.bDescriptorSubType = UVC_VS_COLORFORMAT; 3107 color_match->desc.bColorPrimaries = UVC_COLOR_PRIMARIES_BT_709_SRGB; 3108 color_match->desc.bTransferCharacteristics = UVC_TRANSFER_CHARACTERISTICS_BT_709; 3109 color_match->desc.bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS_SMPTE_170M; 3110 3111 config_group_init_type_name(&color_match->group, "default", 3112 &uvcg_color_matching_type); 3113 configfs_add_default_group(&color_match->group, parent); 3114 3115 return 0; 3116 } 3117 3118 static const struct uvcg_config_group_type uvcg_color_matching_grp_type = { 3119 .type = { 3120 .ct_item_ops = &uvcg_config_item_ops, 3121 .ct_group_ops = &uvcg_color_matching_grp_group_ops, 3122 .ct_owner = THIS_MODULE, 3123 }, 3124 .name = "color_matching", 3125 .create_children = uvcg_color_matching_create_children, 3126 }; 3127 3128 /* ----------------------------------------------------------------------------- 3129 * streaming/class/{fs|hs|ss} 3130 */ 3131 3132 struct uvcg_streaming_class_group { 3133 struct config_group group; 3134 const char *name; 3135 }; 3136 3137 static inline struct uvc_descriptor_header 3138 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) 3139 { 3140 struct uvcg_streaming_class_group *group = 3141 container_of(i, struct uvcg_streaming_class_group, 3142 group.cg_item); 3143 3144 if (!strcmp(group->name, "fs")) 3145 return &o->uvc_fs_streaming_cls; 3146 3147 if (!strcmp(group->name, "hs")) 3148 return &o->uvc_hs_streaming_cls; 3149 3150 if (!strcmp(group->name, "ss")) 3151 return &o->uvc_ss_streaming_cls; 3152 3153 return NULL; 3154 } 3155 3156 enum uvcg_strm_type { 3157 UVCG_HEADER = 0, 3158 UVCG_FORMAT, 3159 UVCG_FRAME, 3160 UVCG_COLOR_MATCHING, 3161 }; 3162 3163 /* 3164 * Iterate over a hierarchy of streaming descriptors' config items. 3165 * The items are created by the user with configfs. 3166 * 3167 * It "processes" the header pointed to by @priv1, then for each format 3168 * that follows the header "processes" the format itself and then for 3169 * each frame inside a format "processes" the frame. 3170 * 3171 * As a "processing" function the @fun is used. 3172 * 3173 * __uvcg_iter_strm_cls() is used in two context: first, to calculate 3174 * the amount of memory needed for an array of streaming descriptors 3175 * and second, to actually fill the array. 3176 * 3177 * @h: streaming header pointer 3178 * @priv2: an "inout" parameter (the caller might want to see the changes to it) 3179 * @priv3: an "inout" parameter (the caller might want to see the changes to it) 3180 * @fun: callback function for processing each level of the hierarchy 3181 */ 3182 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, 3183 void *priv2, void *priv3, 3184 int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) 3185 { 3186 struct uvcg_format_ptr *f; 3187 struct config_group *grp; 3188 struct config_item *item; 3189 struct uvcg_frame *frm; 3190 int ret, i, j; 3191 3192 if (!fun) 3193 return -EINVAL; 3194 3195 i = j = 0; 3196 ret = fun(h, priv2, priv3, 0, UVCG_HEADER); 3197 if (ret) 3198 return ret; 3199 list_for_each_entry(f, &h->formats, entry) { 3200 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); 3201 if (ret) 3202 return ret; 3203 grp = &f->fmt->group; 3204 j = 0; 3205 list_for_each_entry(item, &grp->cg_children, ci_entry) { 3206 frm = to_uvcg_frame(item); 3207 ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); 3208 if (ret) 3209 return ret; 3210 } 3211 3212 ret = fun(f->fmt->color_matching, priv2, priv3, 0, 3213 UVCG_COLOR_MATCHING); 3214 if (ret) 3215 return ret; 3216 } 3217 3218 return ret; 3219 } 3220 3221 /* 3222 * Count how many bytes are needed for an array of streaming descriptors. 3223 * 3224 * @priv1: pointer to a header, format or frame 3225 * @priv2: inout parameter, accumulated size of the array 3226 * @priv3: inout parameter, accumulated number of the array elements 3227 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls 3228 */ 3229 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 3230 enum uvcg_strm_type type) 3231 { 3232 size_t *size = priv2; 3233 size_t *count = priv3; 3234 3235 switch (type) { 3236 case UVCG_HEADER: { 3237 struct uvcg_streaming_header *h = priv1; 3238 3239 *size += sizeof(h->desc); 3240 /* bmaControls */ 3241 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; 3242 } 3243 break; 3244 case UVCG_FORMAT: { 3245 struct uvcg_format *fmt = priv1; 3246 3247 if (fmt->type == UVCG_UNCOMPRESSED) { 3248 struct uvcg_uncompressed *u = 3249 container_of(fmt, struct uvcg_uncompressed, 3250 fmt); 3251 3252 *size += sizeof(u->desc); 3253 } else if (fmt->type == UVCG_MJPEG) { 3254 struct uvcg_mjpeg *m = 3255 container_of(fmt, struct uvcg_mjpeg, fmt); 3256 3257 *size += sizeof(m->desc); 3258 } else if (fmt->type == UVCG_FRAMEBASED) { 3259 struct uvcg_framebased *f = 3260 container_of(fmt, struct uvcg_framebased, fmt); 3261 3262 *size += sizeof(f->desc); 3263 } else { 3264 return -EINVAL; 3265 } 3266 } 3267 break; 3268 case UVCG_FRAME: { 3269 struct uvcg_frame *frm = priv1; 3270 int sz = sizeof(frm->dw_frame_interval); 3271 3272 *size += sizeof(frm->frame); 3273 /* 3274 * framebased has duplicate member with uncompressed and 3275 * mjpeg, so minus it 3276 */ 3277 *size -= sizeof(u32); 3278 *size += frm->frame.b_frame_interval_type * sz; 3279 } 3280 break; 3281 case UVCG_COLOR_MATCHING: { 3282 struct uvcg_color_matching *color_match = priv1; 3283 3284 *size += sizeof(color_match->desc); 3285 } 3286 break; 3287 } 3288 3289 ++*count; 3290 3291 return 0; 3292 } 3293 3294 static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm, 3295 int sz) 3296 { 3297 struct uvc_frame_framebased *desc = dest; 3298 3299 desc->bLength = frm->frame.b_length; 3300 desc->bDescriptorType = frm->frame.b_descriptor_type; 3301 desc->bDescriptorSubType = frm->frame.b_descriptor_subtype; 3302 desc->bFrameIndex = frm->frame.b_frame_index; 3303 desc->bmCapabilities = frm->frame.bm_capabilities; 3304 desc->wWidth = frm->frame.w_width; 3305 desc->wHeight = frm->frame.w_height; 3306 desc->dwMinBitRate = frm->frame.dw_min_bit_rate; 3307 desc->dwMaxBitRate = frm->frame.dw_max_bit_rate; 3308 desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval; 3309 desc->bFrameIntervalType = frm->frame.b_frame_interval_type; 3310 desc->dwBytesPerLine = frm->frame.dw_bytes_perline; 3311 3312 return 0; 3313 } 3314 3315 /* 3316 * Fill an array of streaming descriptors. 3317 * 3318 * @priv1: pointer to a header, format or frame 3319 * @priv2: inout parameter, pointer into a block of memory 3320 * @priv3: inout parameter, pointer to a 2-dimensional array 3321 */ 3322 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 3323 enum uvcg_strm_type type) 3324 { 3325 void **dest = priv2; 3326 struct uvc_descriptor_header ***array = priv3; 3327 size_t sz; 3328 3329 **array = *dest; 3330 ++*array; 3331 3332 switch (type) { 3333 case UVCG_HEADER: { 3334 struct uvc_input_header_descriptor *ihdr = *dest; 3335 struct uvcg_streaming_header *h = priv1; 3336 struct uvcg_format_ptr *f; 3337 3338 memcpy(*dest, &h->desc, sizeof(h->desc)); 3339 *dest += sizeof(h->desc); 3340 sz = UVCG_STREAMING_CONTROL_SIZE; 3341 list_for_each_entry(f, &h->formats, entry) { 3342 memcpy(*dest, f->fmt->bmaControls, sz); 3343 *dest += sz; 3344 } 3345 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; 3346 ihdr->bNumFormats = h->num_fmt; 3347 } 3348 break; 3349 case UVCG_FORMAT: { 3350 struct uvcg_format *fmt = priv1; 3351 3352 if (fmt->type == UVCG_UNCOMPRESSED) { 3353 struct uvcg_uncompressed *u = 3354 container_of(fmt, struct uvcg_uncompressed, 3355 fmt); 3356 3357 u->desc.bFormatIndex = n + 1; 3358 u->desc.bNumFrameDescriptors = fmt->num_frames; 3359 memcpy(*dest, &u->desc, sizeof(u->desc)); 3360 *dest += sizeof(u->desc); 3361 } else if (fmt->type == UVCG_MJPEG) { 3362 struct uvcg_mjpeg *m = 3363 container_of(fmt, struct uvcg_mjpeg, fmt); 3364 3365 m->desc.bFormatIndex = n + 1; 3366 m->desc.bNumFrameDescriptors = fmt->num_frames; 3367 memcpy(*dest, &m->desc, sizeof(m->desc)); 3368 *dest += sizeof(m->desc); 3369 } else if (fmt->type == UVCG_FRAMEBASED) { 3370 struct uvcg_framebased *f = 3371 container_of(fmt, struct uvcg_framebased, 3372 fmt); 3373 3374 f->desc.bFormatIndex = n + 1; 3375 f->desc.bNumFrameDescriptors = fmt->num_frames; 3376 memcpy(*dest, &f->desc, sizeof(f->desc)); 3377 *dest += sizeof(f->desc); 3378 } else { 3379 return -EINVAL; 3380 } 3381 } 3382 break; 3383 case UVCG_FRAME: { 3384 struct uvcg_frame *frm = priv1; 3385 struct uvc_descriptor_header *h = *dest; 3386 3387 sz = sizeof(frm->frame) - 4; 3388 if (frm->fmt_type != UVCG_FRAMEBASED) 3389 memcpy(*dest, &frm->frame, sz); 3390 else 3391 __uvcg_copy_framebased_desc(*dest, frm, sz); 3392 *dest += sz; 3393 sz = frm->frame.b_frame_interval_type * 3394 sizeof(*frm->dw_frame_interval); 3395 memcpy(*dest, frm->dw_frame_interval, sz); 3396 *dest += sz; 3397 if (frm->fmt_type == UVCG_UNCOMPRESSED) 3398 h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( 3399 frm->frame.b_frame_interval_type); 3400 else if (frm->fmt_type == UVCG_MJPEG) 3401 h->bLength = UVC_DT_FRAME_MJPEG_SIZE( 3402 frm->frame.b_frame_interval_type); 3403 else if (frm->fmt_type == UVCG_FRAMEBASED) 3404 h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE( 3405 frm->frame.b_frame_interval_type); 3406 } 3407 break; 3408 case UVCG_COLOR_MATCHING: { 3409 struct uvcg_color_matching *color_match = priv1; 3410 3411 memcpy(*dest, &color_match->desc, sizeof(color_match->desc)); 3412 *dest += sizeof(color_match->desc); 3413 } 3414 break; 3415 } 3416 3417 return 0; 3418 } 3419 3420 static int uvcg_streaming_class_allow_link(struct config_item *src, 3421 struct config_item *target) 3422 { 3423 struct config_item *streaming, *header; 3424 struct f_uvc_opts *opts; 3425 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 3426 struct uvc_descriptor_header ***class_array, **cl_arr; 3427 struct uvcg_streaming_header *target_hdr; 3428 void *data, *data_save; 3429 size_t size = 0, count = 0; 3430 int ret = -EINVAL; 3431 3432 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 3433 3434 streaming = src->ci_parent->ci_parent; 3435 header = config_group_find_item(to_config_group(streaming), "header"); 3436 if (!header || target->ci_parent != header) 3437 goto out; 3438 3439 opts = to_f_uvc_opts(streaming->ci_parent); 3440 3441 mutex_lock(&opts->lock); 3442 3443 class_array = __uvcg_get_stream_class_arr(src, opts); 3444 if (!class_array || *class_array || opts->refcnt) { 3445 ret = -EBUSY; 3446 goto unlock; 3447 } 3448 3449 target_hdr = to_uvcg_streaming_header(target); 3450 ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); 3451 if (ret) 3452 goto unlock; 3453 3454 count += 1; /* NULL */ 3455 *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); 3456 if (!*class_array) { 3457 ret = -ENOMEM; 3458 goto unlock; 3459 } 3460 3461 data = data_save = kzalloc(size, GFP_KERNEL); 3462 if (!data) { 3463 kfree(*class_array); 3464 *class_array = NULL; 3465 ret = -ENOMEM; 3466 goto unlock; 3467 } 3468 cl_arr = *class_array; 3469 ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, 3470 __uvcg_fill_strm); 3471 if (ret) { 3472 kfree(*class_array); 3473 *class_array = NULL; 3474 /* 3475 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() 3476 * might have advanced the "data", so use a backup copy 3477 */ 3478 kfree(data_save); 3479 goto unlock; 3480 } 3481 3482 ++target_hdr->linked; 3483 ret = 0; 3484 3485 unlock: 3486 mutex_unlock(&opts->lock); 3487 out: 3488 config_item_put(header); 3489 mutex_unlock(su_mutex); 3490 return ret; 3491 } 3492 3493 static void uvcg_streaming_class_drop_link(struct config_item *src, 3494 struct config_item *target) 3495 { 3496 struct config_item *streaming, *header; 3497 struct f_uvc_opts *opts; 3498 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 3499 struct uvc_descriptor_header ***class_array; 3500 struct uvcg_streaming_header *target_hdr; 3501 3502 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 3503 3504 streaming = src->ci_parent->ci_parent; 3505 header = config_group_find_item(to_config_group(streaming), "header"); 3506 if (!header || target->ci_parent != header) 3507 goto out; 3508 3509 opts = to_f_uvc_opts(streaming->ci_parent); 3510 3511 mutex_lock(&opts->lock); 3512 3513 class_array = __uvcg_get_stream_class_arr(src, opts); 3514 if (!class_array || !*class_array) 3515 goto unlock; 3516 3517 if (opts->refcnt) 3518 goto unlock; 3519 3520 target_hdr = to_uvcg_streaming_header(target); 3521 --target_hdr->linked; 3522 kfree(**class_array); 3523 kfree(*class_array); 3524 *class_array = NULL; 3525 3526 unlock: 3527 mutex_unlock(&opts->lock); 3528 out: 3529 config_item_put(header); 3530 mutex_unlock(su_mutex); 3531 } 3532 3533 static struct configfs_item_operations uvcg_streaming_class_item_ops = { 3534 .release = uvcg_config_item_release, 3535 .allow_link = uvcg_streaming_class_allow_link, 3536 .drop_link = uvcg_streaming_class_drop_link, 3537 }; 3538 3539 static const struct config_item_type uvcg_streaming_class_type = { 3540 .ct_item_ops = &uvcg_streaming_class_item_ops, 3541 .ct_owner = THIS_MODULE, 3542 }; 3543 3544 /* ----------------------------------------------------------------------------- 3545 * streaming/class 3546 */ 3547 3548 static int uvcg_streaming_class_create_children(struct config_group *parent) 3549 { 3550 static const char * const names[] = { "fs", "hs", "ss" }; 3551 unsigned int i; 3552 3553 for (i = 0; i < ARRAY_SIZE(names); ++i) { 3554 struct uvcg_streaming_class_group *group; 3555 3556 group = kzalloc(sizeof(*group), GFP_KERNEL); 3557 if (!group) 3558 return -ENOMEM; 3559 3560 group->name = names[i]; 3561 3562 config_group_init_type_name(&group->group, group->name, 3563 &uvcg_streaming_class_type); 3564 configfs_add_default_group(&group->group, parent); 3565 } 3566 3567 return 0; 3568 } 3569 3570 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = { 3571 .type = { 3572 .ct_item_ops = &uvcg_config_item_ops, 3573 .ct_owner = THIS_MODULE, 3574 }, 3575 .name = "class", 3576 .create_children = uvcg_streaming_class_create_children, 3577 }; 3578 3579 /* ----------------------------------------------------------------------------- 3580 * streaming 3581 */ 3582 3583 static ssize_t uvcg_default_streaming_b_interface_number_show( 3584 struct config_item *item, char *page) 3585 { 3586 struct config_group *group = to_config_group(item); 3587 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 3588 struct config_item *opts_item; 3589 struct f_uvc_opts *opts; 3590 int result = 0; 3591 3592 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 3593 3594 opts_item = item->ci_parent; 3595 opts = to_f_uvc_opts(opts_item); 3596 3597 mutex_lock(&opts->lock); 3598 result += sprintf(page, "%u\n", opts->streaming_interface); 3599 mutex_unlock(&opts->lock); 3600 3601 mutex_unlock(su_mutex); 3602 3603 return result; 3604 } 3605 3606 UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber); 3607 3608 static struct configfs_attribute *uvcg_default_streaming_attrs[] = { 3609 &uvcg_default_streaming_attr_b_interface_number, 3610 NULL, 3611 }; 3612 3613 static const struct uvcg_config_group_type uvcg_streaming_grp_type = { 3614 .type = { 3615 .ct_item_ops = &uvcg_config_item_ops, 3616 .ct_attrs = uvcg_default_streaming_attrs, 3617 .ct_owner = THIS_MODULE, 3618 }, 3619 .name = "streaming", 3620 .children = (const struct uvcg_config_group_type*[]) { 3621 &uvcg_streaming_header_grp_type, 3622 &uvcg_uncompressed_grp_type, 3623 &uvcg_mjpeg_grp_type, 3624 &uvcg_framebased_grp_type, 3625 &uvcg_color_matching_grp_type, 3626 &uvcg_streaming_class_grp_type, 3627 NULL, 3628 }, 3629 }; 3630 3631 /* ----------------------------------------------------------------------------- 3632 * UVC function 3633 */ 3634 3635 static void uvc_func_item_release(struct config_item *item) 3636 { 3637 struct f_uvc_opts *opts = to_f_uvc_opts(item); 3638 3639 uvcg_config_remove_children(to_config_group(item)); 3640 usb_put_function_instance(&opts->func_inst); 3641 } 3642 3643 static int uvc_func_allow_link(struct config_item *src, struct config_item *tgt) 3644 { 3645 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 3646 struct gadget_string *string; 3647 struct config_item *strings; 3648 struct f_uvc_opts *opts; 3649 int ret = 0; 3650 3651 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 3652 3653 /* Validate that the target is an entry in strings/<langid> */ 3654 strings = config_group_find_item(to_config_group(src->ci_parent->ci_parent), 3655 "strings"); 3656 if (!strings || tgt->ci_parent->ci_parent != strings) { 3657 ret = -EINVAL; 3658 goto put_strings; 3659 } 3660 3661 string = to_gadget_string(tgt); 3662 3663 opts = to_f_uvc_opts(src); 3664 mutex_lock(&opts->lock); 3665 3666 if (!strcmp(tgt->ci_name, "iad_desc")) 3667 opts->iad_index = string->usb_string.id; 3668 else if (!strcmp(tgt->ci_name, "vs0_desc")) 3669 opts->vs0_index = string->usb_string.id; 3670 else if (!strcmp(tgt->ci_name, "vs1_desc")) 3671 opts->vs1_index = string->usb_string.id; 3672 else 3673 ret = -EINVAL; 3674 3675 mutex_unlock(&opts->lock); 3676 3677 put_strings: 3678 config_item_put(strings); 3679 mutex_unlock(su_mutex); 3680 3681 return ret; 3682 } 3683 3684 static void uvc_func_drop_link(struct config_item *src, struct config_item *tgt) 3685 { 3686 struct f_uvc_opts *opts; 3687 3688 opts = to_f_uvc_opts(src); 3689 mutex_lock(&opts->lock); 3690 3691 if (!strcmp(tgt->ci_name, "iad_desc")) 3692 opts->iad_index = 0; 3693 else if (!strcmp(tgt->ci_name, "vs0_desc")) 3694 opts->vs0_index = 0; 3695 else if (!strcmp(tgt->ci_name, "vs1_desc")) 3696 opts->vs1_index = 0; 3697 3698 mutex_unlock(&opts->lock); 3699 } 3700 3701 static struct configfs_item_operations uvc_func_item_ops = { 3702 .release = uvc_func_item_release, 3703 .allow_link = uvc_func_allow_link, 3704 .drop_link = uvc_func_drop_link, 3705 }; 3706 3707 #define UVCG_OPTS_ATTR(cname, aname, limit) \ 3708 static ssize_t f_uvc_opts_##cname##_show( \ 3709 struct config_item *item, char *page) \ 3710 { \ 3711 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 3712 int result; \ 3713 \ 3714 mutex_lock(&opts->lock); \ 3715 result = sprintf(page, "%u\n", opts->cname); \ 3716 mutex_unlock(&opts->lock); \ 3717 \ 3718 return result; \ 3719 } \ 3720 \ 3721 static ssize_t \ 3722 f_uvc_opts_##cname##_store(struct config_item *item, \ 3723 const char *page, size_t len) \ 3724 { \ 3725 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 3726 unsigned int num; \ 3727 int ret; \ 3728 \ 3729 mutex_lock(&opts->lock); \ 3730 if (opts->refcnt) { \ 3731 ret = -EBUSY; \ 3732 goto end; \ 3733 } \ 3734 \ 3735 ret = kstrtouint(page, 0, &num); \ 3736 if (ret) \ 3737 goto end; \ 3738 \ 3739 if (num > limit) { \ 3740 ret = -EINVAL; \ 3741 goto end; \ 3742 } \ 3743 opts->cname = num; \ 3744 ret = len; \ 3745 end: \ 3746 mutex_unlock(&opts->lock); \ 3747 return ret; \ 3748 } \ 3749 \ 3750 UVC_ATTR(f_uvc_opts_, cname, cname) 3751 3752 UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16); 3753 UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072); 3754 UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); 3755 3756 #undef UVCG_OPTS_ATTR 3757 3758 #define UVCG_OPTS_STRING_ATTR(cname, aname) \ 3759 static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\ 3760 char *page) \ 3761 { \ 3762 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 3763 int result; \ 3764 \ 3765 mutex_lock(&opts->lock); \ 3766 result = scnprintf(page, sizeof(opts->aname), "%s", opts->aname);\ 3767 mutex_unlock(&opts->lock); \ 3768 \ 3769 return result; \ 3770 } \ 3771 \ 3772 static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\ 3773 const char *page, size_t len) \ 3774 { \ 3775 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 3776 int size = min(sizeof(opts->aname), len + 1); \ 3777 int ret = 0; \ 3778 \ 3779 mutex_lock(&opts->lock); \ 3780 if (opts->refcnt) { \ 3781 ret = -EBUSY; \ 3782 goto end; \ 3783 } \ 3784 \ 3785 ret = strscpy(opts->aname, page, size); \ 3786 if (ret == -E2BIG) \ 3787 ret = size - 1; \ 3788 \ 3789 end: \ 3790 mutex_unlock(&opts->lock); \ 3791 return ret; \ 3792 } \ 3793 \ 3794 UVC_ATTR(f_uvc_opts_string_, cname, aname) 3795 3796 UVCG_OPTS_STRING_ATTR(function_name, function_name); 3797 3798 #undef UVCG_OPTS_STRING_ATTR 3799 3800 static struct configfs_attribute *uvc_attrs[] = { 3801 &f_uvc_opts_attr_streaming_interval, 3802 &f_uvc_opts_attr_streaming_maxpacket, 3803 &f_uvc_opts_attr_streaming_maxburst, 3804 &f_uvc_opts_string_attr_function_name, 3805 NULL, 3806 }; 3807 3808 static const struct uvcg_config_group_type uvc_func_type = { 3809 .type = { 3810 .ct_item_ops = &uvc_func_item_ops, 3811 .ct_attrs = uvc_attrs, 3812 .ct_owner = THIS_MODULE, 3813 }, 3814 .name = "", 3815 .children = (const struct uvcg_config_group_type*[]) { 3816 &uvcg_control_grp_type, 3817 &uvcg_streaming_grp_type, 3818 NULL, 3819 }, 3820 }; 3821 3822 int uvcg_attach_configfs(struct f_uvc_opts *opts) 3823 { 3824 int ret; 3825 3826 config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name, 3827 &uvc_func_type.type); 3828 3829 ret = uvcg_config_create_children(&opts->func_inst.group, 3830 &uvc_func_type); 3831 if (ret < 0) 3832 config_group_put(&opts->func_inst.group); 3833 3834 return ret; 3835 } 3836