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