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: creat 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