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