• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   /* TODO: Enable UDC */
813   ret = fconfig_composite_initialize(gi, com_s);
814   if (ret)
815     {
816       usb_err("%s: fcofnig composite init failed\n", __FUNCTION__);
817       goto err;
818     }
819   usbd_start_udc();
820   ret = usbd_gadget_attach_driver(com_s->parnet_conext, &com_s->drvr.drvr);
821   if (ret < 0)
822     {
823       usb_err("%s, usbd_gadget_attach_driver fail\n", __func__);
824       goto err;
825     }
826 
827   return 0;
828 
829 err:
830   usbm_free(&gi->obj, udc_name);
831   return -1;
832 }
833 
fconfig_disable_udc(struct fconfig_softc * cdev,void * user_data)834 static int fconfig_disable_udc(struct fconfig_softc *cdev, void *user_data)
835 {
836   struct gadget_info *gi = NULL;
837   struct fconfig_udc_info udc_info;
838   int ret;
839 
840   ret = memcpy_s(&udc_info, sizeof(udc_info), (void *)user_data, sizeof(udc_info));
841   if (ret != EOK)
842     {
843       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
844       return -1;
845     }
846 
847   gi = gadget_find_by_name(cdev, &udc_info.gadget_name);
848   if (gi == NULL)
849     {
850       usb_err("%s: can't find the gadget\n", __FUNCTION__);
851       goto err;
852     }
853 
854   /* disable UDC */
855   usbd_stop_udc();
856   usbm_free(&gi->obj, gi->udc_name);
857   gi->udc_name = NULL;
858   return 0;
859 
860 err:
861   return -1;
862 }
863 
change_dev_descritor_info(struct gadget_info * gi,struct fconfig_dev_desc_info * desc_info)864 static int change_dev_descritor_info(struct gadget_info *gi,
865                                      struct fconfig_dev_desc_info *desc_info)
866 {
867   const char *name = NULL;
868 
869   if (desc_info == NULL || gi == NULL)
870     {
871       usb_err("%s: param invail\n", __FUNCTION__);
872       return -1;
873     }
874   name = desc_info->prop.prop_name;
875   if (strcmp(USBDEV_VENDOR, name) == 0)
876     {
877       gi->dev_desc->idVendor[0] = (uint8_t)desc_info->prop.prop_value;
878       gi->dev_desc->idVendor[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
879     }
880   else if (strcmp(USBDEV_IDPRODUCT, name) == 0)
881     {
882       gi->dev_desc->idProduct[0] = (uint8_t)desc_info->prop.prop_value;
883       gi->dev_desc->idProduct[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
884     }
885   else if (strcmp(USBDEV_CLASS, name) == 0)
886     {
887       gi->dev_desc->bDeviceClass = (uint8_t)desc_info->prop.prop_value;
888     }
889   else if (strcmp(USBDEV_SUBCLASS, name) == 0)
890     {
891       gi->dev_desc->bDeviceSubClass = (uint8_t)desc_info->prop.prop_value;
892     }
893   else if (strcmp(USBDEV_PROTOCOL, name) == 0)
894     {
895       gi->dev_desc->bDeviceProtocol = (uint8_t)desc_info->prop.prop_value;
896     }
897   else if (strcmp(USBDEV_MAXSIZE, name) == 0)
898     {
899       gi->dev_desc->bMaxPacketSize = (uint8_t)desc_info->prop.prop_value;
900     }
901   else if (strcmp(USBDEV_NUMCFG, name) == 0)
902     {
903       gi->dev_desc->bNumConfigurations = (uint8_t)desc_info->prop.prop_value;
904     }
905   else if (strcmp(USBDEV_BCD, name) == 0)
906     {
907       gi->dev_desc->bcdUSB[0] = (uint8_t)desc_info->prop.prop_value;
908       gi->dev_desc->bcdUSB[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
909     }
910   else if (strcmp(USBDEV_BCDDEVICE, name) == 0)
911     {
912       gi->dev_desc->bcdDevice[0] = (uint8_t)desc_info->prop.prop_value;
913       gi->dev_desc->bcdDevice[1] = (uint8_t)(desc_info->prop.prop_value >> 8);
914     }
915   else
916     {
917       usb_err("%{public}s: other prop", __func__);
918       return -1;
919     }
920   return 0;
921 }
922 
fconfig_change_dev_desc_info(struct fconfig_softc * cdev,void * user_data)923 static int fconfig_change_dev_desc_info(struct fconfig_softc *cdev, void *user_data)
924 {
925   struct gadget_info *gi = NULL;
926   struct fconfig_dev_desc_info desc_info;
927   int ret;
928 
929   ret = memcpy_s(&desc_info, sizeof(desc_info), (void *)user_data, sizeof(desc_info));
930   if (ret != EOK)
931     {
932       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
933       return -1;
934     }
935 
936   gi = gadget_find_by_name(cdev, &desc_info.gadget_name);
937   if (gi == NULL)
938     {
939       usb_err("%s: can't find the gadget\n", __FUNCTION__);
940       return -1;
941     }
942   if (gi->dev_desc == NULL)
943     {
944       usb_err("%s: dev_desc is null\n", __FUNCTION__);
945       return -1;
946     }
947   ret = change_dev_descritor_info(gi, &desc_info);
948   if (ret != EOK)
949     {
950       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
951       return -1;
952     }
953   return 0;
954 }
955 
change_dev_descritor_string(struct gadget_info * gi,struct fconfig_dev_desc_string * desc_string,struct gadget_strings * dev_strings)956 static int change_dev_descritor_string(struct gadget_info *gi,
957                                        struct fconfig_dev_desc_string *desc_string,
958                                        struct gadget_strings *dev_strings)
959 {
960   uint8_t id = 0xff;
961   int i;
962   const char *name = NULL;
963 
964   if (desc_string == NULL || gi == NULL || dev_strings == NULL)
965     {
966       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
967       return -1;
968     }
969   for (i = 0; dev_strings->strings[i].s != NULL; i++)
970     {
971       const char *str = dev_strings->strings[i].s;
972       if (strcmp(str, desc_string->prop.prop_value) == 0)
973         {
974           id = dev_strings->strings[i].id;
975           break;
976         }
977     }
978   if (id == 0xff)
979     {
980       usb_err("%s: not found ringht string ID\n", __FUNCTION__);
981       return -1;
982     }
983   name = desc_string->prop.prop_name;
984   if (strcmp(USBDEV_MANUFACTURER, name) == 0)
985     {
986       gi->dev_desc->iManufacturer = id;
987     }
988   else if (strcmp(USBDEV_PRODUCT, name) == 0)
989     {
990       gi->dev_desc->iProduct = id;
991     }
992   else if (strcmp(USBDEV_SERIALNUM, name) == 0)
993     {
994       gi->dev_desc->iSerialNumber = id;
995     }
996   else
997     {
998       usb_err("%{public}s: other prop", __func__);
999       return -1;
1000     }
1001   return 0;
1002 }
1003 
fconfig_change_dev_desc_string(struct fconfig_softc * cdev,void * user_data)1004 static int fconfig_change_dev_desc_string(struct fconfig_softc *cdev, void *user_data)
1005 {
1006   struct usb_obj *obj = NULL;
1007   struct gadget_info *gi = NULL;
1008   struct fconfig_dev_desc_string desc_string;
1009   struct gadget_strings *dev_strings = NULL;
1010   int ret;
1011 
1012   ret = memcpy_s(&desc_string, sizeof(desc_string), (void *)user_data, sizeof(desc_string));
1013   if (ret != EOK)
1014     {
1015       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
1016       return -1;
1017     }
1018 
1019   gi = gadget_find_by_name(cdev, &desc_string.gadget_name);
1020   if (gi == NULL)
1021     {
1022       usb_err("%s: can't find the gadget\n", __FUNCTION__);
1023       return -1;
1024     }
1025   if (gi->dev_desc == NULL)
1026     {
1027       usb_err("%s: dev_desc is null\n", __FUNCTION__);
1028       return -1;
1029     }
1030 
1031   obj = usbobj_find(&gi->strings, gadget_strings_match, &desc_string.prop.lang);
1032   if (!obj)
1033     {
1034       usb_err("%s: can not find language = 0x%x strings\n", __func__, desc_string.prop.lang);
1035       return -1;
1036     }
1037   dev_strings = container_of(obj, struct gadget_strings, obj);
1038 
1039   ret = change_dev_descritor_string(gi, &desc_string, dev_strings);
1040   if (ret != EOK)
1041     {
1042       usb_err("%s: copy config descs from user failed\n", __FUNCTION__);
1043       return -1;
1044     }
1045   return 0;
1046 }
1047 
fconfig_handle_open(struct usb_handle * handle)1048 int fconfig_handle_open(struct usb_handle *handle)
1049 {
1050   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1051 
1052 
1053   if (cdev == NULL)
1054     {
1055       usb_err("Invalid private parameter!\n");
1056       return -1;
1057     }
1058 
1059   usbobj_get(&cdev->obj);
1060   return 0;
1061 }
1062 
fconfig_handle_close(struct usb_handle * handle)1063 int fconfig_handle_close(struct usb_handle *handle)
1064 {
1065   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1066 
1067   if (cdev == NULL)
1068     {
1069       usb_err("Invalid private parameter!\n");
1070       return -1;
1071     }
1072 
1073   usbobj_put(&cdev->obj);
1074   return 0;
1075 }
1076 
fconfig_handle_read(struct usb_handle * handle,void * buffer,size_t len)1077 int fconfig_handle_read(struct usb_handle *handle, void *buffer, size_t len)
1078 {
1079   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1080 
1081   if (len == 0)
1082     {
1083       usb_err("buflen is 0!\n");
1084       return -1;
1085     }
1086 
1087   if (cdev == NULL)
1088     {
1089       usb_err("Invalid private parameter!\n");
1090       return -1;
1091     }
1092 
1093   return 0;
1094 }
1095 
fconfig_handle_write(struct usb_handle * handle,void * buffer,size_t len)1096 int fconfig_handle_write(struct usb_handle *handle, void *buffer, size_t len)
1097 {
1098   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1099 
1100   if (len == 0)
1101     {
1102       usb_err("buflen is 0!\n");
1103       return -1;
1104     }
1105 
1106   if (cdev == NULL)
1107     {
1108       usb_err("Invalid private parameter!\n");
1109       return -1;
1110     }
1111 
1112   return 0;
1113 }
1114 
fconfig_handle_ioctl(struct usb_handle * handle,int cmd,void * arg)1115 int fconfig_handle_ioctl(struct usb_handle *handle, int cmd, void *arg)
1116 {
1117   struct fconfig_softc *cdev = (struct fconfig_softc *)(handle->priv);
1118   void *argp = (void *)arg;
1119   int ret = -1;
1120 
1121   if (cdev == NULL || argp == NULL)
1122     {
1123       usb_err("Invalid private parameter!\n");
1124       return -ENODEV;
1125     }
1126 
1127   switch (cmd)
1128     {
1129     case FCONFIG_CMD_MAKE_GADGET:
1130 	  ret = fconfig_make_gadget(cdev, argp);
1131 	  break;
1132 
1133     case FCONFIG_CMD_DROP_GADGET:
1134       ret = fconfig_drop_gadget(cdev, argp);
1135       break;
1136 
1137     case FCONFIG_CMD_WRITE_DEV_DESC:
1138       ret = fconfig_write_dev_desc(cdev, argp);
1139       break;
1140 
1141     case FCONFIG_CMD_ADD_CONFIG:
1142       ret = fconfig_add_gadget_cfg(cdev, argp);
1143       break;
1144 
1145     case FCONFIG_CMD_REMOVE_CONFIG:
1146       ret = fconfig_remove_gadget_cfg(cdev, argp);
1147       break;
1148 
1149     case FCONFIG_CMD_WRITE_STRINGS:
1150       ret = fconfig_write_strings(cdev, argp);
1151       break;
1152 
1153     case FCONFIG_CMD_MAKE_FUNCTION:
1154       ret = fconfig_make_function(cdev, argp);
1155       break;
1156 
1157     case FCONFIG_CMD_DROP_FUNCTION:
1158       ret = fconfig_drop_function(cdev, argp);
1159       break;
1160 
1161     case FCONFIG_CMD_ENABLE_UDC:
1162       ret = fconfig_enable_udc(cdev, argp);
1163       break;
1164 
1165     case FCONFIG_CMD_DISABLE_UDC:
1166       ret = fconfig_disable_udc(cdev, argp);
1167       break;
1168     case FCONFIG_CMD_CHAGE_DEVINFO:
1169       ret = fconfig_change_dev_desc_info(cdev, argp);
1170       break;
1171     case FCONFIG_CMD_CHAGE_DEVSTRING:
1172       ret = fconfig_change_dev_desc_string(cdev, argp);
1173       break;
1174     default:
1175       usb_err("the ioctl %d is not supported\n", cmd);
1176       break;
1177     }
1178 
1179   return ret;
1180 }
1181 
1182 static struct UsbHandleOps g_fconfig_handle_fops =
1183 {
1184   .open   = fconfig_handle_open,
1185   .close  = fconfig_handle_close,
1186   .read   = fconfig_handle_read,
1187   .write  = fconfig_handle_write,
1188   .ioctl  = fconfig_handle_ioctl,
1189 };
1190 
fconfig_fops_init(struct fconfig_softc * cdev)1191 int fconfig_fops_init(struct fconfig_softc *cdev)
1192 {
1193   int ret;
1194   char *devName = NULL;
1195 
1196   if (cdev == NULL)
1197     {
1198       usb_err("%s: cdev is NULL\n", __FUNCTION__);
1199       return -1;
1200     }
1201 
1202   devName = usbm_malloc(&cdev->obj, strlen(USB_FCONFIG_DEV) + 1);
1203   if (!devName)
1204     {
1205       return -1;
1206     }
1207   ret = snprintf_s(devName, strlen(USB_FCONFIG_DEV) + 1, strlen(USB_FCONFIG_DEV),
1208                    "%s", USB_FCONFIG_DEV);
1209     if (ret < 0)
1210       {
1211         goto free_devname;
1212       }
1213   ret = register_handle(devName, &g_fconfig_handle_fops, cdev, &cdev->obj);
1214   if (ret != OK)
1215     {
1216       usb_err("%s: fconfig device register failed!\n", __FUNCTION__);
1217       goto free_devname;
1218     }
1219 
1220   return 0;
1221 
1222 free_devname:
1223   usbm_free(&cdev->obj, devName);
1224   return ret;
1225 }
1226 
fconfig_fops_deinit(const struct fconfig_softc * cdev)1227 int fconfig_fops_deinit(const struct fconfig_softc *cdev)
1228 {
1229   int ret;
1230 
1231   if (cdev == NULL)
1232     {
1233       usb_err("%s: cdev is NULL\n", __FUNCTION__);
1234       return -1;
1235     }
1236   ret = unregister_handle(USB_FCONFIG_DEV);
1237   if (ret != OK)
1238     {
1239       usb_err("%s: fconfig device unregister failed!\n", __FUNCTION__);
1240     }
1241 
1242   return ret;
1243 }
1244 
1245 #ifdef __cplusplus
1246 #if __cplusplus
1247 //}
1248 #endif /* __cplusplus */
1249 #endif /* __cplusplus */
1250