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