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