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
50 struct func_info {
51 uint8_t ndevices;
52 int ifnobase;
53 int strbase;
54 struct composite_devdesc_s *devs;
55 };
56
57 extern void usbdev_generic_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
58 extern void usbdev_cdcacm_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
59 extern void usbdev_rndis_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
60 extern void usbdev_mass_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
61 extern void usbdev_uac_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
62 extern void usbdev_uvc_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
63 extern int gadget_strings_match(struct usb_obj *obj, void *match_data);
64
65 struct usbdev_info g_generic_usbdev_info =
66 {
67 "generic", DEV_GENERIC, 0, usbdev_generic_initialize_sub
68 };
69
70 struct usbdev_info *g_fconfig_usbdev_info[] =
71 {
72 &g_generic_usbdev_info,
73 NULL,
74 };
75
fconfig_find_usbdev_info(char * name)76 static 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
fconfig_get_string(struct usb_obj * obj,struct fconfig_string * str)92 static 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
gadget_match(struct usb_obj * obj,void * match_data)116 static 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
gadget_find_by_name(struct fconfig_softc * cdev,struct fconfig_string * name)122 static 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
gadget_make(struct fconfig_softc * cdev,char * name)146 static 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
gadget_drop(struct fconfig_softc * cdev,struct fconfig_string * name)177 static 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
fconfig_make_gadget(struct fconfig_softc * cdev,void * user_data)195 static 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
fconfig_drop_gadget(struct fconfig_softc * cdev,void * user_data)217 static 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
fconfig_write_dev_desc(struct fconfig_softc * cdev,void * user_data)231 static 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
267 err:
268 usbm_free(&gi->obj, dev_desc);
269 return -1;
270 }
271
fconfig_alloc_gadget_cfg(struct gadget_info * gi,char * cfg_name,struct usb_config_descriptor * cfg_desc)272 static 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
fconfig_add_gadget_cfg(struct fconfig_softc * cdev,void * user_data)294 static 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
356 err:
357 usbm_free(&gi->obj, cfg_desc);
358 usbm_free(&gi->obj, cfg_name);
359 return -1;
360 }
361
fconfig_remove_gadget_cfg(struct fconfig_softc * cdev,void * user_data)362 static 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
405 err:
406 usbm_free(&gi->obj, config_name);
407 return -1;
408 }
409
fconfig_fill_strings(struct gadget_info * gi,struct fconfig_dev_strings * str_data)410 static 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
468 err:
469 usbobj_put(&dev_strings->obj);
470 return -1;
471 }
472
fconfig_write_strings(struct fconfig_softc * cdev,void * user_data)473 static 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
function_instance_release(struct usb_obj * obj)507 void 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
fconfig_do_make_function(struct gadget_config * cfg,char * func_name)523 static 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
579 err:
580 usbobj_put(&func_inst->obj);
581 return -1;
582 }
583
fconfig_do_drop_function(struct gadget_config * cfg,char * func_name)584 static 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
fconfig_get_function_info(struct fconfig_softc * cdev,void * user_data,char ** name,struct gadget_config ** usb_cfg)610 static 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
663 err2:
664 usbm_free(&cfg->obj, func_name);
665 err:
666 usbm_free(&gi->obj, config_name);
667 return -1;
668 }
669
fconfig_make_function(struct fconfig_softc * cdev,void * user_data)670 static 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
fconfig_drop_function(struct fconfig_softc * cdev,void * user_data)693 static 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
usb_config_match(struct usb_obj * obj,void * match_data)716 static 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
func_inst_init(struct usb_obj * obj,void * data)724 static 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
fconfig_composite_initialize(struct gadget_info * gi,struct composite_softc * com_s)752 static 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
fconfig_enable_udc(struct fconfig_softc * cdev,void * user_data)782 static 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
828 err:
829 usbm_free(&gi->obj, udc_name);
830 return -1;
831 }
832
fconfig_disable_udc(struct fconfig_softc * cdev,void * user_data)833 static 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
859 err:
860 return -1;
861 }
862
change_dev_descritor_info(struct gadget_info * gi,struct fconfig_dev_desc_info * desc_info)863 static 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
fconfig_change_dev_desc_info(struct fconfig_softc * cdev,void * user_data)922 static 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
change_dev_descritor_string(struct gadget_info * gi,struct fconfig_dev_desc_string * desc_string,struct gadget_strings * dev_strings)955 static 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
fconfig_change_dev_desc_string(struct fconfig_softc * cdev,void * user_data)1003 static 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
fconfig_handle_open(struct usb_handle * handle)1047 int 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
fconfig_handle_close(struct usb_handle * handle)1062 int 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
fconfig_handle_read(struct usb_handle * handle,void * buffer,size_t len)1076 int 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
fconfig_handle_write(struct usb_handle * handle,void * buffer,size_t len)1095 int 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
fconfig_handle_ioctl(struct usb_handle * handle,int cmd,void * arg)1114 int 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
1181 static 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
fconfig_fops_init(struct fconfig_softc * cdev)1190 int 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
1221 free_devname:
1222 usbm_free(&cdev->obj, devName);
1223 return ret;
1224 }
1225
fconfig_fops_deinit(const struct fconfig_softc * cdev)1226 int 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