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