1// SPDX-License-Identifier: GPL-2.0 2/* 3 * uvc_configfs.c 4 * 5 * Configfs support for the uvc function. 6 * 7 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 8 * http://www.samsung.com 9 * 10 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 11 */ 12 13#include <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(i_terminal, iTerminal, 8); 509 510#undef UVCG_DEFAULT_OUTPUT_ATTR 511 512static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item, 513 char *page) 514{ 515 struct config_group *group = to_config_group(item); 516 struct f_uvc_opts *opts; 517 struct config_item *opts_item; 518 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 519 struct uvc_output_terminal_descriptor *cd; 520 int result; 521 522 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 523 524 opts_item = group->cg_item.ci_parent->ci_parent-> 525 ci_parent->ci_parent; 526 opts = to_f_uvc_opts(opts_item); 527 cd = &opts->uvc_output_terminal; 528 529 mutex_lock(&opts->lock); 530 result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID)); 531 mutex_unlock(&opts->lock); 532 533 mutex_unlock(su_mutex); 534 535 return result; 536} 537 538static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, 539 const char *page, size_t len) 540{ 541 struct config_group *group = to_config_group(item); 542 struct f_uvc_opts *opts; 543 struct config_item *opts_item; 544 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 545 struct uvc_output_terminal_descriptor *cd; 546 int result; 547 u8 num; 548 549 result = kstrtou8(page, 0, &num); 550 if (result) 551 return result; 552 553 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 554 555 opts_item = group->cg_item.ci_parent->ci_parent-> 556 ci_parent->ci_parent; 557 opts = to_f_uvc_opts(opts_item); 558 cd = &opts->uvc_output_terminal; 559 560 mutex_lock(&opts->lock); 561 cd->bSourceID = num; 562 mutex_unlock(&opts->lock); 563 564 mutex_unlock(su_mutex); 565 566 return len; 567} 568UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID); 569 570static struct configfs_attribute *uvcg_default_output_attrs[] = { 571 &uvcg_default_output_attr_b_terminal_id, 572 &uvcg_default_output_attr_w_terminal_type, 573 &uvcg_default_output_attr_b_assoc_terminal, 574 &uvcg_default_output_attr_b_source_id, 575 &uvcg_default_output_attr_i_terminal, 576 NULL, 577}; 578 579static const struct uvcg_config_group_type uvcg_default_output_type = { 580 .type = { 581 .ct_item_ops = &uvcg_config_item_ops, 582 .ct_attrs = uvcg_default_output_attrs, 583 .ct_owner = THIS_MODULE, 584 }, 585 .name = "default", 586}; 587 588/* ----------------------------------------------------------------------------- 589 * control/terminal/output 590 */ 591 592static const struct uvcg_config_group_type uvcg_output_grp_type = { 593 .type = { 594 .ct_item_ops = &uvcg_config_item_ops, 595 .ct_owner = THIS_MODULE, 596 }, 597 .name = "output", 598 .children = (const struct uvcg_config_group_type*[]) { 599 &uvcg_default_output_type, 600 NULL, 601 }, 602}; 603 604/* ----------------------------------------------------------------------------- 605 * control/terminal 606 */ 607 608static const struct uvcg_config_group_type uvcg_terminal_grp_type = { 609 .type = { 610 .ct_item_ops = &uvcg_config_item_ops, 611 .ct_owner = THIS_MODULE, 612 }, 613 .name = "terminal", 614 .children = (const struct uvcg_config_group_type*[]) { 615 &uvcg_camera_grp_type, 616 &uvcg_output_grp_type, 617 NULL, 618 }, 619}; 620 621/* ----------------------------------------------------------------------------- 622 * control/class/{fs|ss} 623 */ 624 625struct uvcg_control_class_group { 626 struct config_group group; 627 const char *name; 628}; 629 630static inline struct uvc_descriptor_header 631**uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o) 632{ 633 struct uvcg_control_class_group *group = 634 container_of(i, struct uvcg_control_class_group, 635 group.cg_item); 636 637 if (!strcmp(group->name, "fs")) 638 return o->uvc_fs_control_cls; 639 640 if (!strcmp(group->name, "ss")) 641 return o->uvc_ss_control_cls; 642 643 return NULL; 644} 645 646static int uvcg_control_class_allow_link(struct config_item *src, 647 struct config_item *target) 648{ 649 struct config_item *control, *header; 650 struct f_uvc_opts *opts; 651 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 652 struct uvc_descriptor_header **class_array; 653 struct uvcg_control_header *target_hdr; 654 int ret = -EINVAL; 655 656 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 657 658 control = src->ci_parent->ci_parent; 659 header = config_group_find_item(to_config_group(control), "header"); 660 if (!header || target->ci_parent != header) 661 goto out; 662 663 opts = to_f_uvc_opts(control->ci_parent); 664 665 mutex_lock(&opts->lock); 666 667 class_array = uvcg_get_ctl_class_arr(src, opts); 668 if (!class_array) 669 goto unlock; 670 if (opts->refcnt || class_array[0]) { 671 ret = -EBUSY; 672 goto unlock; 673 } 674 675 target_hdr = to_uvcg_control_header(target); 676 ++target_hdr->linked; 677 class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc; 678 ret = 0; 679 680unlock: 681 mutex_unlock(&opts->lock); 682out: 683 config_item_put(header); 684 mutex_unlock(su_mutex); 685 return ret; 686} 687 688static void uvcg_control_class_drop_link(struct config_item *src, 689 struct config_item *target) 690{ 691 struct config_item *control, *header; 692 struct f_uvc_opts *opts; 693 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 694 struct uvc_descriptor_header **class_array; 695 struct uvcg_control_header *target_hdr; 696 697 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 698 699 control = src->ci_parent->ci_parent; 700 header = config_group_find_item(to_config_group(control), "header"); 701 if (!header || target->ci_parent != header) 702 goto out; 703 704 opts = to_f_uvc_opts(control->ci_parent); 705 706 mutex_lock(&opts->lock); 707 708 class_array = uvcg_get_ctl_class_arr(src, opts); 709 if (!class_array || opts->refcnt) 710 goto unlock; 711 712 target_hdr = to_uvcg_control_header(target); 713 --target_hdr->linked; 714 class_array[0] = NULL; 715 716unlock: 717 mutex_unlock(&opts->lock); 718out: 719 config_item_put(header); 720 mutex_unlock(su_mutex); 721} 722 723static struct configfs_item_operations uvcg_control_class_item_ops = { 724 .release = uvcg_config_item_release, 725 .allow_link = uvcg_control_class_allow_link, 726 .drop_link = uvcg_control_class_drop_link, 727}; 728 729static const struct config_item_type uvcg_control_class_type = { 730 .ct_item_ops = &uvcg_control_class_item_ops, 731 .ct_owner = THIS_MODULE, 732}; 733 734/* ----------------------------------------------------------------------------- 735 * control/class 736 */ 737 738static int uvcg_control_class_create_children(struct config_group *parent) 739{ 740 static const char * const names[] = { "fs", "ss" }; 741 unsigned int i; 742 743 for (i = 0; i < ARRAY_SIZE(names); ++i) { 744 struct uvcg_control_class_group *group; 745 746 group = kzalloc(sizeof(*group), GFP_KERNEL); 747 if (!group) 748 return -ENOMEM; 749 750 group->name = names[i]; 751 752 config_group_init_type_name(&group->group, group->name, 753 &uvcg_control_class_type); 754 configfs_add_default_group(&group->group, parent); 755 } 756 757 return 0; 758} 759 760static const struct uvcg_config_group_type uvcg_control_class_grp_type = { 761 .type = { 762 .ct_item_ops = &uvcg_config_item_ops, 763 .ct_owner = THIS_MODULE, 764 }, 765 .name = "class", 766 .create_children = uvcg_control_class_create_children, 767}; 768 769/* ----------------------------------------------------------------------------- 770 * control 771 */ 772 773static ssize_t uvcg_default_control_b_interface_number_show( 774 struct config_item *item, char *page) 775{ 776 struct config_group *group = to_config_group(item); 777 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 778 struct config_item *opts_item; 779 struct f_uvc_opts *opts; 780 int result = 0; 781 782 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 783 784 opts_item = item->ci_parent; 785 opts = to_f_uvc_opts(opts_item); 786 787 mutex_lock(&opts->lock); 788 result += sprintf(page, "%u\n", opts->control_interface); 789 mutex_unlock(&opts->lock); 790 791 mutex_unlock(su_mutex); 792 793 return result; 794} 795 796UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber); 797 798static struct configfs_attribute *uvcg_default_control_attrs[] = { 799 &uvcg_default_control_attr_b_interface_number, 800 NULL, 801}; 802 803static const struct uvcg_config_group_type uvcg_control_grp_type = { 804 .type = { 805 .ct_item_ops = &uvcg_config_item_ops, 806 .ct_attrs = uvcg_default_control_attrs, 807 .ct_owner = THIS_MODULE, 808 }, 809 .name = "control", 810 .children = (const struct uvcg_config_group_type*[]) { 811 &uvcg_control_header_grp_type, 812 &uvcg_processing_grp_type, 813 &uvcg_terminal_grp_type, 814 &uvcg_control_class_grp_type, 815 NULL, 816 }, 817}; 818 819/* ----------------------------------------------------------------------------- 820 * streaming/uncompressed 821 * streaming/mjpeg 822 */ 823 824static const char * const uvcg_format_names[] = { 825 "uncompressed", 826 "mjpeg", 827}; 828 829enum uvcg_format_type { 830 UVCG_UNCOMPRESSED = 0, 831 UVCG_MJPEG, 832}; 833 834struct uvcg_format { 835 struct config_group group; 836 enum uvcg_format_type type; 837 unsigned linked; 838 unsigned num_frames; 839 __u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE]; 840}; 841 842static struct uvcg_format *to_uvcg_format(struct config_item *item) 843{ 844 return container_of(to_config_group(item), struct uvcg_format, group); 845} 846 847static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page) 848{ 849 struct f_uvc_opts *opts; 850 struct config_item *opts_item; 851 struct mutex *su_mutex = &f->group.cg_subsys->su_mutex; 852 int result, i; 853 char *pg = page; 854 855 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 856 857 opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent; 858 opts = to_f_uvc_opts(opts_item); 859 860 mutex_lock(&opts->lock); 861 result = sprintf(pg, "0x"); 862 pg += result; 863 for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) { 864 result += sprintf(pg, "%x\n", f->bmaControls[i]); 865 pg = page + result; 866 } 867 mutex_unlock(&opts->lock); 868 869 mutex_unlock(su_mutex); 870 return result; 871} 872 873static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch, 874 const char *page, size_t len) 875{ 876 struct f_uvc_opts *opts; 877 struct config_item *opts_item; 878 struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex; 879 int ret = -EINVAL; 880 881 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 882 883 opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent; 884 opts = to_f_uvc_opts(opts_item); 885 886 mutex_lock(&opts->lock); 887 if (ch->linked || opts->refcnt) { 888 ret = -EBUSY; 889 goto end; 890 } 891 892 if (len < 4 || *page != '0' || 893 (*(page + 1) != 'x' && *(page + 1) != 'X')) 894 goto end; 895 ret = hex2bin(ch->bmaControls, page + 2, 1); 896 if (ret < 0) 897 goto end; 898 ret = len; 899end: 900 mutex_unlock(&opts->lock); 901 mutex_unlock(su_mutex); 902 return ret; 903} 904 905struct uvcg_format_ptr { 906 struct uvcg_format *fmt; 907 struct list_head entry; 908}; 909 910/* ----------------------------------------------------------------------------- 911 * streaming/header/<NAME> 912 * streaming/header 913 */ 914 915struct uvcg_streaming_header { 916 struct config_item item; 917 struct uvc_input_header_descriptor desc; 918 unsigned linked; 919 struct list_head formats; 920 unsigned num_fmt; 921}; 922 923static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item) 924{ 925 return container_of(item, struct uvcg_streaming_header, item); 926} 927 928static void uvcg_format_set_indices(struct config_group *fmt); 929 930static int uvcg_streaming_header_allow_link(struct config_item *src, 931 struct config_item *target) 932{ 933 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 934 struct config_item *opts_item; 935 struct f_uvc_opts *opts; 936 struct uvcg_streaming_header *src_hdr; 937 struct uvcg_format *target_fmt = NULL; 938 struct uvcg_format_ptr *format_ptr; 939 int i, ret = -EINVAL; 940 941 src_hdr = to_uvcg_streaming_header(src); 942 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 943 944 opts_item = src->ci_parent->ci_parent->ci_parent; 945 opts = to_f_uvc_opts(opts_item); 946 947 mutex_lock(&opts->lock); 948 949 if (src_hdr->linked) { 950 ret = -EBUSY; 951 goto out; 952 } 953 954 /* 955 * Linking is only allowed to direct children of the format nodes 956 * (streaming/uncompressed or streaming/mjpeg nodes). First check that 957 * the grand-parent of the target matches the grand-parent of the source 958 * (the streaming node), and then verify that the target parent is a 959 * format node. 960 */ 961 if (src->ci_parent->ci_parent != target->ci_parent->ci_parent) 962 goto out; 963 964 for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) { 965 if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i])) 966 break; 967 } 968 969 if (i == ARRAY_SIZE(uvcg_format_names)) 970 goto out; 971 972 target_fmt = container_of(to_config_group(target), struct uvcg_format, 973 group); 974 if (!target_fmt) 975 goto out; 976 977 uvcg_format_set_indices(to_config_group(target)); 978 979 format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); 980 if (!format_ptr) { 981 ret = -ENOMEM; 982 goto out; 983 } 984 ret = 0; 985 format_ptr->fmt = target_fmt; 986 list_add_tail(&format_ptr->entry, &src_hdr->formats); 987 ++src_hdr->num_fmt; 988 ++target_fmt->linked; 989 990out: 991 mutex_unlock(&opts->lock); 992 mutex_unlock(su_mutex); 993 return ret; 994} 995 996static void uvcg_streaming_header_drop_link(struct config_item *src, 997 struct config_item *target) 998{ 999 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 1000 struct config_item *opts_item; 1001 struct f_uvc_opts *opts; 1002 struct uvcg_streaming_header *src_hdr; 1003 struct uvcg_format *target_fmt = NULL; 1004 struct uvcg_format_ptr *format_ptr, *tmp; 1005 1006 src_hdr = to_uvcg_streaming_header(src); 1007 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1008 1009 opts_item = src->ci_parent->ci_parent->ci_parent; 1010 opts = to_f_uvc_opts(opts_item); 1011 1012 mutex_lock(&opts->lock); 1013 target_fmt = container_of(to_config_group(target), struct uvcg_format, 1014 group); 1015 if (!target_fmt) 1016 goto out; 1017 1018 list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) 1019 if (format_ptr->fmt == target_fmt) { 1020 list_del(&format_ptr->entry); 1021 kfree(format_ptr); 1022 --src_hdr->num_fmt; 1023 break; 1024 } 1025 1026 --target_fmt->linked; 1027 1028out: 1029 mutex_unlock(&opts->lock); 1030 mutex_unlock(su_mutex); 1031} 1032 1033static struct configfs_item_operations uvcg_streaming_header_item_ops = { 1034 .release = uvcg_config_item_release, 1035 .allow_link = uvcg_streaming_header_allow_link, 1036 .drop_link = uvcg_streaming_header_drop_link, 1037}; 1038 1039#define UVCG_STREAMING_HEADER_ATTR(cname, aname, bits) \ 1040static ssize_t uvcg_streaming_header_##cname##_show( \ 1041 struct config_item *item, char *page) \ 1042{ \ 1043 struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \ 1044 struct f_uvc_opts *opts; \ 1045 struct config_item *opts_item; \ 1046 struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ 1047 int result; \ 1048 \ 1049 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1050 \ 1051 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ 1052 opts = to_f_uvc_opts(opts_item); \ 1053 \ 1054 mutex_lock(&opts->lock); \ 1055 result = sprintf(page, "%u\n", le##bits##_to_cpu(sh->desc.aname));\ 1056 mutex_unlock(&opts->lock); \ 1057 \ 1058 mutex_unlock(su_mutex); \ 1059 return result; \ 1060} \ 1061 \ 1062UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) 1063 1064UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, 8); 1065UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, 8); 1066UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 8); 1067UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, 8); 1068UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, 8); 1069 1070#undef UVCG_STREAMING_HEADER_ATTR 1071 1072static struct configfs_attribute *uvcg_streaming_header_attrs[] = { 1073 &uvcg_streaming_header_attr_bm_info, 1074 &uvcg_streaming_header_attr_b_terminal_link, 1075 &uvcg_streaming_header_attr_b_still_capture_method, 1076 &uvcg_streaming_header_attr_b_trigger_support, 1077 &uvcg_streaming_header_attr_b_trigger_usage, 1078 NULL, 1079}; 1080 1081static const struct config_item_type uvcg_streaming_header_type = { 1082 .ct_item_ops = &uvcg_streaming_header_item_ops, 1083 .ct_attrs = uvcg_streaming_header_attrs, 1084 .ct_owner = THIS_MODULE, 1085}; 1086 1087static struct config_item 1088*uvcg_streaming_header_make(struct config_group *group, const char *name) 1089{ 1090 struct uvcg_streaming_header *h; 1091 1092 h = kzalloc(sizeof(*h), GFP_KERNEL); 1093 if (!h) 1094 return ERR_PTR(-ENOMEM); 1095 1096 INIT_LIST_HEAD(&h->formats); 1097 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1098 h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER; 1099 h->desc.bTerminalLink = 3; 1100 h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE; 1101 1102 config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); 1103 1104 return &h->item; 1105} 1106 1107static struct configfs_group_operations uvcg_streaming_header_grp_ops = { 1108 .make_item = uvcg_streaming_header_make, 1109}; 1110 1111static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = { 1112 .type = { 1113 .ct_item_ops = &uvcg_config_item_ops, 1114 .ct_group_ops = &uvcg_streaming_header_grp_ops, 1115 .ct_owner = THIS_MODULE, 1116 }, 1117 .name = "header", 1118}; 1119 1120/* ----------------------------------------------------------------------------- 1121 * streaming/<mode>/<format>/<NAME> 1122 */ 1123 1124struct uvcg_frame { 1125 struct config_item item; 1126 enum uvcg_format_type fmt_type; 1127 struct { 1128 u8 b_length; 1129 u8 b_descriptor_type; 1130 u8 b_descriptor_subtype; 1131 u8 b_frame_index; 1132 u8 bm_capabilities; 1133 u16 w_width; 1134 u16 w_height; 1135 u32 dw_min_bit_rate; 1136 u32 dw_max_bit_rate; 1137 u32 dw_max_video_frame_buffer_size; 1138 u32 dw_default_frame_interval; 1139 u8 b_frame_interval_type; 1140 } __attribute__((packed)) frame; 1141 u32 *dw_frame_interval; 1142}; 1143 1144static struct uvcg_frame *to_uvcg_frame(struct config_item *item) 1145{ 1146 return container_of(item, struct uvcg_frame, item); 1147} 1148 1149#define UVCG_FRAME_ATTR(cname, aname, bits) \ 1150static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ 1151{ \ 1152 struct uvcg_frame *f = to_uvcg_frame(item); \ 1153 struct f_uvc_opts *opts; \ 1154 struct config_item *opts_item; \ 1155 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1156 int result; \ 1157 \ 1158 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1159 \ 1160 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1161 opts = to_f_uvc_opts(opts_item); \ 1162 \ 1163 mutex_lock(&opts->lock); \ 1164 result = sprintf(page, "%u\n", f->frame.cname); \ 1165 mutex_unlock(&opts->lock); \ 1166 \ 1167 mutex_unlock(su_mutex); \ 1168 return result; \ 1169} \ 1170 \ 1171static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ 1172 const char *page, size_t len)\ 1173{ \ 1174 struct uvcg_frame *f = to_uvcg_frame(item); \ 1175 struct f_uvc_opts *opts; \ 1176 struct config_item *opts_item; \ 1177 struct uvcg_format *fmt; \ 1178 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1179 typeof(f->frame.cname) num; \ 1180 int ret; \ 1181 \ 1182 ret = kstrtou##bits(page, 0, &num); \ 1183 if (ret) \ 1184 return ret; \ 1185 \ 1186 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1187 \ 1188 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1189 opts = to_f_uvc_opts(opts_item); \ 1190 fmt = to_uvcg_format(f->item.ci_parent); \ 1191 \ 1192 mutex_lock(&opts->lock); \ 1193 if (fmt->linked || opts->refcnt) { \ 1194 ret = -EBUSY; \ 1195 goto end; \ 1196 } \ 1197 \ 1198 f->frame.cname = num; \ 1199 ret = len; \ 1200end: \ 1201 mutex_unlock(&opts->lock); \ 1202 mutex_unlock(su_mutex); \ 1203 return ret; \ 1204} \ 1205 \ 1206UVC_ATTR(uvcg_frame_, cname, aname); 1207 1208static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, 1209 char *page) 1210{ 1211 struct uvcg_frame *f = to_uvcg_frame(item); 1212 struct uvcg_format *fmt; 1213 struct f_uvc_opts *opts; 1214 struct config_item *opts_item; 1215 struct config_item *fmt_item; 1216 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; 1217 int result; 1218 1219 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1220 1221 fmt_item = f->item.ci_parent; 1222 fmt = to_uvcg_format(fmt_item); 1223 1224 if (!fmt->linked) { 1225 result = -EBUSY; 1226 goto out; 1227 } 1228 1229 opts_item = fmt_item->ci_parent->ci_parent->ci_parent; 1230 opts = to_f_uvc_opts(opts_item); 1231 1232 mutex_lock(&opts->lock); 1233 result = sprintf(page, "%u\n", f->frame.b_frame_index); 1234 mutex_unlock(&opts->lock); 1235 1236out: 1237 mutex_unlock(su_mutex); 1238 return result; 1239} 1240 1241UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); 1242 1243UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, 8); 1244UVCG_FRAME_ATTR(w_width, wWidth, 16); 1245UVCG_FRAME_ATTR(w_height, wHeight, 16); 1246UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32); 1247UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32); 1248UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32); 1249UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32); 1250 1251#undef UVCG_FRAME_ATTR 1252 1253static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, 1254 char *page) 1255{ 1256 struct uvcg_frame *frm = to_uvcg_frame(item); 1257 struct f_uvc_opts *opts; 1258 struct config_item *opts_item; 1259 struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; 1260 int result, i; 1261 char *pg = page; 1262 1263 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1264 1265 opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 1266 opts = to_f_uvc_opts(opts_item); 1267 1268 mutex_lock(&opts->lock); 1269 for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { 1270 result += sprintf(pg, "%u\n", frm->dw_frame_interval[i]); 1271 pg = page + result; 1272 } 1273 mutex_unlock(&opts->lock); 1274 1275 mutex_unlock(su_mutex); 1276 return result; 1277} 1278 1279static inline int __uvcg_count_frm_intrv(char *buf, void *priv) 1280{ 1281 ++*((int *)priv); 1282 return 0; 1283} 1284 1285static inline int __uvcg_fill_frm_intrv(char *buf, void *priv) 1286{ 1287 u32 num, **interv; 1288 int ret; 1289 1290 ret = kstrtou32(buf, 0, &num); 1291 if (ret) 1292 return ret; 1293 1294 interv = priv; 1295 **interv = num; 1296 ++*interv; 1297 1298 return 0; 1299} 1300 1301static int __uvcg_iter_frm_intrv(const char *page, size_t len, 1302 int (*fun)(char *, void *), void *priv) 1303{ 1304 /* sign, base 2 representation, newline, terminator */ 1305 char buf[1 + sizeof(u32) * 8 + 1 + 1]; 1306 const char *pg = page; 1307 int i, ret; 1308 1309 if (!fun) 1310 return -EINVAL; 1311 1312 while (pg - page < len) { 1313 i = 0; 1314 while (i < sizeof(buf) && (pg - page < len) && 1315 *pg != '\0' && *pg != '\n') 1316 buf[i++] = *pg++; 1317 if (i == sizeof(buf)) 1318 return -EINVAL; 1319 while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 1320 ++pg; 1321 buf[i] = '\0'; 1322 ret = fun(buf, priv); 1323 if (ret) 1324 return ret; 1325 } 1326 1327 return 0; 1328} 1329 1330static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, 1331 const char *page, size_t len) 1332{ 1333 struct uvcg_frame *ch = to_uvcg_frame(item); 1334 struct f_uvc_opts *opts; 1335 struct config_item *opts_item; 1336 struct uvcg_format *fmt; 1337 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; 1338 int ret = 0, n = 0; 1339 u32 *frm_intrv, *tmp; 1340 1341 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1342 1343 opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; 1344 opts = to_f_uvc_opts(opts_item); 1345 fmt = to_uvcg_format(ch->item.ci_parent); 1346 1347 mutex_lock(&opts->lock); 1348 if (fmt->linked || opts->refcnt) { 1349 ret = -EBUSY; 1350 goto end; 1351 } 1352 1353 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); 1354 if (ret) 1355 goto end; 1356 1357 tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 1358 if (!frm_intrv) { 1359 ret = -ENOMEM; 1360 goto end; 1361 } 1362 1363 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); 1364 if (ret) { 1365 kfree(frm_intrv); 1366 goto end; 1367 } 1368 1369 kfree(ch->dw_frame_interval); 1370 ch->dw_frame_interval = frm_intrv; 1371 ch->frame.b_frame_interval_type = n; 1372 sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval), 1373 uvcg_config_compare_u32, NULL); 1374 ret = len; 1375 1376end: 1377 mutex_unlock(&opts->lock); 1378 mutex_unlock(su_mutex); 1379 return ret; 1380} 1381 1382UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); 1383 1384static struct configfs_attribute *uvcg_frame_attrs[] = { 1385 &uvcg_frame_attr_b_frame_index, 1386 &uvcg_frame_attr_bm_capabilities, 1387 &uvcg_frame_attr_w_width, 1388 &uvcg_frame_attr_w_height, 1389 &uvcg_frame_attr_dw_min_bit_rate, 1390 &uvcg_frame_attr_dw_max_bit_rate, 1391 &uvcg_frame_attr_dw_max_video_frame_buffer_size, 1392 &uvcg_frame_attr_dw_default_frame_interval, 1393 &uvcg_frame_attr_dw_frame_interval, 1394 NULL, 1395}; 1396 1397static const struct config_item_type uvcg_frame_type = { 1398 .ct_item_ops = &uvcg_config_item_ops, 1399 .ct_attrs = uvcg_frame_attrs, 1400 .ct_owner = THIS_MODULE, 1401}; 1402 1403static struct config_item *uvcg_frame_make(struct config_group *group, 1404 const char *name) 1405{ 1406 struct uvcg_frame *h; 1407 struct uvcg_format *fmt; 1408 struct f_uvc_opts *opts; 1409 struct config_item *opts_item; 1410 1411 h = kzalloc(sizeof(*h), GFP_KERNEL); 1412 if (!h) 1413 return ERR_PTR(-ENOMEM); 1414 1415 h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; 1416 h->frame.b_frame_index = 1; 1417 h->frame.w_width = 640; 1418 h->frame.w_height = 360; 1419 h->frame.dw_min_bit_rate = 18432000; 1420 h->frame.dw_max_bit_rate = 55296000; 1421 h->frame.dw_max_video_frame_buffer_size = 460800; 1422 h->frame.dw_default_frame_interval = 666666; 1423 1424 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1425 opts = to_f_uvc_opts(opts_item); 1426 1427 mutex_lock(&opts->lock); 1428 fmt = to_uvcg_format(&group->cg_item); 1429 if (fmt->type == UVCG_UNCOMPRESSED) { 1430 h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED; 1431 h->fmt_type = UVCG_UNCOMPRESSED; 1432 } else if (fmt->type == UVCG_MJPEG) { 1433 h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; 1434 h->fmt_type = UVCG_MJPEG; 1435 } else { 1436 mutex_unlock(&opts->lock); 1437 kfree(h); 1438 return ERR_PTR(-EINVAL); 1439 } 1440 ++fmt->num_frames; 1441 mutex_unlock(&opts->lock); 1442 1443 config_item_init_type_name(&h->item, name, &uvcg_frame_type); 1444 1445 return &h->item; 1446} 1447 1448static void uvcg_frame_drop(struct config_group *group, struct config_item *item) 1449{ 1450 struct uvcg_format *fmt; 1451 struct f_uvc_opts *opts; 1452 struct config_item *opts_item; 1453 1454 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1455 opts = to_f_uvc_opts(opts_item); 1456 1457 mutex_lock(&opts->lock); 1458 fmt = to_uvcg_format(&group->cg_item); 1459 --fmt->num_frames; 1460 mutex_unlock(&opts->lock); 1461 1462 config_item_put(item); 1463} 1464 1465static void uvcg_format_set_indices(struct config_group *fmt) 1466{ 1467 struct config_item *ci; 1468 unsigned int i = 1; 1469 1470 list_for_each_entry(ci, &fmt->cg_children, ci_entry) { 1471 struct uvcg_frame *frm; 1472 1473 if (ci->ci_type != &uvcg_frame_type) 1474 continue; 1475 1476 frm = to_uvcg_frame(ci); 1477 frm->frame.b_frame_index = i++; 1478 } 1479} 1480 1481/* ----------------------------------------------------------------------------- 1482 * streaming/uncompressed/<NAME> 1483 */ 1484 1485struct uvcg_uncompressed { 1486 struct uvcg_format fmt; 1487 struct uvc_format_uncompressed desc; 1488}; 1489 1490static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) 1491{ 1492 return container_of( 1493 container_of(to_config_group(item), struct uvcg_format, group), 1494 struct uvcg_uncompressed, fmt); 1495} 1496 1497static struct configfs_group_operations uvcg_uncompressed_group_ops = { 1498 .make_item = uvcg_frame_make, 1499 .drop_item = uvcg_frame_drop, 1500}; 1501 1502static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, 1503 char *page) 1504{ 1505 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1506 struct f_uvc_opts *opts; 1507 struct config_item *opts_item; 1508 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1509 1510 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1511 1512 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1513 opts = to_f_uvc_opts(opts_item); 1514 1515 mutex_lock(&opts->lock); 1516 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 1517 mutex_unlock(&opts->lock); 1518 1519 mutex_unlock(su_mutex); 1520 1521 return sizeof(ch->desc.guidFormat); 1522} 1523 1524static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, 1525 const char *page, size_t len) 1526{ 1527 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1528 struct f_uvc_opts *opts; 1529 struct config_item *opts_item; 1530 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1531 int ret; 1532 1533 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1534 1535 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1536 opts = to_f_uvc_opts(opts_item); 1537 1538 mutex_lock(&opts->lock); 1539 if (ch->fmt.linked || opts->refcnt) { 1540 ret = -EBUSY; 1541 goto end; 1542 } 1543 1544 memcpy(ch->desc.guidFormat, page, 1545 min(sizeof(ch->desc.guidFormat), len)); 1546 ret = sizeof(ch->desc.guidFormat); 1547 1548end: 1549 mutex_unlock(&opts->lock); 1550 mutex_unlock(su_mutex); 1551 return ret; 1552} 1553 1554UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); 1555 1556#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \ 1557static ssize_t uvcg_uncompressed_##cname##_show( \ 1558 struct config_item *item, char *page) \ 1559{ \ 1560 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1561 struct f_uvc_opts *opts; \ 1562 struct config_item *opts_item; \ 1563 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1564 int result; \ 1565 \ 1566 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1567 \ 1568 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1569 opts = to_f_uvc_opts(opts_item); \ 1570 \ 1571 mutex_lock(&opts->lock); \ 1572 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1573 mutex_unlock(&opts->lock); \ 1574 \ 1575 mutex_unlock(su_mutex); \ 1576 return result; \ 1577} \ 1578 \ 1579UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); 1580 1581#define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \ 1582static ssize_t uvcg_uncompressed_##cname##_show( \ 1583 struct config_item *item, char *page) \ 1584{ \ 1585 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1586 struct f_uvc_opts *opts; \ 1587 struct config_item *opts_item; \ 1588 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1589 int result; \ 1590 \ 1591 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1592 \ 1593 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1594 opts = to_f_uvc_opts(opts_item); \ 1595 \ 1596 mutex_lock(&opts->lock); \ 1597 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1598 mutex_unlock(&opts->lock); \ 1599 \ 1600 mutex_unlock(su_mutex); \ 1601 return result; \ 1602} \ 1603 \ 1604static ssize_t \ 1605uvcg_uncompressed_##cname##_store(struct config_item *item, \ 1606 const char *page, size_t len) \ 1607{ \ 1608 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1609 struct f_uvc_opts *opts; \ 1610 struct config_item *opts_item; \ 1611 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1612 int ret; \ 1613 u8 num; \ 1614 \ 1615 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1616 \ 1617 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1618 opts = to_f_uvc_opts(opts_item); \ 1619 \ 1620 mutex_lock(&opts->lock); \ 1621 if (u->fmt.linked || opts->refcnt) { \ 1622 ret = -EBUSY; \ 1623 goto end; \ 1624 } \ 1625 \ 1626 ret = kstrtou8(page, 0, &num); \ 1627 if (ret) \ 1628 goto end; \ 1629 \ 1630 u->desc.aname = num; \ 1631 ret = len; \ 1632end: \ 1633 mutex_unlock(&opts->lock); \ 1634 mutex_unlock(su_mutex); \ 1635 return ret; \ 1636} \ 1637 \ 1638UVC_ATTR(uvcg_uncompressed_, cname, aname); 1639 1640UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, 8); 1641UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8); 1642UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 1643UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 1644UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 1645UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); 1646 1647#undef UVCG_UNCOMPRESSED_ATTR 1648#undef UVCG_UNCOMPRESSED_ATTR_RO 1649 1650static inline ssize_t 1651uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) 1652{ 1653 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1654 return uvcg_format_bma_controls_show(&unc->fmt, page); 1655} 1656 1657static inline ssize_t 1658uvcg_uncompressed_bma_controls_store(struct config_item *item, 1659 const char *page, size_t len) 1660{ 1661 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1662 return uvcg_format_bma_controls_store(&unc->fmt, page, len); 1663} 1664 1665UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); 1666 1667static struct configfs_attribute *uvcg_uncompressed_attrs[] = { 1668 &uvcg_uncompressed_attr_b_format_index, 1669 &uvcg_uncompressed_attr_guid_format, 1670 &uvcg_uncompressed_attr_b_bits_per_pixel, 1671 &uvcg_uncompressed_attr_b_default_frame_index, 1672 &uvcg_uncompressed_attr_b_aspect_ratio_x, 1673 &uvcg_uncompressed_attr_b_aspect_ratio_y, 1674 &uvcg_uncompressed_attr_bm_interface_flags, 1675 &uvcg_uncompressed_attr_bma_controls, 1676 NULL, 1677}; 1678 1679static const struct config_item_type uvcg_uncompressed_type = { 1680 .ct_item_ops = &uvcg_config_item_ops, 1681 .ct_group_ops = &uvcg_uncompressed_group_ops, 1682 .ct_attrs = uvcg_uncompressed_attrs, 1683 .ct_owner = THIS_MODULE, 1684}; 1685 1686static struct config_group *uvcg_uncompressed_make(struct config_group *group, 1687 const char *name) 1688{ 1689 static char guid[] = { 1690 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 1691 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 1692 }; 1693 struct uvcg_uncompressed *h; 1694 1695 h = kzalloc(sizeof(*h), GFP_KERNEL); 1696 if (!h) 1697 return ERR_PTR(-ENOMEM); 1698 1699 h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; 1700 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1701 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 1702 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 1703 h->desc.bBitsPerPixel = 16; 1704 h->desc.bDefaultFrameIndex = 1; 1705 h->desc.bAspectRatioX = 0; 1706 h->desc.bAspectRatioY = 0; 1707 h->desc.bmInterfaceFlags = 0; 1708 h->desc.bCopyProtect = 0; 1709 1710 h->fmt.type = UVCG_UNCOMPRESSED; 1711 config_group_init_type_name(&h->fmt.group, name, 1712 &uvcg_uncompressed_type); 1713 1714 return &h->fmt.group; 1715} 1716 1717static struct configfs_group_operations uvcg_uncompressed_grp_ops = { 1718 .make_group = uvcg_uncompressed_make, 1719}; 1720 1721static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { 1722 .type = { 1723 .ct_item_ops = &uvcg_config_item_ops, 1724 .ct_group_ops = &uvcg_uncompressed_grp_ops, 1725 .ct_owner = THIS_MODULE, 1726 }, 1727 .name = "uncompressed", 1728}; 1729 1730/* ----------------------------------------------------------------------------- 1731 * streaming/mjpeg/<NAME> 1732 */ 1733 1734struct uvcg_mjpeg { 1735 struct uvcg_format fmt; 1736 struct uvc_format_mjpeg desc; 1737}; 1738 1739static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) 1740{ 1741 return container_of( 1742 container_of(to_config_group(item), struct uvcg_format, group), 1743 struct uvcg_mjpeg, fmt); 1744} 1745 1746static struct configfs_group_operations uvcg_mjpeg_group_ops = { 1747 .make_item = uvcg_frame_make, 1748 .drop_item = uvcg_frame_drop, 1749}; 1750 1751#define UVCG_MJPEG_ATTR_RO(cname, aname, bits) \ 1752static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1753{ \ 1754 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1755 struct f_uvc_opts *opts; \ 1756 struct config_item *opts_item; \ 1757 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1758 int result; \ 1759 \ 1760 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1761 \ 1762 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1763 opts = to_f_uvc_opts(opts_item); \ 1764 \ 1765 mutex_lock(&opts->lock); \ 1766 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1767 mutex_unlock(&opts->lock); \ 1768 \ 1769 mutex_unlock(su_mutex); \ 1770 return result; \ 1771} \ 1772 \ 1773UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) 1774 1775#define UVCG_MJPEG_ATTR(cname, aname, bits) \ 1776static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1777{ \ 1778 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1779 struct f_uvc_opts *opts; \ 1780 struct config_item *opts_item; \ 1781 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1782 int result; \ 1783 \ 1784 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1785 \ 1786 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1787 opts = to_f_uvc_opts(opts_item); \ 1788 \ 1789 mutex_lock(&opts->lock); \ 1790 result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ 1791 mutex_unlock(&opts->lock); \ 1792 \ 1793 mutex_unlock(su_mutex); \ 1794 return result; \ 1795} \ 1796 \ 1797static ssize_t \ 1798uvcg_mjpeg_##cname##_store(struct config_item *item, \ 1799 const char *page, size_t len) \ 1800{ \ 1801 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1802 struct f_uvc_opts *opts; \ 1803 struct config_item *opts_item; \ 1804 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1805 int ret; \ 1806 u8 num; \ 1807 \ 1808 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1809 \ 1810 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1811 opts = to_f_uvc_opts(opts_item); \ 1812 \ 1813 mutex_lock(&opts->lock); \ 1814 if (u->fmt.linked || opts->refcnt) { \ 1815 ret = -EBUSY; \ 1816 goto end; \ 1817 } \ 1818 \ 1819 ret = kstrtou8(page, 0, &num); \ 1820 if (ret) \ 1821 goto end; \ 1822 \ 1823 u->desc.aname = num; \ 1824 ret = len; \ 1825end: \ 1826 mutex_unlock(&opts->lock); \ 1827 mutex_unlock(su_mutex); \ 1828 return ret; \ 1829} \ 1830 \ 1831UVC_ATTR(uvcg_mjpeg_, cname, aname) 1832 1833UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, 8); 1834UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); 1835UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8); 1836UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); 1837UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); 1838UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); 1839 1840#undef UVCG_MJPEG_ATTR 1841#undef UVCG_MJPEG_ATTR_RO 1842 1843static inline ssize_t 1844uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) 1845{ 1846 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1847 return uvcg_format_bma_controls_show(&u->fmt, page); 1848} 1849 1850static inline ssize_t 1851uvcg_mjpeg_bma_controls_store(struct config_item *item, 1852 const char *page, size_t len) 1853{ 1854 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1855 return uvcg_format_bma_controls_store(&u->fmt, page, len); 1856} 1857 1858UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); 1859 1860static struct configfs_attribute *uvcg_mjpeg_attrs[] = { 1861 &uvcg_mjpeg_attr_b_format_index, 1862 &uvcg_mjpeg_attr_b_default_frame_index, 1863 &uvcg_mjpeg_attr_bm_flags, 1864 &uvcg_mjpeg_attr_b_aspect_ratio_x, 1865 &uvcg_mjpeg_attr_b_aspect_ratio_y, 1866 &uvcg_mjpeg_attr_bm_interface_flags, 1867 &uvcg_mjpeg_attr_bma_controls, 1868 NULL, 1869}; 1870 1871static const struct config_item_type uvcg_mjpeg_type = { 1872 .ct_item_ops = &uvcg_config_item_ops, 1873 .ct_group_ops = &uvcg_mjpeg_group_ops, 1874 .ct_attrs = uvcg_mjpeg_attrs, 1875 .ct_owner = THIS_MODULE, 1876}; 1877 1878static struct config_group *uvcg_mjpeg_make(struct config_group *group, 1879 const char *name) 1880{ 1881 struct uvcg_mjpeg *h; 1882 1883 h = kzalloc(sizeof(*h), GFP_KERNEL); 1884 if (!h) 1885 return ERR_PTR(-ENOMEM); 1886 1887 h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; 1888 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1889 h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; 1890 h->desc.bDefaultFrameIndex = 1; 1891 h->desc.bAspectRatioX = 0; 1892 h->desc.bAspectRatioY = 0; 1893 h->desc.bmInterfaceFlags = 0; 1894 h->desc.bCopyProtect = 0; 1895 1896 h->fmt.type = UVCG_MJPEG; 1897 config_group_init_type_name(&h->fmt.group, name, 1898 &uvcg_mjpeg_type); 1899 1900 return &h->fmt.group; 1901} 1902 1903static struct configfs_group_operations uvcg_mjpeg_grp_ops = { 1904 .make_group = uvcg_mjpeg_make, 1905}; 1906 1907static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { 1908 .type = { 1909 .ct_item_ops = &uvcg_config_item_ops, 1910 .ct_group_ops = &uvcg_mjpeg_grp_ops, 1911 .ct_owner = THIS_MODULE, 1912 }, 1913 .name = "mjpeg", 1914}; 1915 1916/* ----------------------------------------------------------------------------- 1917 * streaming/color_matching/default 1918 */ 1919 1920#define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, bits) \ 1921static ssize_t uvcg_default_color_matching_##cname##_show( \ 1922 struct config_item *item, char *page) \ 1923{ \ 1924 struct config_group *group = to_config_group(item); \ 1925 struct f_uvc_opts *opts; \ 1926 struct config_item *opts_item; \ 1927 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 1928 struct uvc_color_matching_descriptor *cd; \ 1929 int result; \ 1930 \ 1931 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1932 \ 1933 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 1934 opts = to_f_uvc_opts(opts_item); \ 1935 cd = &opts->uvc_color_matching; \ 1936 \ 1937 mutex_lock(&opts->lock); \ 1938 result = sprintf(page, "%u\n", le##bits##_to_cpu(cd->aname)); \ 1939 mutex_unlock(&opts->lock); \ 1940 \ 1941 mutex_unlock(su_mutex); \ 1942 return result; \ 1943} \ 1944 \ 1945UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname) 1946 1947UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 8); 1948UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics, 1949 bTransferCharacteristics, 8); 1950UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 8); 1951 1952#undef UVCG_DEFAULT_COLOR_MATCHING_ATTR 1953 1954static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { 1955 &uvcg_default_color_matching_attr_b_color_primaries, 1956 &uvcg_default_color_matching_attr_b_transfer_characteristics, 1957 &uvcg_default_color_matching_attr_b_matrix_coefficients, 1958 NULL, 1959}; 1960 1961static const struct uvcg_config_group_type uvcg_default_color_matching_type = { 1962 .type = { 1963 .ct_item_ops = &uvcg_config_item_ops, 1964 .ct_attrs = uvcg_default_color_matching_attrs, 1965 .ct_owner = THIS_MODULE, 1966 }, 1967 .name = "default", 1968}; 1969 1970/* ----------------------------------------------------------------------------- 1971 * streaming/color_matching 1972 */ 1973 1974static const struct uvcg_config_group_type uvcg_color_matching_grp_type = { 1975 .type = { 1976 .ct_item_ops = &uvcg_config_item_ops, 1977 .ct_owner = THIS_MODULE, 1978 }, 1979 .name = "color_matching", 1980 .children = (const struct uvcg_config_group_type*[]) { 1981 &uvcg_default_color_matching_type, 1982 NULL, 1983 }, 1984}; 1985 1986/* ----------------------------------------------------------------------------- 1987 * streaming/class/{fs|hs|ss} 1988 */ 1989 1990struct uvcg_streaming_class_group { 1991 struct config_group group; 1992 const char *name; 1993}; 1994 1995static inline struct uvc_descriptor_header 1996***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) 1997{ 1998 struct uvcg_streaming_class_group *group = 1999 container_of(i, struct uvcg_streaming_class_group, 2000 group.cg_item); 2001 2002 if (!strcmp(group->name, "fs")) 2003 return &o->uvc_fs_streaming_cls; 2004 2005 if (!strcmp(group->name, "hs")) 2006 return &o->uvc_hs_streaming_cls; 2007 2008 if (!strcmp(group->name, "ss")) 2009 return &o->uvc_ss_streaming_cls; 2010 2011 return NULL; 2012} 2013 2014enum uvcg_strm_type { 2015 UVCG_HEADER = 0, 2016 UVCG_FORMAT, 2017 UVCG_FRAME 2018}; 2019 2020/* 2021 * Iterate over a hierarchy of streaming descriptors' config items. 2022 * The items are created by the user with configfs. 2023 * 2024 * It "processes" the header pointed to by @priv1, then for each format 2025 * that follows the header "processes" the format itself and then for 2026 * each frame inside a format "processes" the frame. 2027 * 2028 * As a "processing" function the @fun is used. 2029 * 2030 * __uvcg_iter_strm_cls() is used in two context: first, to calculate 2031 * the amount of memory needed for an array of streaming descriptors 2032 * and second, to actually fill the array. 2033 * 2034 * @h: streaming header pointer 2035 * @priv2: an "inout" parameter (the caller might want to see the changes to it) 2036 * @priv3: an "inout" parameter (the caller might want to see the changes to it) 2037 * @fun: callback function for processing each level of the hierarchy 2038 */ 2039static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, 2040 void *priv2, void *priv3, 2041 int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) 2042{ 2043 struct uvcg_format_ptr *f; 2044 struct config_group *grp; 2045 struct config_item *item; 2046 struct uvcg_frame *frm; 2047 int ret, i, j; 2048 2049 if (!fun) 2050 return -EINVAL; 2051 2052 i = j = 0; 2053 ret = fun(h, priv2, priv3, 0, UVCG_HEADER); 2054 if (ret) 2055 return ret; 2056 list_for_each_entry(f, &h->formats, entry) { 2057 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); 2058 if (ret) 2059 return ret; 2060 grp = &f->fmt->group; 2061 list_for_each_entry(item, &grp->cg_children, ci_entry) { 2062 frm = to_uvcg_frame(item); 2063 ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); 2064 if (ret) 2065 return ret; 2066 } 2067 } 2068 2069 return ret; 2070} 2071 2072/* 2073 * Count how many bytes are needed for an array of streaming descriptors. 2074 * 2075 * @priv1: pointer to a header, format or frame 2076 * @priv2: inout parameter, accumulated size of the array 2077 * @priv3: inout parameter, accumulated number of the array elements 2078 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls 2079 */ 2080static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 2081 enum uvcg_strm_type type) 2082{ 2083 size_t *size = priv2; 2084 size_t *count = priv3; 2085 2086 switch (type) { 2087 case UVCG_HEADER: { 2088 struct uvcg_streaming_header *h = priv1; 2089 2090 *size += sizeof(h->desc); 2091 /* bmaControls */ 2092 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; 2093 } 2094 break; 2095 case UVCG_FORMAT: { 2096 struct uvcg_format *fmt = priv1; 2097 2098 if (fmt->type == UVCG_UNCOMPRESSED) { 2099 struct uvcg_uncompressed *u = 2100 container_of(fmt, struct uvcg_uncompressed, 2101 fmt); 2102 2103 *size += sizeof(u->desc); 2104 } else if (fmt->type == UVCG_MJPEG) { 2105 struct uvcg_mjpeg *m = 2106 container_of(fmt, struct uvcg_mjpeg, fmt); 2107 2108 *size += sizeof(m->desc); 2109 } else { 2110 return -EINVAL; 2111 } 2112 } 2113 break; 2114 case UVCG_FRAME: { 2115 struct uvcg_frame *frm = priv1; 2116 int sz = sizeof(frm->dw_frame_interval); 2117 2118 *size += sizeof(frm->frame); 2119 *size += frm->frame.b_frame_interval_type * sz; 2120 } 2121 break; 2122 } 2123 2124 ++*count; 2125 2126 return 0; 2127} 2128 2129/* 2130 * Fill an array of streaming descriptors. 2131 * 2132 * @priv1: pointer to a header, format or frame 2133 * @priv2: inout parameter, pointer into a block of memory 2134 * @priv3: inout parameter, pointer to a 2-dimensional array 2135 */ 2136static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 2137 enum uvcg_strm_type type) 2138{ 2139 void **dest = priv2; 2140 struct uvc_descriptor_header ***array = priv3; 2141 size_t sz; 2142 2143 **array = *dest; 2144 ++*array; 2145 2146 switch (type) { 2147 case UVCG_HEADER: { 2148 struct uvc_input_header_descriptor *ihdr = *dest; 2149 struct uvcg_streaming_header *h = priv1; 2150 struct uvcg_format_ptr *f; 2151 2152 memcpy(*dest, &h->desc, sizeof(h->desc)); 2153 *dest += sizeof(h->desc); 2154 sz = UVCG_STREAMING_CONTROL_SIZE; 2155 list_for_each_entry(f, &h->formats, entry) { 2156 memcpy(*dest, f->fmt->bmaControls, sz); 2157 *dest += sz; 2158 } 2159 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; 2160 ihdr->bNumFormats = h->num_fmt; 2161 } 2162 break; 2163 case UVCG_FORMAT: { 2164 struct uvcg_format *fmt = priv1; 2165 2166 if (fmt->type == UVCG_UNCOMPRESSED) { 2167 struct uvcg_uncompressed *u = 2168 container_of(fmt, struct uvcg_uncompressed, 2169 fmt); 2170 2171 u->desc.bFormatIndex = n + 1; 2172 u->desc.bNumFrameDescriptors = fmt->num_frames; 2173 memcpy(*dest, &u->desc, sizeof(u->desc)); 2174 *dest += sizeof(u->desc); 2175 } else if (fmt->type == UVCG_MJPEG) { 2176 struct uvcg_mjpeg *m = 2177 container_of(fmt, struct uvcg_mjpeg, fmt); 2178 2179 m->desc.bFormatIndex = n + 1; 2180 m->desc.bNumFrameDescriptors = fmt->num_frames; 2181 memcpy(*dest, &m->desc, sizeof(m->desc)); 2182 *dest += sizeof(m->desc); 2183 } else { 2184 return -EINVAL; 2185 } 2186 } 2187 break; 2188 case UVCG_FRAME: { 2189 struct uvcg_frame *frm = priv1; 2190 struct uvc_descriptor_header *h = *dest; 2191 2192 sz = sizeof(frm->frame); 2193 memcpy(*dest, &frm->frame, sz); 2194 *dest += sz; 2195 sz = frm->frame.b_frame_interval_type * 2196 sizeof(*frm->dw_frame_interval); 2197 memcpy(*dest, frm->dw_frame_interval, sz); 2198 *dest += sz; 2199 if (frm->fmt_type == UVCG_UNCOMPRESSED) 2200 h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( 2201 frm->frame.b_frame_interval_type); 2202 else if (frm->fmt_type == UVCG_MJPEG) 2203 h->bLength = UVC_DT_FRAME_MJPEG_SIZE( 2204 frm->frame.b_frame_interval_type); 2205 } 2206 break; 2207 } 2208 2209 return 0; 2210} 2211 2212static int uvcg_streaming_class_allow_link(struct config_item *src, 2213 struct config_item *target) 2214{ 2215 struct config_item *streaming, *header; 2216 struct f_uvc_opts *opts; 2217 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2218 struct uvc_descriptor_header ***class_array, **cl_arr; 2219 struct uvcg_streaming_header *target_hdr; 2220 void *data, *data_save; 2221 size_t size = 0, count = 0; 2222 int ret = -EINVAL; 2223 2224 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2225 2226 streaming = src->ci_parent->ci_parent; 2227 header = config_group_find_item(to_config_group(streaming), "header"); 2228 if (!header || target->ci_parent != header) 2229 goto out; 2230 2231 opts = to_f_uvc_opts(streaming->ci_parent); 2232 2233 mutex_lock(&opts->lock); 2234 2235 class_array = __uvcg_get_stream_class_arr(src, opts); 2236 if (!class_array || *class_array || opts->refcnt) { 2237 ret = -EBUSY; 2238 goto unlock; 2239 } 2240 2241 target_hdr = to_uvcg_streaming_header(target); 2242 ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); 2243 if (ret) 2244 goto unlock; 2245 2246 count += 2; /* color_matching, NULL */ 2247 *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); 2248 if (!*class_array) { 2249 ret = -ENOMEM; 2250 goto unlock; 2251 } 2252 2253 data = data_save = kzalloc(size, GFP_KERNEL); 2254 if (!data) { 2255 kfree(*class_array); 2256 *class_array = NULL; 2257 ret = -ENOMEM; 2258 goto unlock; 2259 } 2260 cl_arr = *class_array; 2261 ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, 2262 __uvcg_fill_strm); 2263 if (ret) { 2264 kfree(*class_array); 2265 *class_array = NULL; 2266 /* 2267 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() 2268 * might have advanced the "data", so use a backup copy 2269 */ 2270 kfree(data_save); 2271 goto unlock; 2272 } 2273 *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching; 2274 2275 ++target_hdr->linked; 2276 ret = 0; 2277 2278unlock: 2279 mutex_unlock(&opts->lock); 2280out: 2281 config_item_put(header); 2282 mutex_unlock(su_mutex); 2283 return ret; 2284} 2285 2286static void uvcg_streaming_class_drop_link(struct config_item *src, 2287 struct config_item *target) 2288{ 2289 struct config_item *streaming, *header; 2290 struct f_uvc_opts *opts; 2291 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2292 struct uvc_descriptor_header ***class_array; 2293 struct uvcg_streaming_header *target_hdr; 2294 2295 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2296 2297 streaming = src->ci_parent->ci_parent; 2298 header = config_group_find_item(to_config_group(streaming), "header"); 2299 if (!header || target->ci_parent != header) 2300 goto out; 2301 2302 opts = to_f_uvc_opts(streaming->ci_parent); 2303 2304 mutex_lock(&opts->lock); 2305 2306 class_array = __uvcg_get_stream_class_arr(src, opts); 2307 if (!class_array || !*class_array) 2308 goto unlock; 2309 2310 if (opts->refcnt) 2311 goto unlock; 2312 2313 target_hdr = to_uvcg_streaming_header(target); 2314 --target_hdr->linked; 2315 kfree(**class_array); 2316 kfree(*class_array); 2317 *class_array = NULL; 2318 2319unlock: 2320 mutex_unlock(&opts->lock); 2321out: 2322 config_item_put(header); 2323 mutex_unlock(su_mutex); 2324} 2325 2326static struct configfs_item_operations uvcg_streaming_class_item_ops = { 2327 .release = uvcg_config_item_release, 2328 .allow_link = uvcg_streaming_class_allow_link, 2329 .drop_link = uvcg_streaming_class_drop_link, 2330}; 2331 2332static const struct config_item_type uvcg_streaming_class_type = { 2333 .ct_item_ops = &uvcg_streaming_class_item_ops, 2334 .ct_owner = THIS_MODULE, 2335}; 2336 2337/* ----------------------------------------------------------------------------- 2338 * streaming/class 2339 */ 2340 2341static int uvcg_streaming_class_create_children(struct config_group *parent) 2342{ 2343 static const char * const names[] = { "fs", "hs", "ss" }; 2344 unsigned int i; 2345 2346 for (i = 0; i < ARRAY_SIZE(names); ++i) { 2347 struct uvcg_streaming_class_group *group; 2348 2349 group = kzalloc(sizeof(*group), GFP_KERNEL); 2350 if (!group) 2351 return -ENOMEM; 2352 2353 group->name = names[i]; 2354 2355 config_group_init_type_name(&group->group, group->name, 2356 &uvcg_streaming_class_type); 2357 configfs_add_default_group(&group->group, parent); 2358 } 2359 2360 return 0; 2361} 2362 2363static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = { 2364 .type = { 2365 .ct_item_ops = &uvcg_config_item_ops, 2366 .ct_owner = THIS_MODULE, 2367 }, 2368 .name = "class", 2369 .create_children = uvcg_streaming_class_create_children, 2370}; 2371 2372/* ----------------------------------------------------------------------------- 2373 * streaming 2374 */ 2375 2376static ssize_t uvcg_default_streaming_b_interface_number_show( 2377 struct config_item *item, char *page) 2378{ 2379 struct config_group *group = to_config_group(item); 2380 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 2381 struct config_item *opts_item; 2382 struct f_uvc_opts *opts; 2383 int result = 0; 2384 2385 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2386 2387 opts_item = item->ci_parent; 2388 opts = to_f_uvc_opts(opts_item); 2389 2390 mutex_lock(&opts->lock); 2391 result += sprintf(page, "%u\n", opts->streaming_interface); 2392 mutex_unlock(&opts->lock); 2393 2394 mutex_unlock(su_mutex); 2395 2396 return result; 2397} 2398 2399UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber); 2400 2401static struct configfs_attribute *uvcg_default_streaming_attrs[] = { 2402 &uvcg_default_streaming_attr_b_interface_number, 2403 NULL, 2404}; 2405 2406static const struct uvcg_config_group_type uvcg_streaming_grp_type = { 2407 .type = { 2408 .ct_item_ops = &uvcg_config_item_ops, 2409 .ct_attrs = uvcg_default_streaming_attrs, 2410 .ct_owner = THIS_MODULE, 2411 }, 2412 .name = "streaming", 2413 .children = (const struct uvcg_config_group_type*[]) { 2414 &uvcg_streaming_header_grp_type, 2415 &uvcg_uncompressed_grp_type, 2416 &uvcg_mjpeg_grp_type, 2417 &uvcg_color_matching_grp_type, 2418 &uvcg_streaming_class_grp_type, 2419 NULL, 2420 }, 2421}; 2422 2423/* ----------------------------------------------------------------------------- 2424 * UVC function 2425 */ 2426 2427static void uvc_func_item_release(struct config_item *item) 2428{ 2429 struct f_uvc_opts *opts = to_f_uvc_opts(item); 2430 2431 uvcg_config_remove_children(to_config_group(item)); 2432 usb_put_function_instance(&opts->func_inst); 2433} 2434 2435static struct configfs_item_operations uvc_func_item_ops = { 2436 .release = uvc_func_item_release, 2437}; 2438 2439#define UVCG_OPTS_ATTR(cname, aname, limit) \ 2440static ssize_t f_uvc_opts_##cname##_show( \ 2441 struct config_item *item, char *page) \ 2442{ \ 2443 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2444 int result; \ 2445 \ 2446 mutex_lock(&opts->lock); \ 2447 result = sprintf(page, "%u\n", opts->cname); \ 2448 mutex_unlock(&opts->lock); \ 2449 \ 2450 return result; \ 2451} \ 2452 \ 2453static ssize_t \ 2454f_uvc_opts_##cname##_store(struct config_item *item, \ 2455 const char *page, size_t len) \ 2456{ \ 2457 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2458 unsigned int num; \ 2459 int ret; \ 2460 \ 2461 mutex_lock(&opts->lock); \ 2462 if (opts->refcnt) { \ 2463 ret = -EBUSY; \ 2464 goto end; \ 2465 } \ 2466 \ 2467 ret = kstrtouint(page, 0, &num); \ 2468 if (ret) \ 2469 goto end; \ 2470 \ 2471 if (num > limit) { \ 2472 ret = -EINVAL; \ 2473 goto end; \ 2474 } \ 2475 opts->cname = num; \ 2476 ret = len; \ 2477end: \ 2478 mutex_unlock(&opts->lock); \ 2479 return ret; \ 2480} \ 2481 \ 2482UVC_ATTR(f_uvc_opts_, cname, cname) 2483 2484UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16); 2485UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072); 2486UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); 2487 2488#undef UVCG_OPTS_ATTR 2489 2490static struct configfs_attribute *uvc_attrs[] = { 2491 &f_uvc_opts_attr_streaming_interval, 2492 &f_uvc_opts_attr_streaming_maxpacket, 2493 &f_uvc_opts_attr_streaming_maxburst, 2494 NULL, 2495}; 2496 2497static const struct uvcg_config_group_type uvc_func_type = { 2498 .type = { 2499 .ct_item_ops = &uvc_func_item_ops, 2500 .ct_attrs = uvc_attrs, 2501 .ct_owner = THIS_MODULE, 2502 }, 2503 .name = "", 2504 .children = (const struct uvcg_config_group_type*[]) { 2505 &uvcg_control_grp_type, 2506 &uvcg_streaming_grp_type, 2507 NULL, 2508 }, 2509}; 2510 2511int uvcg_attach_configfs(struct f_uvc_opts *opts) 2512{ 2513 int ret; 2514 2515 config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name, 2516 &uvc_func_type.type); 2517 2518 ret = uvcg_config_create_children(&opts->func_inst.group, 2519 &uvc_func_type); 2520 if (ret < 0) 2521 config_group_put(&opts->func_inst.group); 2522 2523 return ret; 2524} 2525