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