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