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