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