1/* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. 3 * Description: LiteOS USB Driver Config Data Stream 4 * Author: Yannik Li 5 * Create: 2021-02-21 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28/* ---------------------------------------------------------------------------- 29 * Notice of Export Control Law 30 * =============================================== 31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34 * applicable export control laws and regulations. 35 * --------------------------------------------------------------------------- */ 36 37#include <poll.h> 38#include "implementation/global_implementation.h" 39#include "gadget/composite.h" 40#include "f_common.h" 41#include "devsvc_manager_clnt.h" 42#include "hdf_device_desc.h" 43 44#ifdef __cplusplus 45#if __cplusplus 46//extern "C" { 47#endif /* __cplusplus */ 48#endif /* __cplusplus */ 49 50struct func_info { 51 uint8_t ndevices; 52 int ifnobase; 53 int strbase; 54 struct composite_devdesc_s *devs; 55}; 56 57extern void usbdev_generic_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 58extern void usbdev_cdcacm_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 59extern void usbdev_rndis_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 60extern void usbdev_mass_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 61extern void usbdev_uac_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 62extern void usbdev_uvc_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor); 63extern int gadget_strings_match(struct usb_obj *obj, void *match_data); 64 65struct usbdev_info g_generic_usbdev_info = 66{ 67 "generic", DEV_GENERIC, 0, usbdev_generic_initialize_sub 68}; 69 70struct usbdev_info *g_fconfig_usbdev_info[] = 71{ 72 &g_generic_usbdev_info, 73 NULL, 74}; 75 76static struct usbdev_info *fconfig_find_usbdev_info(char *name) 77{ 78 struct usbdev_info **dev_info = g_fconfig_usbdev_info; 79 int i; 80 81 for (i = 0; dev_info[i] != NULL; i++) 82 { 83 if (strcmp(dev_info[i]->name, name) == 0) 84 { 85 return dev_info[i]; 86 } 87 } 88 89 return NULL; 90} 91 92static char *fconfig_get_string(struct usb_obj *obj, struct fconfig_string *str) 93{ 94 size_t size = str->len; 95 char *buf = NULL; 96 int ret; 97 buf = (char *)usbm_malloc(obj, (size + 1)); 98 if (buf == NULL) 99 { 100 usb_err("%s: malloc name buffer failed\n", __FUNCTION__); 101 return NULL; 102 } 103 memset_s(buf, size, 0, size); 104 105 ret = memcpy_s((void *)buf, (size + 1), (void *)str->s, size); 106 if (ret != EOK) 107 { 108 usb_err("%s: copy string from user failed\n", __FUNCTION__); 109 usbm_free(obj, buf); 110 return NULL; 111 } 112 *(buf + str->len) = '\0'; 113 return buf; 114} 115 116static int gadget_match(struct usb_obj *obj, void *match_data) 117{ 118 struct gadget_info *gi = container_of(obj, struct gadget_info, obj); 119 return !strcmp(gi->name, (char *)match_data); 120} 121 122static struct gadget_info *gadget_find_by_name(struct fconfig_softc *cdev, 123 struct fconfig_string *name) 124{ 125 struct gadget_info *gi = NULL; 126 struct usb_obj *obj = NULL; 127 char *gadget_name = NULL; 128 129 gadget_name = fconfig_get_string(&cdev->obj, name); 130 if (gadget_name == NULL) 131 { 132 usb_err("%s: get gadget name failed\n", __FUNCTION__); 133 return NULL; 134 } 135 136 obj = usbobj_find(&cdev->obj, gadget_match, (void *)gadget_name); 137 if (obj) 138 { 139 gi = container_of(obj, struct gadget_info, obj); 140 } 141 142 usbm_free(&cdev->obj, gadget_name); 143 return gi; 144} 145 146static int gadget_make(struct fconfig_softc *cdev, char *name) 147{ 148 struct gadget_info *gi = NULL; 149 unsigned long flags; 150 151 spin_lock_irqsave(&cdev->obj.lock, flags); 152 if (!list_empty(&cdev->obj.children)) 153 { 154 usb_err("%s, %d: gadget had make\n", __FUNCTION__, __LINE__); 155 spin_unlock_irqrestore(&cdev->obj.lock, flags); 156 return -1; 157 } 158 spin_unlock_irqrestore(&cdev->obj.lock, flags); 159 160 gi = usbm_malloc(&cdev->obj, sizeof(*gi)); 161 if (gi == NULL) 162 { 163 usb_err("%s: malloc gadget failed\n", __FUNCTION__); 164 return -1; 165 } 166 167 memset_s(gi, sizeof(*gi), 0, sizeof(*gi)); 168 usbobj_init(&gi->obj, name, usbobj_default_release); 169 usbobj_init(&gi->strings, "strings", usbobj_default_release); 170 gi->name = name; 171 gi->cdev = cdev; 172 gi->com_s = cdev->com_s; 173 usbobj_add(&gi->obj, &cdev->obj); 174 return 0; 175} 176 177static int gadget_drop(struct fconfig_softc *cdev, struct fconfig_string *name) 178{ 179 struct gadget_info *gi = NULL; 180 181 gi = gadget_find_by_name(cdev, name); 182 if (gi == NULL) 183 { 184 usb_err("%s: can not find gadget\n", __FUNCTION__); 185 return -1; 186 } 187 188 usbm_free(&cdev->obj, (void *)gi->name); 189 usbobj_put(&gi->strings); 190 usbobj_put(&gi->obj); 191 usbm_free(&cdev->obj, gi); 192 return 0; 193} 194 195static int fconfig_make_gadget(struct fconfig_softc *cdev, void *user_data) 196{ 197 struct fconfig_string str; 198 char *name = NULL; 199 int ret; 200 201 ret = memcpy_s(&str, sizeof(str), user_data, sizeof(str)); 202 if (ret != EOK) 203 { 204 return -1; 205 } 206 207 name = fconfig_get_string(&cdev->obj, &str); 208 if (name == NULL) 209 { 210 usb_err("%s: get gadget name failed\n", __FUNCTION__); 211 return -1; 212 } 213 214 return gadget_make(cdev, name); 215} 216 217static int fconfig_drop_gadget(struct fconfig_softc *cdev, void *user_data) 218{ 219 struct fconfig_string str; 220 int ret; 221 222 ret = memcpy_s(&str, sizeof(str), user_data, sizeof(str)); 223 if (ret != EOK) 224 { 225 return -1; 226 } 227 228 return gadget_drop(cdev, &str); 229} 230 231static int fconfig_write_dev_desc(struct fconfig_softc *cdev, void *user_data) 232{ 233 struct gadget_info *gi = NULL; 234 struct fconfig_dev_desc desc; 235 struct usb_device_descriptor *dev_desc = NULL; 236 int ret; 237 238 ret = memcpy_s(&desc, sizeof(desc), user_data, sizeof(desc)); 239 if (ret != EOK) 240 { 241 return -1; 242 } 243 244 gi = gadget_find_by_name(cdev, &desc.gadget_name); 245 if (gi == NULL) 246 { 247 usb_err("%s: can not find the gadget\n", __FUNCTION__); 248 return -1; 249 } 250 251 dev_desc = (struct usb_device_descriptor *)usbm_malloc(&gi->obj, sizeof(*dev_desc)); 252 if (dev_desc == NULL) 253 { 254 usb_err("%s: malloc device descriptor failed\n", __FUNCTION__); 255 goto err; 256 } 257 258 ret = memcpy_s(dev_desc, sizeof(*dev_desc), &desc.dev_desc, sizeof(*dev_desc)); 259 if (ret != EOK) 260 { 261 goto err; 262 } 263 264 gi->dev_desc = dev_desc; 265 return 0; 266 267err: 268 usbm_free(&gi->obj, dev_desc); 269 return -1; 270} 271 272static struct gadget_config *fconfig_alloc_gadget_cfg(struct gadget_info *gi, char *cfg_name, 273 struct usb_config_descriptor *cfg_desc) 274{ 275 struct gadget_config *cfg = NULL; 276 277 cfg = (struct gadget_config *)usbm_malloc(&gi->obj, sizeof(*cfg)); 278 if (cfg == NULL) 279 { 280 usb_err("%s: malloc usb cfg failed\n", __FUNCTION__); 281 return NULL; 282 } 283 memset_s(cfg, sizeof(*cfg), 0, sizeof(*cfg)); 284 usbobj_init(&cfg->obj, cfg_name, usbobj_default_release); 285 286 cfg->gi = gi; 287 cfg->name = cfg_name; 288 cfg->cfg_desc = cfg_desc; 289 cfg->cfg_num = cfg_desc->bConfigurationValue; 290 291 return cfg; 292} 293 294static int fconfig_add_gadget_cfg(struct fconfig_softc *cdev, void *user_data) 295{ 296 struct usb_config_descriptor *cfg_desc = NULL; 297 struct fconfig_cfg_desc desc; 298 struct gadget_config *cfg = NULL; 299 struct gadget_info *gi = NULL; 300 struct usb_obj *obj = NULL; 301 char *cfg_name = NULL; 302 int ret; 303 304 ret = memcpy_s(&desc, sizeof(desc), user_data, sizeof(desc)); 305 if (ret != EOK) 306 { 307 return -1; 308 } 309 310 gi = gadget_find_by_name(cdev, &desc.gadget_name); 311 if (gi == NULL) 312 { 313 usb_err("%s: can't find the gadget\n", __FUNCTION__); 314 goto err; 315 } 316 317 cfg_name = fconfig_get_string(&gi->obj, &desc.config_name); 318 if (cfg_name == NULL) 319 { 320 usb_err("%s: get config name failed\n", __FUNCTION__); 321 goto err; 322 } 323 324 obj = usbobj_find(&gi->obj, usbobj_default_match, cfg_name); 325 if (obj) 326 { 327 usb_err("%s: the config %s has been existed\n", 328 __FUNCTION__, cfg_name); 329 goto err; 330 } 331 332 cfg_desc = (struct usb_config_descriptor *)usbm_malloc(&gi->obj, sizeof(*cfg_desc)); 333 if (cfg_desc == NULL) 334 { 335 usb_err("%s: malloc config descriptor failed\n", __FUNCTION__); 336 goto err; 337 } 338 339 ret = memcpy_s(cfg_desc, sizeof(*cfg_desc), &desc.cfg_desc, sizeof(*cfg_desc)); 340 if (ret != EOK) 341 { 342 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 343 goto err; 344 } 345 cfg_desc->bLength = USB_CONFIG_DESC_SIZE; 346 cfg_desc->bDescriptorType = UDESC_CONFIG; 347 cfg = fconfig_alloc_gadget_cfg(gi, cfg_name, cfg_desc); 348 if (cfg == NULL) 349 { 350 usb_err("%s: alloc usb cfg failed\n", __FUNCTION__); 351 goto err; 352 } 353 usbobj_add(&cfg->obj, &gi->obj); 354 return 0; 355 356err: 357 usbm_free(&gi->obj, cfg_desc); 358 usbm_free(&gi->obj, cfg_name); 359 return -1; 360} 361 362static int fconfig_remove_gadget_cfg(struct fconfig_softc *cdev, void *user_data) 363{ 364 struct fconfig_cfg_desc desc; 365 struct gadget_info *gi = NULL; 366 struct gadget_config *cfg = NULL; 367 struct usb_obj *obj = NULL; 368 char *config_name = NULL; 369 int ret; 370 371 ret = memcpy_s(&desc, sizeof(desc), (void *)user_data, sizeof(desc)); 372 if (ret != EOK) 373 { 374 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 375 return -1; 376 } 377 378 gi = gadget_find_by_name(cdev, &desc.gadget_name); 379 if (gi == NULL) 380 { 381 usb_err("%s: can't find the gadget\n", __FUNCTION__); 382 goto err; 383 } 384 385 config_name = fconfig_get_string(&gi->obj, &desc.config_name); 386 if (config_name == NULL) 387 { 388 usb_err("%s: get config name failed\n", __FUNCTION__); 389 goto err; 390 } 391 392 obj = usbobj_find(&gi->obj, usbobj_default_match, config_name); 393 if (!obj) 394 { 395 usb_err("%s: can't find the config %s\n", __FUNCTION__, config_name); 396 goto err; 397 } 398 cfg = container_of(obj, struct gadget_config, obj); 399 usbobj_put(&cfg->obj); 400 401 usbm_free(&gi->obj, cfg->name); 402 usbm_free(&gi->obj, cfg->cfg_desc); 403 return 0; 404 405err: 406 usbm_free(&gi->obj, config_name); 407 return -1; 408} 409 410static int fconfig_fill_strings(struct gadget_info *gi, 411 struct fconfig_dev_strings *str_data) 412{ 413 struct fconfig_usb_string *strings = NULL; 414 struct gadget_strings *dev_strings = NULL; 415 uint32_t size; 416 int i; 417 int ret; 418 419 size = sizeof(*dev_strings); 420 dev_strings = (struct gadget_strings *)usbm_malloc(&gi->obj, size); 421 if (dev_strings == NULL) 422 { 423 usb_err("%s: malloc strings failed\n", __FUNCTION__); 424 return -1; 425 } 426 memset_s(dev_strings, size, 0, size); 427 size = sizeof(struct usbd_string) * (str_data->str_count + 1); 428 dev_strings->strings = usbm_malloc(&gi->obj, size); 429 if (dev_strings == NULL) 430 { 431 usb_err("%s: malloc strings failed\n", __FUNCTION__); 432 return -1; 433 } 434 435 usbobj_init(&dev_strings->obj, "dev_strings", usbobj_default_release); 436 size = sizeof(*strings) * str_data->str_count; 437 strings = (struct fconfig_usb_string *)usbm_malloc(&dev_strings->obj, size); 438 if (strings == NULL) 439 { 440 usb_err("%s: malloc config usb strings failed\n", __FUNCTION__); 441 goto err; 442 } 443 ret = memcpy_s(strings, size, (void *)str_data->strings, size); 444 if (ret != EOK) 445 { 446 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 447 goto err; 448 } 449 for (i = 0; i < str_data->str_count; i++) 450 { 451 char *str = fconfig_get_string(&dev_strings->obj, &strings[i].str); 452 if (str == NULL) 453 { 454 usb_err("%s: get string failed\n", __FUNCTION__); 455 goto err; 456 } 457 dev_strings->strings[i].id = strings[i].id + 1; 458 dev_strings->strings[i].s = str; 459 } 460 dev_strings->strings[i].id = 0; 461 dev_strings->strings[i].s = NULL; 462 dev_strings->language = str_data->language; 463 464 usbm_free(&dev_strings->obj, strings); 465 usbobj_add(&dev_strings->obj, &gi->strings); 466 return 0; 467 468err: 469 usbobj_put(&dev_strings->obj); 470 return -1; 471} 472 473static int fconfig_write_strings(struct fconfig_softc *cdev, void *user_data) 474{ 475 struct gadget_info *gi = NULL; 476 struct fconfig_dev_strings str_data; 477 int ret; 478 479 ret = memcpy_s(&str_data, sizeof(str_data), (void *)user_data, sizeof(str_data)); 480 if (ret != EOK) 481 { 482 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 483 return -1; 484 } 485 486 gi = gadget_find_by_name(cdev, &str_data.gadget_name); 487 if (gi == NULL) 488 { 489 usb_err("%s: can't find the gadget\n", __FUNCTION__); 490 return -1; 491 } 492 493 /* set the string count for first time */ 494 if (!gi->str_count) 495 { 496 gi->str_count = str_data.str_count + 1; 497 } 498 else if (gi->str_count != (str_data.str_count + 1)) 499 { 500 usb_err("%s: str_count %u is not equeal to %u\n", 501 __FUNCTION__, str_data.str_count, gi->str_count); 502 return -1; 503 } 504 return fconfig_fill_strings(gi, &str_data); 505} 506 507void function_instance_release(struct usb_obj *obj) 508{ 509 int ret; 510 struct function_instance *func_inst = container_of(obj, struct function_instance, obj); 511 512 if (func_inst->minor >= DEV_GENERIC) 513 { 514 ret = usbdev_generic_free_instance(func_inst->name); 515 if (ret != 0) 516 { 517 usb_err("%s: free generic_func_inst %s failed\n", __func__, func_inst->name); 518 } 519 } 520 usbm_free(obj->parent, func_inst); 521} 522 523static int fconfig_do_make_function(struct gadget_config *cfg, char *func_name) 524{ 525 struct function_instance *func_inst = NULL; 526 struct usbdev_info *dev_info = NULL; 527 char *instance_name = NULL; 528 char *obj_name = NULL; 529 530 /* split the whole name into function name and instance name */ 531 instance_name = strchr(func_name, '.'); 532 if (instance_name == NULL) 533 { 534 usb_err("%s: unable to locate . in %s\n", __FUNCTION__, func_name); 535 return -1; 536 } 537 *instance_name = '\0'; 538 instance_name++; 539 540 func_inst = usbm_malloc(&cfg->obj, sizeof(*func_inst)); 541 if (func_inst == NULL) 542 { 543 usb_err("%s: malloc function instance failed\n", __FUNCTION__); 544 return -1; 545 } 546 memset_s(func_inst, sizeof(*func_inst), 0, sizeof(*func_inst)); 547 usbobj_init(&func_inst->obj, "", function_instance_release); 548 549 dev_info = fconfig_find_usbdev_info(func_name); 550 if (dev_info == NULL) 551 { 552 usb_err("%s: can not find dev_info\n", __FUNCTION__); 553 goto err; 554 } 555 obj_name = usbm_strdup(&func_inst->obj, instance_name); 556 func_inst->dev_info = dev_info; 557 func_inst->name = obj_name; 558 func_inst->obj.name = obj_name; 559 usbobj_add(&func_inst->obj, &cfg->obj); 560 dprintf("%s, func_inst->obj->name = %s\n", __func__, func_inst->obj.name); 561 if (dev_info->type != DEV_GENERIC) 562 { 563 /*for normal kernel driver */ 564 func_inst->minor = dev_info->type; 565 } 566 else 567 { 568 /* for generic device */ 569 int ret = usbdev_generic_alloc_instance(func_inst->name); 570 if (ret < DEV_GENERIC) 571 { 572 goto err; 573 } 574 func_inst->minor = ret; 575 } 576 577 return 0; 578 579err: 580 usbobj_put(&func_inst->obj); 581 return -1; 582} 583 584static int fconfig_do_drop_function(struct gadget_config *cfg, char *func_name) 585{ 586 struct usb_obj *obj = NULL; 587 char *instance_name = NULL; 588 589 /* split the whole name into function name and instance name */ 590 instance_name = strchr(func_name, '.'); 591 if (instance_name == NULL) 592 { 593 usb_err("unable to locate . in %s\n", func_name); 594 return -1; 595 } 596 *instance_name = '\0'; 597 instance_name++; 598 599 obj = usbobj_find(&cfg->obj, usbobj_default_match, instance_name); 600 if (!obj) 601 { 602 dprintf("%s, usbobj_find %s obj failed\n", __func__, instance_name); 603 return -1; 604 } 605 606 usbobj_put(obj); 607 return 0; 608} 609 610static int fconfig_get_function_info(struct fconfig_softc *cdev, void *user_data, 611 char **name, struct gadget_config **usb_cfg) 612{ 613 struct fconfig_func_info func_info; 614 struct gadget_config *cfg = NULL; 615 struct gadget_info *gi = NULL; 616 struct usb_obj *obj = NULL; 617 char *config_name = NULL; 618 char *func_name = NULL; 619 int ret; 620 621 ret = memcpy_s(&func_info, sizeof(func_info), (void *)user_data, sizeof(func_info)); 622 if (ret != EOK) 623 { 624 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 625 return -1; 626 } 627 628 gi = gadget_find_by_name(cdev, &func_info.gadget_name); 629 if (gi == NULL) 630 { 631 usb_err("%s: can't find the gadget\n", __FUNCTION__); 632 goto err; 633 } 634 635 config_name = fconfig_get_string(&gi->obj, &func_info.config_name); 636 if (config_name == NULL) 637 { 638 usb_err("%s: get config name failed\n", __FUNCTION__); 639 goto err; 640 } 641 642 /* find config from gadget object by the name */ 643 obj = usbobj_find(&gi->obj, usbobj_default_match, config_name); 644 if (!obj) 645 { 646 usb_err("%s: can't find the config %s\n", __FUNCTION__, config_name); 647 goto err; 648 } 649 cfg = container_of(obj, struct gadget_config, obj); 650 651 func_name = fconfig_get_string(obj, &func_info.func_name); 652 if (func_name == NULL) 653 { 654 usb_err("%s: get func name failed\n", __FUNCTION__); 655 goto err2; 656 } 657 658 *name = func_name; 659 *usb_cfg = cfg; 660 usbm_free(&gi->obj, config_name); 661 return 0; 662 663err2: 664 usbm_free(&cfg->obj, func_name); 665err: 666 usbm_free(&gi->obj, config_name); 667 return -1; 668} 669 670static int fconfig_make_function(struct fconfig_softc *cdev, void *user_data) 671{ 672 struct gadget_config *cfg = NULL; 673 char *func_name = NULL; 674 int ret; 675 676 ret = fconfig_get_function_info(cdev, user_data, &func_name, &cfg); 677 if (ret != 0) 678 { 679 usb_err("%s: get function info failed\n", __FUNCTION__); 680 return -1; 681 } 682 683 ret = fconfig_do_make_function(cfg, func_name); 684 if (ret != 0) 685 { 686 usb_err("%s: make function failed\n", __FUNCTION__); 687 } 688 usbm_free(&cfg->obj, func_name); 689 690 return ret; 691} 692 693static int fconfig_drop_function(struct fconfig_softc *cdev, void *user_data) 694{ 695 struct gadget_config *cfg = NULL; 696 char *func_name = NULL; 697 int ret; 698 699 ret = fconfig_get_function_info(cdev, user_data, &func_name, &cfg); 700 if (ret != 0) 701 { 702 usb_err("%s: get function info failed\n", __FUNCTION__); 703 return -1; 704 } 705 706 ret = fconfig_do_drop_function(cfg, func_name); 707 if (ret != 0) 708 { 709 usb_err("%s: make function failed\n", __FUNCTION__); 710 } 711 712 usbm_free(&cfg->obj, func_name); 713 return ret; 714} 715 716static int usb_config_match(struct usb_obj *obj, void *match_data) 717{ 718 struct gadget_config *cfg = container_of(obj, struct gadget_config, obj); 719 uint8_t config_num = *(uint8_t *)match_data; 720 721 return (cfg->cfg_num == config_num); 722} 723 724static void func_inst_init(struct usb_obj *obj, void *data) 725{ 726 struct function_instance *func = container_of(obj, struct function_instance, obj); 727 struct func_info * info = (struct func_info *)data; 728 struct usbdev_info *dev_info = NULL; 729 730 if (func == NULL || func->dev_info == NULL) 731 { 732 usb_err("%s: get function_instance failed\n", __FUNCTION__); 733 return; 734 } 735 dev_info = func->dev_info; 736 737 if (dev_info->type == DEV_GENERIC) 738 { 739 dev_info->initialize_sub(&info->devs[info->ndevices], info->ifnobase, func->minor); 740 info->devs[info->ndevices].devinfo.strbase = info->strbase; 741 info->ifnobase += info->devs[info->ndevices].devinfo.ninterfaces; 742 info->strbase += info->devs[info->ndevices].devinfo.nstrings; 743 } 744 else 745 { 746 dev_info->initialize_sub(&info->devs[info->ndevices], info->ifnobase, dev_info->type); 747 info->ifnobase += dev_info->ifnum; 748 } 749 info->ndevices++; 750} 751 752static int fconfig_composite_initialize(struct gadget_info *gi, 753 struct composite_softc *com_s) 754{ 755 struct composite_devdesc_s devs[NUM_DEVICES_TO_HANDLE]; 756 struct func_info info; 757 uint8_t config_num = 1; 758 struct usb_obj *obj = NULL; 759 struct gadget_config *cfg = NULL; 760 761 if (com_s) 762 { 763 config_num = com_s->dev.config; 764 } 765 info.devs = devs; 766 info.ndevices = 0; 767 info.ifnobase = 0; 768 info.strbase = 0; 769 config_num = 1; 770 obj = usbobj_find(&gi->obj, usb_config_match, &config_num); 771 if (!obj) 772 { 773 usb_err("%s: can't find the configNumber %d\n", __FUNCTION__, config_num); 774 return -1; 775 } 776 cfg = container_of(obj, struct gadget_config, obj); 777 usbobj_for_each_child(&cfg->obj, NULL, NULL, func_inst_init, &info); 778 779 return fconfig_do_composite_initialize(com_s, info.ndevices, devs); 780} 781 782static int fconfig_enable_udc(struct fconfig_softc *cdev, void *user_data) 783{ 784 struct composite_softc *com_s = cdev->com_s; 785 struct fconfig_udc_info udc_info; 786 struct gadget_info *gi = NULL; 787 char *udc_name = NULL; 788 int ret; 789 790 ret = memcpy_s(&udc_info, sizeof(udc_info), (void *)user_data, sizeof(udc_info)); 791 if (ret != EOK) 792 { 793 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 794 return -1; 795 } 796 797 gi = gadget_find_by_name(cdev, &udc_info.gadget_name); 798 if (gi == NULL) 799 { 800 usb_err("%s: can't find the gadget\n", __FUNCTION__); 801 goto err; 802 } 803 804 udc_name = fconfig_get_string(&gi->obj, &udc_info.udc_name); 805 if (udc_name == NULL) 806 { 807 usb_err("%s: get udc name failed\n", __FUNCTION__); 808 goto err; 809 } 810 811 gi->udc_name = udc_name; 812 ret = fconfig_composite_initialize(gi, com_s); 813 if (ret) 814 { 815 usb_err("%s: fcofnig composite init failed\n", __FUNCTION__); 816 goto err; 817 } 818 usbd_start_udc(); 819 ret = usbd_gadget_attach_driver(com_s->parnet_conext, &com_s->drvr.drvr); 820 if (ret < 0) 821 { 822 usb_err("%s, usbd_gadget_attach_driver fail\n", __func__); 823 goto err; 824 } 825 826 return 0; 827 828err: 829 usbm_free(&gi->obj, udc_name); 830 return -1; 831} 832 833static int fconfig_disable_udc(struct fconfig_softc *cdev, void *user_data) 834{ 835 struct gadget_info *gi = NULL; 836 struct fconfig_udc_info udc_info; 837 int ret; 838 839 ret = memcpy_s(&udc_info, sizeof(udc_info), (void *)user_data, sizeof(udc_info)); 840 if (ret != EOK) 841 { 842 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 843 return -1; 844 } 845 846 gi = gadget_find_by_name(cdev, &udc_info.gadget_name); 847 if (gi == NULL) 848 { 849 usb_err("%s: can't find the gadget\n", __FUNCTION__); 850 goto err; 851 } 852 853 /* disable UDC */ 854 usbd_stop_udc(); 855 usbm_free(&gi->obj, gi->udc_name); 856 gi->udc_name = NULL; 857 return 0; 858 859err: 860 return -1; 861} 862 863static int change_dev_descritor_info(struct gadget_info *gi, 864 struct fconfig_dev_desc_info *desc_info) 865{ 866 const char *name = NULL; 867 868 if (desc_info == NULL || gi == NULL) 869 { 870 usb_err("%s: param invail\n", __FUNCTION__); 871 return -1; 872 } 873 name = desc_info->prop.prop_name; 874 if (strcmp(USBDEV_VENDOR, name) == 0) 875 { 876 gi->dev_desc->idVendor[0] = (uint8_t)desc_info->prop.prop_value; 877 gi->dev_desc->idVendor[1] = (uint8_t)(desc_info->prop.prop_value >> 8); 878 } 879 else if (strcmp(USBDEV_IDPRODUCT, name) == 0) 880 { 881 gi->dev_desc->idProduct[0] = (uint8_t)desc_info->prop.prop_value; 882 gi->dev_desc->idProduct[1] = (uint8_t)(desc_info->prop.prop_value >> 8); 883 } 884 else if (strcmp(USBDEV_CLASS, name) == 0) 885 { 886 gi->dev_desc->bDeviceClass = (uint8_t)desc_info->prop.prop_value; 887 } 888 else if (strcmp(USBDEV_SUBCLASS, name) == 0) 889 { 890 gi->dev_desc->bDeviceSubClass = (uint8_t)desc_info->prop.prop_value; 891 } 892 else if (strcmp(USBDEV_PROTOCOL, name) == 0) 893 { 894 gi->dev_desc->bDeviceProtocol = (uint8_t)desc_info->prop.prop_value; 895 } 896 else if (strcmp(USBDEV_MAXSIZE, name) == 0) 897 { 898 gi->dev_desc->bMaxPacketSize = (uint8_t)desc_info->prop.prop_value; 899 } 900 else if (strcmp(USBDEV_NUMCFG, name) == 0) 901 { 902 gi->dev_desc->bNumConfigurations = (uint8_t)desc_info->prop.prop_value; 903 } 904 else if (strcmp(USBDEV_BCD, name) == 0) 905 { 906 gi->dev_desc->bcdUSB[0] = (uint8_t)desc_info->prop.prop_value; 907 gi->dev_desc->bcdUSB[1] = (uint8_t)(desc_info->prop.prop_value >> 8); 908 } 909 else if (strcmp(USBDEV_BCDDEVICE, name) == 0) 910 { 911 gi->dev_desc->bcdDevice[0] = (uint8_t)desc_info->prop.prop_value; 912 gi->dev_desc->bcdDevice[1] = (uint8_t)(desc_info->prop.prop_value >> 8); 913 } 914 else 915 { 916 usb_err("%{public}s: other prop", __func__); 917 return -1; 918 } 919 return 0; 920} 921 922static int fconfig_change_dev_desc_info(struct fconfig_softc *cdev, void *user_data) 923{ 924 struct gadget_info *gi = NULL; 925 struct fconfig_dev_desc_info desc_info; 926 int ret; 927 928 ret = memcpy_s(&desc_info, sizeof(desc_info), (void *)user_data, sizeof(desc_info)); 929 if (ret != EOK) 930 { 931 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 932 return -1; 933 } 934 935 gi = gadget_find_by_name(cdev, &desc_info.gadget_name); 936 if (gi == NULL) 937 { 938 usb_err("%s: can't find the gadget\n", __FUNCTION__); 939 return -1; 940 } 941 if (gi->dev_desc == NULL) 942 { 943 usb_err("%s: dev_desc is null\n", __FUNCTION__); 944 return -1; 945 } 946 ret = change_dev_descritor_info(gi, &desc_info); 947 if (ret != EOK) 948 { 949 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 950 return -1; 951 } 952 return 0; 953} 954 955static int change_dev_descritor_string(struct gadget_info *gi, 956 struct fconfig_dev_desc_string *desc_string, 957 struct gadget_strings *dev_strings) 958{ 959 uint8_t id = 0xff; 960 int i; 961 const char *name = NULL; 962 963 if (desc_string == NULL || gi == NULL || dev_strings == NULL) 964 { 965 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 966 return -1; 967 } 968 for (i = 0; dev_strings->strings[i].s != NULL; i++) 969 { 970 const char *str = dev_strings->strings[i].s; 971 if (strcmp(str, desc_string->prop.prop_value) == 0) 972 { 973 id = dev_strings->strings[i].id; 974 break; 975 } 976 } 977 if (id == 0xff) 978 { 979 usb_err("%s: not found ringht string ID\n", __FUNCTION__); 980 return -1; 981 } 982 name = desc_string->prop.prop_name; 983 if (strcmp(USBDEV_MANUFACTURER, name) == 0) 984 { 985 gi->dev_desc->iManufacturer = id; 986 } 987 else if (strcmp(USBDEV_PRODUCT, name) == 0) 988 { 989 gi->dev_desc->iProduct = id; 990 } 991 else if (strcmp(USBDEV_SERIALNUM, name) == 0) 992 { 993 gi->dev_desc->iSerialNumber = id; 994 } 995 else 996 { 997 usb_err("%{public}s: other prop", __func__); 998 return -1; 999 } 1000 return 0; 1001} 1002 1003static int fconfig_change_dev_desc_string(struct fconfig_softc *cdev, void *user_data) 1004{ 1005 struct usb_obj *obj = NULL; 1006 struct gadget_info *gi = NULL; 1007 struct fconfig_dev_desc_string desc_string; 1008 struct gadget_strings *dev_strings = NULL; 1009 int ret; 1010 1011 ret = memcpy_s(&desc_string, sizeof(desc_string), (void *)user_data, sizeof(desc_string)); 1012 if (ret != EOK) 1013 { 1014 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 1015 return -1; 1016 } 1017 1018 gi = gadget_find_by_name(cdev, &desc_string.gadget_name); 1019 if (gi == NULL) 1020 { 1021 usb_err("%s: can't find the gadget\n", __FUNCTION__); 1022 return -1; 1023 } 1024 if (gi->dev_desc == NULL) 1025 { 1026 usb_err("%s: dev_desc is null\n", __FUNCTION__); 1027 return -1; 1028 } 1029 1030 obj = usbobj_find(&gi->strings, gadget_strings_match, &desc_string.prop.lang); 1031 if (!obj) 1032 { 1033 usb_err("%s: can not find language = 0x%x strings\n", __func__, desc_string.prop.lang); 1034 return -1; 1035 } 1036 dev_strings = container_of(obj, struct gadget_strings, obj); 1037 1038 ret = change_dev_descritor_string(gi, &desc_string, dev_strings); 1039 if (ret != EOK) 1040 { 1041 usb_err("%s: copy config descs from user failed\n", __FUNCTION__); 1042 return -1; 1043 } 1044 return 0; 1045} 1046 1047int fconfig_handle_open(struct usb_handle *handle) 1048{ 1049 struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv); 1050 1051 1052 if (cdev == NULL) 1053 { 1054 usb_err("Invalid private parameter!\n"); 1055 return -1; 1056 } 1057 1058 usbobj_get(&cdev->obj); 1059 return 0; 1060} 1061 1062int fconfig_handle_close(struct usb_handle *handle) 1063{ 1064 struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv); 1065 1066 if (cdev == NULL) 1067 { 1068 usb_err("Invalid private parameter!\n"); 1069 return -1; 1070 } 1071 1072 usbobj_put(&cdev->obj); 1073 return 0; 1074} 1075 1076int fconfig_handle_read(struct usb_handle *handle, void *buffer, size_t len) 1077{ 1078 struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv); 1079 1080 if (len == 0) 1081 { 1082 usb_err("buflen is 0!\n"); 1083 return -1; 1084 } 1085 1086 if (cdev == NULL) 1087 { 1088 usb_err("Invalid private parameter!\n"); 1089 return -1; 1090 } 1091 1092 return 0; 1093} 1094 1095int fconfig_handle_write(struct usb_handle *handle, void *buffer, size_t len) 1096{ 1097 struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv); 1098 1099 if (len == 0) 1100 { 1101 usb_err("buflen is 0!\n"); 1102 return -1; 1103 } 1104 1105 if (cdev == NULL) 1106 { 1107 usb_err("Invalid private parameter!\n"); 1108 return -1; 1109 } 1110 1111 return 0; 1112} 1113 1114int fconfig_handle_ioctl(struct usb_handle *handle, int cmd, void *arg) 1115{ 1116 struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv); 1117 void *argp = (void *)arg; 1118 int ret = -1; 1119 1120 if (cdev == NULL || argp == NULL) 1121 { 1122 usb_err("Invalid private parameter!\n"); 1123 return -ENODEV; 1124 } 1125 1126 switch (cmd) 1127 { 1128 case FCONFIG_CMD_MAKE_GADGET: 1129 ret = fconfig_make_gadget(cdev, argp); 1130 break; 1131 1132 case FCONFIG_CMD_DROP_GADGET: 1133 ret = fconfig_drop_gadget(cdev, argp); 1134 break; 1135 1136 case FCONFIG_CMD_WRITE_DEV_DESC: 1137 ret = fconfig_write_dev_desc(cdev, argp); 1138 break; 1139 1140 case FCONFIG_CMD_ADD_CONFIG: 1141 ret = fconfig_add_gadget_cfg(cdev, argp); 1142 break; 1143 1144 case FCONFIG_CMD_REMOVE_CONFIG: 1145 ret = fconfig_remove_gadget_cfg(cdev, argp); 1146 break; 1147 1148 case FCONFIG_CMD_WRITE_STRINGS: 1149 ret = fconfig_write_strings(cdev, argp); 1150 break; 1151 1152 case FCONFIG_CMD_MAKE_FUNCTION: 1153 ret = fconfig_make_function(cdev, argp); 1154 break; 1155 1156 case FCONFIG_CMD_DROP_FUNCTION: 1157 ret = fconfig_drop_function(cdev, argp); 1158 break; 1159 1160 case FCONFIG_CMD_ENABLE_UDC: 1161 ret = fconfig_enable_udc(cdev, argp); 1162 break; 1163 1164 case FCONFIG_CMD_DISABLE_UDC: 1165 ret = fconfig_disable_udc(cdev, argp); 1166 break; 1167 case FCONFIG_CMD_CHAGE_DEVINFO: 1168 ret = fconfig_change_dev_desc_info(cdev, argp); 1169 break; 1170 case FCONFIG_CMD_CHAGE_DEVSTRING: 1171 ret = fconfig_change_dev_desc_string(cdev, argp); 1172 break; 1173 default: 1174 usb_err("the ioctl %d is not supported\n", cmd); 1175 break; 1176 } 1177 1178 return ret; 1179} 1180 1181static struct UsbHandleOps g_fconfig_handle_fops = 1182{ 1183 .open = fconfig_handle_open, 1184 .close = fconfig_handle_close, 1185 .read = fconfig_handle_read, 1186 .write = fconfig_handle_write, 1187 .ioctl = fconfig_handle_ioctl, 1188}; 1189 1190int fconfig_fops_init(struct fconfig_softc *cdev) 1191{ 1192 int ret; 1193 char *devName = NULL; 1194 1195 if (cdev == NULL) 1196 { 1197 usb_err("%s: cdev is NULL\n", __FUNCTION__); 1198 return -1; 1199 } 1200 1201 devName = usbm_malloc(&cdev->obj, strlen(USB_FCONFIG_DEV) + 1); 1202 if (!devName) 1203 { 1204 return -1; 1205 } 1206 ret = snprintf_s(devName, strlen(USB_FCONFIG_DEV) + 1, strlen(USB_FCONFIG_DEV), 1207 "%s", USB_FCONFIG_DEV); 1208 if (ret < 0) 1209 { 1210 goto free_devname; 1211 } 1212 ret = register_handle(devName, &g_fconfig_handle_fops, cdev, &cdev->obj); 1213 if (ret != OK) 1214 { 1215 usb_err("%s: fconfig device register failed!\n", __FUNCTION__); 1216 goto free_devname; 1217 } 1218 1219 return 0; 1220 1221free_devname: 1222 usbm_free(&cdev->obj, devName); 1223 return ret; 1224} 1225 1226int fconfig_fops_deinit(const struct fconfig_softc *cdev) 1227{ 1228 int ret; 1229 1230 if (cdev == NULL) 1231 { 1232 usb_err("%s: cdev is NULL\n", __FUNCTION__); 1233 return -1; 1234 } 1235 ret = unregister_handle(USB_FCONFIG_DEV); 1236 if (ret != OK) 1237 { 1238 usb_err("%s: fconfig device unregister failed!\n", __FUNCTION__); 1239 } 1240 1241 return ret; 1242} 1243 1244#ifdef __cplusplus 1245#if __cplusplus 1246//} 1247#endif /* __cplusplus */ 1248#endif /* __cplusplus */ 1249