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