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