1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "usb_host_config.h"
10 #include "fsl_common.h"
11 #include "usb_host.h"
12 #include "usb_host_hci.h"
13 #include "usb_host_devices.h"
14 #include "fsl_device_registers.h"
15 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
16 #include "fsl_cache.h"
17 #endif
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /* Component ID definition, used by tools. */
24 #ifndef FSL_COMPONENT_ID
25 #define FSL_COMPONENT_ID "middleware.usb.host_stack"
26 #endif
27 
28 #if defined __CORTEX_M && (__CORTEX_M == 7U)
29 #if (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
30 #warning USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE is not supported.
31 #endif
32 #endif
33 
34 /*******************************************************************************
35  * Prototypes
36  ******************************************************************************/
37 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
38 
39 #include "usb_host_hub.h"
40 #include "usb_host_hub_app.h"
41 #endif
42 
43 /*!
44  * @brief get the idle host instance.
45  *
46  * @return  host instance pointer.
47  */
48 static usb_host_instance_t *USB_HostGetInstance(void);
49 
50 /*!
51  * @brief release host instance.
52  *
53  * @param hostInstance  host instance pointer.
54  */
55 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
56 
57 /*!
58  * @brief get the khci/ehci interface.
59  *
60  * @param controllerId    controller id.
61  * @param controllerTable return controller interface structure.
62  */
63 static void USB_HostGetControllerInterface(uint8_t controllerId,
64                                            const usb_host_controller_interface_t **controllerTable);
65 
66 /*******************************************************************************
67  * Variables
68  ******************************************************************************/
69 /*! @brief USB host instance resource */
70 usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
71 
72 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
73 #include "usb_host_ehci.h"
74 static const usb_host_controller_interface_t s_EhciInterface = {
75     USB_HostEhciCreate,    USB_HostEhciDestory,  USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
76     USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
77 };
78 #endif /* USB_HOST_CONFIG_EHCI */
79 
80 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
81 #include "usb_host_khci.h"
82 static const usb_host_controller_interface_t s_KhciInterface = {
83     USB_HostKhciCreate,    USB_HostKhciDestory,  USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
84     USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
85 };
86 #endif /* USB_HOST_CONFIG_KHCI */
87 
88 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
89 #include "usb_host_ohci.h"
90 static const usb_host_controller_interface_t s_OhciInterface = {
91     USB_HostOhciCreate,    USB_HostOhciDestory,  USB_HostOhciOpenPipe, USB_HostOhciClosePipe,
92     USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl,
93 };
94 #endif /* USB_HOST_CONFIG_OHCI */
95 
96 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
97 #include "usb_host_ip3516hs.h"
98 static const usb_host_controller_interface_t s_Ip3516HsInterface = {
99     USB_HostIp3516HsCreate,    USB_HostIp3516HsDestory,  USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe,
100     USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl,
101 };
102 #endif /* USB_HOST_CONFIG_IP3516HS */
103 
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)104 USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
105 static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)];
106 /*******************************************************************************
107  * Code
108  ******************************************************************************/
109 
110 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
111 /*FUNCTION*----------------------------------------------------------------
112  *
113  * Function Name  : usb_test_mode_init
114  * Returned Value : None
115  * Comments       :
116  *     This function is called by common class to initialize the class driver. It
117  *     is called in response to a select interface call by application
118  *
119  *END*--------------------------------------------------------------------*/
120 usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
121 {
122 #if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \
123      ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)))
124     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
125     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)deviceInstance->hostHandle;
126 #endif
127     uint32_t productId;
128     uint32_t vendorId;
129 
130     (void)usb_echo("usb host test init\r\n");
131     (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDevicePID, &productId);
132     (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceVID, &vendorId);
133     (void)usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
134 
135     if ((productId != 0x0200U) && (productId != 0x0101U) && (productId != 0x0102U) && (productId != 0x0103U) &&
136         (productId != 0x0104U) && (productId != 0x0105U) && (productId != 0x0106U) && (productId != 0x0107U) &&
137         (productId != 0x0108U))
138     {
139         (void)usb_echo("Unsupported Device\r\n");
140     }
141 
142     if (productId == 0x0200U)
143     {
144         (void)usb_echo("PET test device attached\r\n");
145     }
146     else
147     {
148 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
149         if (hostInstance->controllerTable == &s_EhciInterface)
150         {
151             (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
152                                                                  (void *)deviceHandle);
153         }
154 #elif ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
155         if (hostInstance->controllerTable == &s_Ip3516HsInterface)
156         {
157             (void)hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostTestModeInit,
158                                                                  (void *)deviceHandle);
159         }
160 #endif
161     }
162 
163     return kStatus_USB_Success;
164 }
165 #endif
166 
USB_HostGetInstance(void)167 static usb_host_instance_t *USB_HostGetInstance(void)
168 {
169     uint8_t i      = 0;
170     uint32_t index = 0;
171     void *temp;
172     OSA_SR_ALLOC();
173     OSA_ENTER_CRITICAL();
174     for (; i < (uint8_t)USB_HOST_CONFIG_MAX_HOST; i++)
175     {
176         if (g_UsbHostInstance[i].occupied != 1U)
177         {
178             uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
179             for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
180             {
181                 buffer[j] = 0x00U;
182             }
183             g_UsbHostInstance[i].occupied = 1;
184             OSA_EXIT_CRITICAL();
185             for (index = 0; index < (uint32_t)USB_HOST_CONFIG_MAX_TRANSFERS; ++index)
186             {
187                 temp                                                 = (void *)&(s_Setupbuffer[i][index][0]);
188                 g_UsbHostInstance[i].transferList[index].setupPacket = (usb_setup_struct_t *)temp;
189             }
190             return &g_UsbHostInstance[i];
191         }
192     }
193     OSA_EXIT_CRITICAL();
194     return NULL;
195 }
196 
USB_HostReleaseInstance(usb_host_instance_t * hostInstance)197 static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
198 {
199     OSA_SR_ALLOC();
200     OSA_ENTER_CRITICAL();
201     hostInstance->occupied = 0;
202     OSA_EXIT_CRITICAL();
203 }
204 
USB_HostGetControllerInterface(uint8_t controllerId,const usb_host_controller_interface_t ** controllerTable)205 static void USB_HostGetControllerInterface(uint8_t controllerId,
206                                            const usb_host_controller_interface_t **controllerTable)
207 {
208 #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
209     if (controllerId == (uint8_t)kUSB_ControllerKhci0)
210     {
211         *controllerTable = &s_KhciInterface;
212     }
213 #endif /* USB_HOST_CONFIG_KHCI */
214 
215 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
216     if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
217     {
218         *controllerTable = &s_EhciInterface;
219     }
220 #endif /* USB_HOST_CONFIG_EHCI */
221 
222 #if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
223     if (controllerId == (uint8_t)kUSB_ControllerOhci0)
224     {
225         *controllerTable = &s_OhciInterface;
226     }
227 #endif /* USB_HOST_CONFIG_OHCI */
228 
229 #if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U))
230     if (controllerId == (uint8_t)kUSB_ControllerIp3516Hs0)
231     {
232         *controllerTable = &s_Ip3516HsInterface;
233     }
234 #endif /* USB_HOST_CONFIG_IP3516HS */
235 }
236 
USB_HostInit(uint8_t controllerId,usb_host_handle * hostHandle,host_callback_t callbackFn)237 usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
238 {
239     usb_status_t status               = kStatus_USB_Success;
240     usb_host_instance_t *hostInstance = NULL;
241     usb_host_transfer_t *transferPrev = NULL;
242     uint8_t i                         = 0;
243 
244     hostInstance = USB_HostGetInstance(); /* get one host instance */
245     if (hostInstance == NULL)
246     {
247         return kStatus_USB_InvalidHandle;
248     }
249 
250     /* get khci/ehci API table */
251     USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable);
252     if (hostInstance->controllerTable == NULL)
253     {
254         USB_HostReleaseInstance(hostInstance);
255         return kStatus_USB_ControllerNotFound;
256     }
257 
258     /* judge the controller interface one time at here */
259     if ((hostInstance->controllerTable->controllerCreate == NULL) ||
260         (hostInstance->controllerTable->controllerDestory == NULL) ||
261         (hostInstance->controllerTable->controllerOpenPipe == NULL) ||
262         (hostInstance->controllerTable->controllerClosePipe == NULL) ||
263         (hostInstance->controllerTable->controllerWritePipe == NULL) ||
264         (hostInstance->controllerTable->controllerReadPipe == NULL) ||
265         (hostInstance->controllerTable->controllerIoctl == NULL))
266     {
267         return kStatus_USB_Error;
268     }
269 
270     /* HOST instance init*/
271     hostInstance->controllerId   = controllerId;
272     hostInstance->deviceCallback = callbackFn;
273     hostInstance->deviceList     = NULL;
274     hostInstance->hostMutex      = (osa_mutex_handle_t)(&hostInstance->mutexBuffer[0]);
275     if (KOSA_StatusSuccess != OSA_MutexCreate(hostInstance->hostMutex))
276     {
277         USB_HostReleaseInstance(hostInstance);
278 #ifdef HOST_ECHO
279         usb_echo("host init: create host mutex fail\r\n");
280 #endif
281         return kStatus_USB_Error;
282     }
283 
284     /* initialize transfer list */
285 
286     hostInstance->transferHead = &hostInstance->transferList[0];
287     transferPrev               = hostInstance->transferHead;
288     for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
289     {
290         transferPrev->next = &hostInstance->transferList[i];
291         transferPrev       = transferPrev->next;
292     }
293 
294     /* controller create, the callbackFn is initialized in USB_HostGetControllerInterface */
295     status =
296         hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
297     if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
298     {
299         (void)OSA_MutexDestroy(hostInstance->hostMutex);
300         USB_HostReleaseInstance(hostInstance);
301 #ifdef HOST_ECHO
302         usb_echo("host init: controller init fail\r\n");
303 #endif
304         return kStatus_USB_Error;
305     }
306 
307     *hostHandle = hostInstance;
308     return kStatus_USB_Success;
309 }
310 
USB_HostDeinit(usb_host_handle hostHandle)311 usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
312 {
313     usb_status_t status                        = kStatus_USB_Success;
314     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
315     usb_host_device_instance_t *deviceInstance = NULL;
316 
317     if (hostHandle == NULL)
318     {
319         return kStatus_USB_InvalidHandle;
320     }
321 
322     /* device list detach */
323     deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
324     while (deviceInstance != NULL)
325     {
326         deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
327         (void)USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
328     }
329 
330     /* controller instance destroy, the callbackFn is initialized in USB_HostGetControllerInterface */
331     status                         = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
332     hostInstance->controllerHandle = NULL;
333     if (status != kStatus_USB_Success)
334     {
335 #ifdef HOST_ECHO
336         usb_echo("host controller destroy fail\r\n");
337 #endif
338     }
339 
340     /* resource release */
341     if (NULL != hostInstance->hostMutex)
342     {
343         (void)OSA_MutexDestroy(hostInstance->hostMutex);
344         hostInstance->hostMutex = NULL;
345     }
346     USB_HostReleaseInstance(hostInstance);
347 
348     return status;
349 }
350 
USB_HostOpenPipe(usb_host_handle hostHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)351 usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
352                               usb_host_pipe_handle *pipeHandle,
353                               usb_host_pipe_init_t *pipeInit)
354 {
355     usb_status_t status               = kStatus_USB_Success;
356     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
357 
358     if ((hostHandle == NULL) || (pipeInit == NULL))
359     {
360         return kStatus_USB_InvalidHandle;
361     }
362 
363     /* call controller open pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
364     status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
365 
366     return status;
367 }
368 
USB_HostClosePipe(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle)369 usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
370 {
371     usb_status_t status               = kStatus_USB_Success;
372     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
373 
374     if ((hostHandle == NULL) || (pipeHandle == NULL))
375     {
376         return kStatus_USB_InvalidHandle;
377     }
378 
379     /* call controller close pipe interface, the callbackFn is initialized in USB_HostGetControllerInterface */
380     status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
381 
382     return status;
383 }
384 
USB_HostSend(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)385 usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
386 {
387     usb_status_t status               = kStatus_USB_Success;
388     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
389 
390     if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
391     {
392         return kStatus_USB_InvalidHandle;
393     }
394 
395     /* initialize transfer */
396     transfer->transferSofar = 0;
397     transfer->direction     = USB_OUT;
398 
399     (void)USB_HostLock(); /* This api can be called by host task and app task */
400 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
401  */
402 #if 0
403     if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
404     {
405         USB_HostUnlock();
406         return status;
407     }
408 #endif
409 /* call controller write pipe interface */
410 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
411     if (transfer->transferLength > 0)
412     {
413         DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
414     }
415 #endif
416     /* the callbackFn is initialized in USB_HostGetControllerInterface */
417     status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
418 
419     (void)USB_HostUnlock();
420     return status;
421 }
422 
USB_HostSendSetup(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)423 usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
424                                usb_host_pipe_handle pipeHandle,
425                                usb_host_transfer_t *transfer)
426 {
427     usb_status_t status               = kStatus_USB_Success;
428     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
429 
430     if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
431     {
432         return kStatus_USB_InvalidHandle;
433     }
434 
435     /* initialize transfer */
436     transfer->transferSofar = 0;
437     transfer->next          = NULL;
438     transfer->setupStatus   = 0;
439     if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
440     {
441         transfer->direction = USB_IN;
442     }
443     else
444     {
445         transfer->direction = USB_OUT;
446     }
447 
448     (void)USB_HostLock(); /* This API can be called by host task and application task */
449 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
450  */
451 #if 0
452     if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
453     {
454         USB_HostUnlock();
455         return status;
456     }
457 #endif
458 /* call controller write pipe interface */
459 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
460     DCACHE_CleanByRange((uint32_t)&transfer->setupPacket->bmRequestType, sizeof(usb_setup_struct_t));
461     if (transfer->transferLength > 0)
462     {
463         DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
464     }
465 #endif
466     /* the callbackFn is initialized in USB_HostGetControllerInterface */
467     status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
468 
469     (void)USB_HostUnlock();
470     return status;
471 }
472 
USB_HostRecv(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)473 usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
474 {
475     usb_status_t status               = kStatus_USB_Success;
476     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
477 
478     if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
479     {
480         return kStatus_USB_InvalidHandle;
481     }
482 
483     /* initialize transfer */
484     transfer->transferSofar = 0;
485     transfer->direction     = USB_IN;
486 
487     (void)USB_HostLock(); /* This API can be called by host task and application task */
488 /* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
489  */
490 #if 0
491     if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
492     {
493         USB_HostUnlock();
494         return status;
495     }
496 #endif
497 
498 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
499     if (transfer->transferLength > 0)
500     {
501         DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
502     }
503 #endif
504     /* the callbackFn is initialized in USB_HostGetControllerInterface */
505     status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
506 
507     (void)USB_HostUnlock();
508     return status;
509 }
510 
USB_HostCancelTransfer(usb_host_handle hostHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)511 usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
512                                     usb_host_pipe_handle pipeHandle,
513                                     usb_host_transfer_t *transfer)
514 {
515     usb_status_t status               = kStatus_USB_Success;
516     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
517     usb_host_cancel_param_t cancelParam;
518 
519     if ((hostHandle == NULL) || (pipeHandle == NULL))
520     {
521         return kStatus_USB_InvalidHandle;
522     }
523 
524     /* initialize cancel parameter */
525     cancelParam.pipeHandle = pipeHandle;
526     cancelParam.transfer   = transfer;
527 
528     /* USB_HostLock(); This api can be called by host task and app task */
529     /* the callbackFn is initialized in USB_HostGetControllerInterface */
530     status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
531                                                             &cancelParam);
532     /* USB_HostUnlock(); */
533 
534     return status;
535 }
536 
USB_HostMallocTransfer(usb_host_handle hostHandle,usb_host_transfer_t ** transfer)537 usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer)
538 {
539     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
540 
541     if ((hostHandle == NULL) || (transfer == NULL))
542     {
543         return kStatus_USB_InvalidHandle;
544     }
545 
546     /* get one from the transfer_head */
547     (void)USB_HostLock();
548     if (hostInstance->transferHead != NULL)
549     {
550         *transfer                  = hostInstance->transferHead;
551         hostInstance->transferHead = hostInstance->transferHead->next;
552         (void)USB_HostUnlock();
553         return kStatus_USB_Success;
554     }
555     else
556     {
557         *transfer = NULL;
558         (void)USB_HostUnlock();
559         return kStatus_USB_Error;
560     }
561 }
562 
USB_HostFreeTransfer(usb_host_handle hostHandle,usb_host_transfer_t * transfer)563 usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer)
564 {
565     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
566 
567     if (hostHandle == NULL)
568     {
569         return kStatus_USB_InvalidHandle;
570     }
571     if (transfer == NULL)
572     {
573         return kStatus_USB_Success;
574     }
575 
576     /* release one to the transfer_head */
577     (void)USB_HostLock();
578     transfer->next             = hostInstance->transferHead;
579     hostInstance->transferHead = transfer;
580     (void)USB_HostUnlock();
581     return kStatus_USB_Success;
582 }
583 
USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,uint32_t infoCode,uint32_t * infoValue)584 usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
585                                                     uint32_t infoCode,
586                                                     uint32_t *infoValue)
587 {
588     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
589     uint32_t *temp;
590     usb_host_dev_info_t devInfo;
591     if ((deviceHandle == NULL) || (infoValue == NULL))
592     {
593         return kStatus_USB_InvalidParameter;
594     }
595     devInfo = (usb_host_dev_info_t)infoCode;
596     switch (devInfo)
597     {
598         case kUSB_HostGetDeviceAddress: /* device address */
599 
600             *infoValue = (uint32_t)deviceInstance->setAddress;
601             break;
602 
603         case kUSB_HostGetDeviceControlPipe: /* device control pipe */
604             temp       = (uint32_t *)deviceInstance->controlPipe;
605             *infoValue = (uint32_t)temp;
606             break;
607 
608         case kUSB_HostGetHostHandle: /* device host handle */
609             temp       = (uint32_t *)deviceInstance->hostHandle;
610             *infoValue = (uint32_t)temp;
611             break;
612 
613 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
614         case kUSB_HostGetDeviceHubNumber: /* device hub address */
615             *infoValue = (uint32_t)deviceInstance->hubNumber;
616             break;
617 
618         case kUSB_HostGetDevicePortNumber: /* device port no */
619             *infoValue = (uint32_t)deviceInstance->portNumber;
620             break;
621 
622         case kUSB_HostGetDeviceLevel: /* device level */
623             *infoValue = (uint32_t)deviceInstance->level;
624             break;
625 
626         case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
627             *infoValue = (uint32_t)deviceInstance->hsHubNumber;
628             break;
629 
630         case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
631             *infoValue = (uint32_t)deviceInstance->hsHubPort;
632             break;
633 
634         case kUSB_HostGetHubThinkTime: /* device hub think time */
635             *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hostHandle, deviceInstance->hubNumber);
636             break;
637 #else
638         case kUSB_HostGetDeviceHubNumber:   /* device hub address */
639         case kUSB_HostGetDevicePortNumber:  /* device port no */
640         case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
641         case kUSB_HostGetDeviceHSHubPort:   /* device high-speed hub port no */
642         case kUSB_HostGetHubThinkTime:      /* device hub think time */
643             *infoValue = 0;
644             break;
645         case kUSB_HostGetDeviceLevel: /* device level */
646             *infoValue = 1;
647             break;
648 #endif /* USB_HOST_CONFIG_HUB */
649 
650         case kUSB_HostGetDeviceSpeed: /* device speed */
651             *infoValue = (uint32_t)deviceInstance->speed;
652             break;
653 
654         case kUSB_HostGetDevicePID: /* device pid */
655             *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idProduct);
656             break;
657 
658         case kUSB_HostGetDeviceVID: /* device vid */
659             *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idVendor);
660             break;
661 
662         case kUSB_HostGetDeviceConfigIndex: /* device config index */
663             *infoValue = (uint32_t)deviceInstance->configurationValue - 1U;
664             break;
665 
666         case kUSB_HostGetConfigurationDes: /* configuration descriptor pointer */
667             *infoValue = (uint32_t)deviceInstance->configurationDesc;
668             break;
669 
670         case kUSB_HostGetConfigurationLength: /* configuration descriptor length */
671             *infoValue = (uint32_t)deviceInstance->configurationLen;
672             break;
673 
674         default:
675             /*no action*/
676             break;
677     }
678 
679     return kStatus_USB_Success;
680 }
681 
USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,usb_host_interface_t * interface)682 usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
683                                                  uint8_t alternateSetting,
684                                                  usb_host_interface_t *interface)
685 {
686     uint32_t endPosition;
687     usb_descriptor_union_t *unionDes;
688     usb_host_ep_t *epParse;
689     void *temp;
690     if (interfaceHandle == NULL)
691     {
692         return kStatus_USB_InvalidHandle;
693     }
694 
695     if (alternateSetting == 0U)
696     {
697         return kStatus_USB_InvalidParameter;
698     }
699 
700     /* parse configuration descriptor */
701     temp = (void *)((usb_host_interface_t *)interfaceHandle)->interfaceExtension;
702     unionDes = (usb_descriptor_union_t *)temp; /* interface extend descriptor start */
703     endPosition =
704         (uint32_t)unionDes +
705         ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */
706 
707     /* search for the alternate setting interface descriptor */
708     while ((uint32_t)unionDes < endPosition)
709     {
710         if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
711         {
712             if (unionDes->interface.bAlternateSetting == alternateSetting)
713             {
714                 break;
715             }
716             else
717             {
718                 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
719             }
720         }
721         else
722         {
723             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
724         }
725     }
726     if ((uint32_t)unionDes >= endPosition)
727     {
728         return kStatus_USB_Error;
729     }
730 
731     /* initialize interface handle structure instance */
732     interface->interfaceDesc            = &unionDes->interface;
733     interface->alternateSettingNumber   = 0U;
734     interface->epCount                  = 0U;
735     interface->interfaceExtension       = NULL;
736     interface->interfaceExtensionLength = 0U;
737     interface->interfaceIndex           = unionDes->interface.bInterfaceNumber;
738 
739     /* search for endpoint descriptor start position */
740     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
741     while ((uint32_t)unionDes < endPosition)
742     {
743         if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
744             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
745         {
746             if (interface->interfaceExtension == NULL)
747             {
748                 interface->interfaceExtension = (uint8_t *)unionDes;
749             }
750             interface->interfaceExtensionLength += unionDes->common.bLength;
751             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
752         }
753         else
754         {
755             break;
756         }
757     }
758 
759     /* parse endpoint descriptor */
760     if (interface->interfaceDesc->bNumEndpoints != 0U)
761     {
762         if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
763             (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
764         {
765 #ifdef HOST_ECHO
766             usb_echo("interface descriptor error\n");
767 #endif
768             return kStatus_USB_Error;
769         }
770         for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++)
771         {
772             if (((uint32_t)unionDes >= endPosition) ||
773                 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
774             {
775 #ifdef HOST_ECHO
776                 usb_echo("endpoint descriptor error\n");
777 #endif
778                 return kStatus_USB_Error;
779             }
780             epParse                    = (usb_host_ep_t *)&interface->epList[interface->epCount];
781             temp                       = (void *)unionDes;
782             epParse->epDesc            = (usb_descriptor_endpoint_t *)temp;
783             epParse->epExtensionLength = 0;
784             epParse->epExtension       = NULL;
785             unionDes                   = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
786             while ((uint32_t)unionDes < endPosition)
787             {
788                 if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
789                     (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
790                 {
791                     if (epParse->epExtension == NULL)
792                     {
793                         epParse->epExtension = (uint8_t *)unionDes;
794                     }
795                     epParse->epExtensionLength += unionDes->common.bLength;
796                     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
797                 }
798                 else
799                 {
800                     break;
801                 }
802             }
803         }
804     }
805 
806     return kStatus_USB_Success;
807 }
808 
USB_HostGetVersion(uint32_t * version)809 void USB_HostGetVersion(uint32_t *version)
810 {
811     if (NULL != version)
812     {
813         *version =
814             (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
815     }
816 }
817 
818 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
819 /* Send BUS or specific device suspend request */
USB_HostSuspendDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)820 usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
821 {
822     usb_host_instance_t *hostInstance;
823     usb_host_device_instance_t *deviceInstance;
824     usb_status_t status         = kStatus_USB_Error;
825     usb_host_bus_control_t type = kUSB_HostBusSuspend;
826 
827     if (hostHandle == NULL)
828     {
829         return kStatus_USB_InvalidHandle;
830     }
831     hostInstance = (usb_host_instance_t *)hostHandle;
832 
833     hostInstance->suspendedDevice = (void *)deviceHandle;
834 
835     if (NULL == deviceHandle)
836     {
837 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
838         status = USB_HostHubSuspendDevice(hostInstance);
839 #else
840         /* the callbackFn is initialized in USB_HostGetControllerInterface */
841         status =
842             hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
843 #endif
844     }
845     else
846     {
847 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
848         deviceInstance = (usb_host_device_instance_t *)deviceHandle;
849         if (0U == deviceInstance->hubNumber)
850         {
851 #endif
852             if (hostInstance->deviceList == deviceHandle)
853             {
854                 /* the callbackFn is initialized in USB_HostGetControllerInterface */
855                 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
856                                                                         kUSB_HostBusControl, &type);
857             }
858 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
859         }
860         else
861         {
862             if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
863             {
864                 status = USB_HostHubSuspendDevice(hostInstance);
865             }
866         }
867 #endif
868     }
869     if (kStatus_USB_Error == status)
870     {
871         hostInstance->suspendedDevice = NULL;
872     }
873     return status;
874 }
875 
876 /* Send BUS or specific device resume request */
USB_HostResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle)877 usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle)
878 {
879     usb_host_instance_t *hostInstance;
880     usb_host_device_instance_t *deviceInstance;
881     usb_status_t status         = kStatus_USB_Error;
882     usb_host_bus_control_t type = kUSB_HostBusResume;
883 
884     if (hostHandle == NULL)
885     {
886         return kStatus_USB_InvalidHandle;
887     }
888     hostInstance = (usb_host_instance_t *)hostHandle;
889 
890     if (hostInstance->suspendedDevice != deviceHandle)
891     {
892         return kStatus_USB_InvalidParameter;
893     }
894     hostInstance->suspendedDevice = (void *)deviceHandle;
895 
896     if (NULL == deviceHandle)
897     {
898         /* the callbackFn is initialized in USB_HostGetControllerInterface */
899         status =
900             hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
901     }
902     else
903     {
904 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
905         deviceInstance = (usb_host_device_instance_t *)deviceHandle;
906         if (0U == deviceInstance->hubNumber)
907         {
908 #endif
909             if (hostInstance->deviceList == deviceHandle)
910             {
911                 /* the callbackFn is initialized in USB_HostGetControllerInterface */
912                 status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle,
913                                                                         kUSB_HostBusControl, &type);
914             }
915 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
916         }
917         else
918         {
919             if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle))
920             {
921                 status = USB_HostHubResumeDevice(hostInstance);
922             }
923         }
924 #endif
925     }
926 
927     return status;
928 }
929 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
930 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)931 usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle,
932                                            usb_device_handle deviceHandle,
933                                            uint8_t sleepType)
934 {
935     usb_host_instance_t *hostInstance;
936     usb_status_t status         = kStatus_USB_Error;
937     usb_host_bus_control_t type = kUSB_HostBusL1Sleep;
938 
939     if (hostHandle == NULL)
940     {
941         return kStatus_USB_InvalidHandle;
942     }
943     hostInstance = (usb_host_instance_t *)hostHandle;
944 
945     hostInstance->suspendedDevice = (void *)deviceHandle;
946 
947     if (1U == sleepType)
948     {
949         /*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/
950         /*To do, incomplete  hub L1 suspend device*/
951         /*#else*/
952         /* the callbackFn is initialized in USB_HostGetControllerInterface */
953         status =
954             hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
955         /*#endif*/
956     }
957     else
958     {
959 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
960 /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
961 #endif
962         if (hostInstance->deviceList == deviceHandle)
963         {
964             /* the callbackFn is initialized in USB_HostGetControllerInterface */
965             status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
966                                                                     &type);
967         }
968     }
969     if (kStatus_USB_Error == status)
970     {
971         hostInstance->suspendedDevice = NULL;
972     }
973     return status;
974 }
975 /* Send BUS or specific device suspend request */
USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle,uint8_t * lpmParam)976 usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam)
977 {
978     usb_host_instance_t *hostInstance;
979     usb_status_t status = kStatus_USB_Error;
980 
981     if (hostHandle == NULL)
982     {
983         return kStatus_USB_InvalidHandle;
984     }
985     hostInstance = (usb_host_instance_t *)hostHandle;
986     /* the callbackFn is initialized in USB_HostGetControllerInterface */
987     status =
988         hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam);
989 
990     return status;
991 }
992 
993 /* Send BUS or specific device resume request */
USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,usb_device_handle deviceHandle,uint8_t sleepType)994 usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle,
995                                             usb_device_handle deviceHandle,
996                                             uint8_t sleepType)
997 {
998     usb_host_instance_t *hostInstance;
999 
1000     usb_status_t status         = kStatus_USB_Error;
1001     usb_host_bus_control_t type = kUSB_HostBusL1Resume;
1002 
1003     if (hostHandle == NULL)
1004     {
1005         return kStatus_USB_InvalidHandle;
1006     }
1007     hostInstance = (usb_host_instance_t *)hostHandle;
1008 
1009     if (1U == sleepType)
1010     {
1011         /* the callbackFn is initialized in USB_HostGetControllerInterface */
1012         status =
1013             hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type);
1014     }
1015     else
1016     {
1017 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1018         /*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/
1019 
1020 #endif
1021         if (hostInstance->deviceList == deviceHandle)
1022         {
1023             /* the callbackFn is initialized in USB_HostGetControllerInterface */
1024             status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
1025                                                                     &type);
1026         }
1027     }
1028 
1029     return status;
1030 }
1031 #endif
1032 /* Update HW tick(unit is ms) */
USB_HostUpdateHwTick(usb_host_handle hostHandle,uint64_t tick)1033 usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick)
1034 {
1035     usb_host_instance_t *hostInstance;
1036     usb_status_t status = kStatus_USB_Success;
1037 
1038     if (hostHandle == NULL)
1039     {
1040         return kStatus_USB_InvalidHandle;
1041     }
1042     hostInstance = (usb_host_instance_t *)hostHandle;
1043 
1044     hostInstance->hwTick = tick;
1045 
1046     return status;
1047 }
1048 #endif
1049 
1050 #if ((defined(USB_HOST_CONFIG_BATTERY_CHARGER)) && (USB_HOST_CONFIG_BATTERY_CHARGER > 0U))
USB_HostSetChargerType(usb_host_handle hostHandle,uint8_t type)1051 usb_status_t USB_HostSetChargerType(usb_host_handle hostHandle, uint8_t type)
1052 {
1053     usb_host_instance_t *hostInstance;
1054 
1055     if (hostHandle == NULL)
1056     {
1057         return kStatus_USB_InvalidHandle;
1058     }
1059     hostInstance = (usb_host_instance_t *)hostHandle;
1060     return hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostSetChargerType,
1061                                                           &type);
1062 }
1063 #endif
1064