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