• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3  * Description: LiteOS USB Driver Composite Devices
4  * Author: huangjieliang
5  * Create: 2017-04-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 "gadget/composite.h"
38 #include "gadget/cdcacm.h"
39 #include "gadget/rndis.h"
40 
41 #ifdef __cplusplus
42 #if __cplusplus
43 extern "C" {
44 #endif /* __cplusplus */
45 #endif /* __cplusplus */
46 
47 #define FMULTI_DEBUG
48 #ifdef FMULTI_DEBUG
49 #define FMSLOG(x...) dprintf(x)
50 #else
51 #define FMSLOG(x...) do {} while(0)
52 #endif
53 
54 #define USB_ETHER_FIRST_INTERFACE_NUM 0
55 #define USB_SERIAL_FIRST_INTERFACE_NUM 2
56 
57 int usbdev_multi_initialize(struct module *mod, int n, void *arg);
58 
59 /* device driver structure definition */
60 
61 static driver_t g_fmulti_driver_t =
62 {
63   .name    = "fmulti",
64   .methods = NULL,
65   .size    = 0
66 };
67 
68 /* private device class information */
69 
70 static devclass_t g_fmulti_devclass;
71 DRIVER_MODULE(fmulti, simple, g_fmulti_driver_t, g_fmulti_devclass, usbdev_multi_initialize, 0);
72 
73 #define MULTI_VENDOR_ID     0x1d6b
74 #define MULTI_PRODUCT_ID    0x0104
75 
76 /* This struct is aimed at enumerating index for composite device strings. */
77 
78 enum
79 {
80   /* Rndis Device */
81 
82   MULTI_RNDIS_CTRL_IDX = 6,
83   MULTI_RNDIS_DATA_IDX,
84   MULTI_RNDIS_IAD_IDX,
85 
86   /* ACM Device */
87 
88   MULTI_ACM_CTRL_IDX = 0xa,
89   MULTI_ACM_DATA_IDX,
90   MULTI_ACM_IAD_IDX
91 };
92 
93 /* Define and initialize multi device descriptor. */
94 
95 static const struct usb_device_descriptor g_fmulti_device_desc =
96 {
97   .bLength            = sizeof(struct usb_device_descriptor),
98   .bDescriptorType    = UDESC_DEVICE,
99   HSETW(.bcdUSB, UD_BCD_USB), /* USB version */
100   .bDeviceClass       = UDCLASS_MISC,
101   .bDeviceSubClass    = 2,
102   .bDeviceProtocol    = 1,
103   .bMaxPacketSize     = UD_USB_MPS,
104   HSETW(.idVendor,    MULTI_VENDOR_ID),  /* vendor */
105   HSETW(.idProduct,   MULTI_PRODUCT_ID), /* product */
106   HSETW(.bcdDevice, 0x0318),             /* device version */
107   .iManufacturer      = 1,
108   .iProduct           = 2,
109   .iSerialNumber      = 0,
110   .bNumConfigurations = 1,
111 };
112 
113 #define MULTI_STRING_ID_LEN  4
114 static const char g_multi_string_id[MULTI_STRING_ID_LEN] =
115 {
116   MULTI_STRING_ID_LEN,
117   UDESC_STRING,
118   0x09,
119   0x04,
120 };
121 
122 #define MULTI_VERSION_STRING_LEN 62
123 static const char g_multi_version_string[MULTI_VERSION_STRING_LEN] =
124 {
125   MULTI_VERSION_STRING_LEN, UDESC_STRING,
126   'M', 0, 'u', 0, 'l', 0, 't', 0, 'i', 0, 'f', 0, 'u', 0, 'n', 0, 'c', 0, 't', 0,
127   'i', 0, 'o', 0, 'n', 0, ' ', 0, 'C', 0, 'o', 0, 'm', 0, 'p', 0, 'o', 0, 's', 0,
128   'i', 0, 't', 0, 'e', 0, ' ', 0, 'G', 0, 'a', 0, 'd', 0, 'g', 0, 'e', 0, 't', 0
129 };
130 
131 #define MULTI_STRING_4_LEN 38
132 static const char g_dt_string_4[MULTI_STRING_4_LEN] =
133 {
134   MULTI_STRING_4_LEN,
135   UDESC_STRING,
136   0x47, 0, 0x61, 0, 0x64, 0, 0x67, 0, 0x65, 0, 0x74, 0, 0x20, 0,
137   0x53, 0, 0x65, 0, 0x72, 0, 0x69, 0, 0x61, 0, 0x6c, 0, 0x20, 0,
138   0x76, 0, 0x32, 0, 0x2e, 0, 0x34, 0
139 };
140 
141 #define DT_STRING_6_LEN 26
142 static const char g_dt_string_6[DT_STRING_6_LEN] =
143 {
144   DT_STRING_6_LEN,
145   UDESC_STRING,
146   0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x41, 0,
147   0x43, 0, 0x4d, 0, 0x20, 0, 0x44, 0, 0x61, 0, 0x74, 0, 0x61, 0
148 };
149 
150 #define DT_STRING_7_LEN 22
151 static const char g_dt_string_7[DT_STRING_7_LEN] =
152 {
153   DT_STRING_7_LEN,
154   UDESC_STRING,
155   0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x53, 0, 0x65, 0,
156   0x72, 0, 0x69, 0, 0x61, 0, 0x6c, 0
157 };
158 
159 #define MULTI_RNDIS_STRING_LEN 12
160 static const char g_multi_rndis_string[MULTI_RNDIS_STRING_LEN] =
161 {
162   MULTI_RNDIS_STRING_LEN,
163   UDESC_STRING,
164   'R',0,'N',0,'D',0,'I',0,'S',0
165 };
166 
167 #define MULTI_SERIAL_STRING_LEN 22
168 static const char g_multi_serial_string[MULTI_SERIAL_STRING_LEN] =
169 {
170   MULTI_SERIAL_STRING_LEN,
171   UDESC_STRING,
172   'C',0,'D',0,'C',0,' ',0,'S',0,'e',0,'i',0,'a',0,'l',0
173 };
174 
175 #define FMULTI_DSTR_IDX 8
176 struct usbd_string g_fmulti_device_strings[FMULTI_DSTR_IDX] =
177 {
178   { 0,                   g_multi_string_id },
179   { 2,                   g_multi_version_string },
180   { 4,                   g_dt_string_4 },
181   { 6,                   g_dt_string_6 },
182   { 7,                   g_dt_string_7 },
183   { MULTI_RNDIS_IAD_IDX, g_multi_rndis_string },
184   { MULTI_ACM_IAD_IDX,   g_multi_serial_string },
185   USBD_DEVICE_STRINGS_END
186 };
187 
multi_mkdevdesc(uint8_t * buf)188 void multi_mkdevdesc(uint8_t *buf)
189 {
190   errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fmulti_device_desc, sizeof(g_fmulti_device_desc));
191   if (ret != EOK)
192     {
193       usb_err("memcpy_s fail!, ret:%d\n", ret);
194       return;
195     }
196 }
197 
multi_mkstrdesc(uint8_t id,uint8_t * buf)198 int multi_mkstrdesc(uint8_t id, uint8_t *buf)
199 {
200   errno_t ret;
201   const char *str;
202   int i;
203 
204   for (i = 0; g_fmulti_device_strings[i].s != NULL; i++)
205     {
206       str = g_fmulti_device_strings[i].s;
207       if (g_fmulti_device_strings[i].id == id)
208         {
209           ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]);
210           if (ret != EOK)
211             {
212               usb_err("memcpy_s failed, ret = %d\n", ret);
213               return -1;
214             }
215           return str[0];
216         }
217     }
218 
219   usb_err("Can not find the id = %u of string\n", id);
220   return -1;
221 }
222 
multi_get_composite_devdesc(struct composite_devdesc_s * dev)223 void multi_get_composite_devdesc(struct composite_devdesc_s *dev)
224 {
225   dev->mkdevdesc = multi_mkdevdesc;
226   dev->mkstrdesc = multi_mkstrdesc;
227 }
228 
usbdev_multi_initialize(struct module * mod,int n,void * arg)229 int usbdev_multi_initialize (struct module *mod, int n, void *arg)
230 {
231   struct composite_softc *com_s = (struct composite_softc *)arg;
232   struct composite_devdesc_s dev[USB_COMPOSITE_DEV_NUM];
233   int ret;
234 
235   (void)mod;
236   (void)n;
237   if (com_s == NULL)
238     {
239       PRINTK("com_s is NULL!\n");
240       return -1;
241     }
242 
243   usbdev_rndis_initialize_sub(&dev[0], USB_ETHER_FIRST_INTERFACE_NUM, DEV_ETHERNET);
244   multi_get_composite_devdesc(&dev[0]);
245   usbdev_cdcacm_initialize_sub(&dev[1], USB_SERIAL_FIRST_INTERFACE_NUM, DEV_SERIAL);
246   multi_get_composite_devdesc(&dev[1]);
247 
248   ret = composite_initialize(com_s, USB_COMPOSITE_DEV_NUM, dev);
249   if (ret < 0)
250     {
251       PRINTK("  ** multi device initialized failed! **\n");
252       return -1;
253     }
254 
255   PRINTK("  ** multi device initialized successfully! **\n");
256   return 0;
257 }
258 
259 #ifdef __cplusplus
260 #if __cplusplus
261 }
262 #endif /* __cplusplus */
263 #endif /* __cplusplus */