1 /*
2 * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "usb_init.h"
33 #include "usb_api_pri.h"
34 #include "devmgr_service.h"
35 #include "devsvc_manager_clnt.h"
36 #include "hdf_device_object.h"
37
38 typedef struct usb_info {
39 bool b_init;
40 controller_type ctype;
41 device_type dtype;
42 } usb_info_t;
43
44 static char *dev_name = NULL;
45 static bool uvc_enable = false;
46 static usb_info_t usb_info = { false, (controller_type)0xFFFF, (device_type)0xFFFF };
47 static struct mtx usb_mtx = PTHREAD_MUTEX_INITIALIZER;
48
49 static struct driver_module_data* usb_driver_mode_list[] = {
50 #ifdef LOSCFG_DRIVERS_USB_HOST_EHCI
51 /* xxx controller modules */
52 /* usb generial controller modules */
53 &usbus_ehci_driver_mod,
54 #endif
55
56 #if defined (LOSCFG_DRIVERS_USB_HOST_XHCI)
57 &usbus_xhci_driver_mod,
58 #endif
59
60 #ifdef LOSCFG_DRIVERS_USB_HOST_DRIVER
61 /* xxx driver modules */
62 &uhub_uhub_driver_mod,
63 &uhub_usbus_driver_mod,
64 #endif
65
66 #ifdef LOSCFG_DRIVERS_USB_4G_MODEM
67 #ifndef LOSCFG_DRIVERS_HDF_USB_DDK_HOST
68 &cdce_uhub_driver_mod,
69 #endif
70 //&bsd_u3g_uhub_driver_mod,
71 #endif
72
73 #if defined (LOSCFG_DRIVERS_USB_SERIAL) || defined (LOSCFG_DRIVERS_USB_4G_MODEM)
74 &u3g_uhub_driver_mod,
75 #endif
76
77 #ifdef LOSCFG_DRIVERS_USB_MASS_STORAGE
78 &umass_uhub_driver_mod,
79 #endif
80
81 #ifdef LOSCFG_DRIVERS_USB_ETHERNET
82 &axe_uhub_driver_mod,
83 &axge_uhub_driver_mod,
84 #endif
85
86 #ifdef LOSCFG_DRIVERS_USB_RNDIS_HOST
87 &urndis_uhub_driver_mod,
88 #endif
89
90 #ifdef LOSCFG_DRIVERS_USB_WIRELESS
91 &usb_linux_uhub_driver_mod,
92 #endif
93
94 #if defined (LOSCFG_DRIVERS_USB_HID_CLASS) && defined (LOSCFG_DRIVERS_HDF_INPUT)
95 &uhid_uhub_driver_mod,
96 #endif
97
98 #ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE
99 &composite_hiudc3_driver_mod,
100 #endif
101 NULL
102 };
103
104 extern device_t
105 bus_get_device(device_t dev, const char *name);
106
107 void
usbinfo_clean(void)108 usbinfo_clean(void)
109 {
110 dev_name = NULL;
111 uvc_enable = false;
112 usb_info.ctype = (controller_type)0xFFFF;
113 usb_info.dtype = (device_type)0xFFFF;
114 usb_info.b_init = false;
115 return;
116 }
117
118 char *
dev_name_get(void)119 dev_name_get(void)
120 {
121 return (dev_name);
122 }
123
124 static uint32_t
usb_loadonce(void)125 usb_loadonce(void)
126 {
127 struct driver_module_data *data;
128 uint32_t i;
129
130 dprintf("usb %s\n",fetach_usbversion());
131
132 #ifdef LOSCFG_DRIVERS_USB
133 /* init quirk */
134 usb_quirk_init(NULL);
135
136 for (i = 0; (data = usb_driver_mode_list[i]) && (data != NULL); i++) {
137 driver_module_handler(NULL, MOD_LOAD, data);
138 }
139 #endif
140
141 #ifdef LOSCFG_USB_DEBUG
142 usb_debug_module_regsiter();
143 #endif
144
145 return (0);
146 }
147
148 static void
usb_unloadonce(void)149 usb_unloadonce(void)
150 {
151 uint32_t i;
152
153 #ifdef LOSCFG_USB_DEBUG
154 usb_debug_module_unregsiter();
155 #endif
156
157 #ifdef LOSCFG_DRIVERS_USB
158 for (i = 0; usb_driver_mode_list[i] != NULL; i++) {
159 driver_module_handler(NULL, MOD_UNLOAD, usb_driver_mode_list[i]);
160 }
161 #endif
162
163 return;
164 }
165 #ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE
HdfLoadUsbDevice(const char * serv_name)166 static struct HdfDeviceObject *HdfLoadUsbDevice(const char *serv_name)
167 {
168 struct IDevmgrService *devmgr = DevmgrServiceGetInstance();
169 if(devmgr== NULL || devmgr->LoadDevice(devmgr, serv_name) != HDF_SUCCESS) {
170 dprintf("failed to load %s", serv_name);
171 return NULL;
172 }
173
174 return DevSvcManagerClntGetDeviceObject(serv_name);
175 }
176
HdfRegisterUsbDevice(struct HdfDeviceObject * usb_fn_master,const char * driver_name,const char * serv_name)177 struct HdfDeviceObject *HdfRegisterUsbDevice(struct HdfDeviceObject *usb_fn_master,
178 const char *driver_name, const char *serv_name)
179 {
180 struct HdfDeviceObject *dev = HdfDeviceObjectAlloc(usb_fn_master, driver_name);
181 if (dev == NULL) {
182 dprintf("%s: failed to alloc device object", __func__);
183 return NULL;
184 }
185
186 if (HdfDeviceObjectRegister(dev) != HDF_SUCCESS) {
187 dprintf("%s: failed to regitst device %s", __func__, serv_name);
188 HdfDeviceObjectRelease(dev);
189 return NULL;
190 }
191
192 if (HdfDeviceObjectPublishService(dev, serv_name, SERVICE_POLICY_PUBLIC, 0664) != HDF_SUCCESS) {
193 dprintf("%s: failed to regitst device %s", __func__, serv_name);
194 HdfDeviceObjectRelease(dev);
195 return NULL;
196 }
197
198 return dev;
199 }
200
composite_add(void)201 static int composite_add(void)
202 {
203 device_t udc;
204 device_t composite;
205
206 udc = bus_get_device(nexus, "hiudc3");
207 if (udc == NULL) {
208 return -1;
209 }
210
211 composite = device_add_child(udc, "composite", -1);
212 if (composite == NULL) {
213 return -1;
214 }
215
216 if (device_probe_and_attach(composite)) {
217 device_printf(composite, "WARNING: Probe and attach failed!\n");
218 return -1;
219 }
220 struct HdfDeviceObject *usb_fn_dev = HdfLoadUsbDevice("usbfn_master");
221 if (usb_fn_dev == NULL) {
222 dprintf("%s register usbfn_master may failed\n", __func__);
223 }
224
225 struct HdfDeviceObject *devobj = HdfRegisterUsbDevice(usb_fn_dev, "usbfn_cdcacm", "usbfn_cdcacm");
226 if (devobj == NULL) {
227 dprintf("%s register usbfn_cdcacm may failed\n", __func__);
228 }
229
230 devobj = HdfRegisterUsbDevice(usb_fn_dev, "usbfn_cdcecm", "usbfn_cdcecm");
231 if (devobj == NULL) {
232 dprintf("%s register usbfn_cdcecm may failed\n", __func__);
233 }
234 dprintf("%s success\n", __func__);
235 return 0;
236 }
237 #endif
238 /*
239 * step1: modify DRIVER_MODULE,register all driver module
240 * step2: make ehci/ohci device (direct skip pci bus)
241 * step3: insert ehci/ohci device into usb controller
242 * step4: create ehci/ohci root hub device
243 * step5: ehci/ohci transfer setup/start
244 */
245 uint32_t
usb_init(controller_type ctype,device_type dtype)246 usb_init(controller_type ctype, device_type dtype)
247 {
248 uint32_t ret;
249 static int usb_loaded = 0;
250
251 dprintf("\n******** %s in **********\n", __FUNCTION__);
252
253 mtx_lock(&usb_mtx);
254 if (usb_info.b_init) {
255 dprintf("\n duplicate usb_init %s, ctype:%d dtype:%d\n", __FUNCTION__, usb_info.ctype, usb_info.dtype);
256 mtx_unlock(&usb_mtx);
257 return (LOS_NOK);
258 }
259
260 if (usb_loaded == 0) {
261 ret = usb_loadonce();
262 if (ret) {
263 goto err;
264 }
265 usb_loaded = 1;
266 }
267
268 usb_dev_init(NULL);
269
270 if (ctype == HOST) {
271 #if defined (LOSCFG_DRIVERS_USB_HOST_XHCI)
272 ret = hixhci_init();
273 #endif
274 #ifdef LOSCFG_DRIVERS_USB_HOST_EHCI
275 ret = hiehci_init();
276 #endif
277 } else {
278 #ifdef LOSCFG_DRIVERS_HDF_USB_DDK_DEVICE
279 ret = usbd_load_driver();
280 if (ret != LOS_OK) {
281 dprintf("usbd_load_driver failed ,ret = %d\n", ret);
282 goto err;
283 }
284 ret = composite_add();
285 if (ret != LOS_OK) {
286 dprintf("composite_add failed ,ret = %d\n", ret);
287 goto err;
288 }
289 ret = usbd_enable_interrupt();
290 if (ret != LOS_OK) {
291 dprintf("usbd_enable_interrupt failed, ret = %d\n", ret);
292 goto err;
293 }
294 #endif
295 }
296
297 usb_info.b_init = true;
298 usb_info.ctype = ctype;
299 usb_info.dtype = dtype;
300
301 mtx_unlock(&usb_mtx);
302 dprintf("******** %s ok**********\n\n", __FUNCTION__);
303 return (LOS_OK);
304
305 err:
306 mtx_unlock(&usb_mtx);
307 if (!usb_loaded) {
308 usb_unloadonce();
309 }
310 dprintf("******** %s fail**********\n\n", __FUNCTION__);
311
312 return (LOS_NOK);
313 }
314
315 uint32_t
usb_deinit(void)316 usb_deinit(void)
317 {
318 uint32_t ret = LOS_OK;
319
320 dprintf("******** %s in **********\n\n", __FUNCTION__);
321 mtx_lock(&usb_mtx);
322
323 if (usb_info.b_init == false) {
324 dprintf("******** %s out, no init **********\n\n", __FUNCTION__);
325 goto err;
326 }
327
328 if (usb_info.ctype == HOST) {
329 dprintf("******** %s fail, host not support **********\n\n", __FUNCTION__);
330 goto err;
331 }
332
333 if (ret) {
334 dprintf("******** %s fail, %d **********\n\n", __FUNCTION__, ret);
335 goto err;
336 }
337
338 usb_dev_uninit(NULL);
339
340 dprintf(" ** %s uninit success **\n", dev_name_get());
341 usbinfo_clean();
342 mtx_unlock(&usb_mtx);
343 return (LOS_OK);
344
345 err:
346 mtx_unlock(&usb_mtx);
347 return (LOS_NOK);
348 }
349
350 bool
usb_is_devicemode(void)351 usb_is_devicemode(void)
352 {
353 return (HiUsbIsDeviceMode());
354 }
355
356