1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016,2019 - 2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #include "usb_host_config.h"
9 #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
10 #include "usb_host.h"
11 #include "usb_host_hci.h"
12 #include "usb_host_devices.h"
13 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
14 #include "usb_host_framework.h"
15 #endif
16 #include "fsl_device_registers.h"
17 #include "usb_host_ehci.h"
18 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT))
19 #include "usb_phy.h"
20 #endif
21 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
22 #include "usb_host.h"
23 #endif
24 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
25 #include "fsl_memory.h"
26 #endif
27 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
28 #include "fsl_cache.h"
29 #endif
30 
31 /*******************************************************************************
32  * Definitions
33  ******************************************************************************/
34 
35 #if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U)
36 
37 #error The SOC does not suppoort dedicated RAM case.
38 
39 #endif
40 
41 #define USB_HOST_EHCI_BANDWIDTH_DELAY             (3500U)
42 #define USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP      (333U)
43 #define USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME (900U)
44 
45 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
46 #define USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH     (18U)
47 #define USB_HOST_EHCI_PORTSC_PTC_J_STATE         (0x01U)
48 #define USB_HOST_EHCI_PORTSC_PTC_K_STATE         (0x02U)
49 #define USB_HOST_EHCI_PORTSC_PTC_SE0_NAK         (0x03U)
50 #define USB_HOST_EHCI_PORTSC_PTC_PACKET          (0x04U)
51 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS (0x05U)
52 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_FS (0x06U)
53 #define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_LS (0x07U)
54 #endif
55 
56 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
57 #define USB_HOST_MEMORY_CPU_2_DMA(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_Local2DMA)
58 #define USB_HOST_MEMORY_DMA_2_CPU(x) MEMORY_ConvertMemoryMapAddress((uint32_t)(x), kMEMORY_DMA2Local)
59 #endif
60 
61 /*******************************************************************************
62  * Prototypes
63  ******************************************************************************/
64 /*!
65  * @brief compute data bandwidth time.
66  *
67  * @param speed       data speed.
68  * @param pipeType    data type.
69  * @param direction   data direction.
70  * @param dataLength  data length.
71  *
72  *@return time value.
73  */
74 static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength);
75 
76 /*!
77  * @brief compute current allocated bandwidth when ehci work as full-speed or low-speed host.
78  *
79  * @param ehciInstance    ehci instance pointer.
80  * @param frameIndex      frame index.
81  * @param frameBandwidths return frame bandwidth data.
82  */
83 static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
84                                                     uint16_t frameIndex,
85                                                     uint16_t *frameBandwidth);
86 
87 /*!
88  * @brief compute current hub's allocated FS/LS bandwidth when ehci work as hi-speed host.
89  *
90  * @param ehciInstance    ehci instance pointer.
91  * @param hubNumber       hub address.
92  * @param frameIndex      frame index.
93  * @param frameBandwidths return frame bandwidth data.
94  */
95 static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
96                                                       uint32_t hubNumber,
97                                                       uint16_t frameIndex,
98                                                       uint16_t frameBandwidths[8]);
99 
100 /*!
101  * @brief compute current allocated HS bandwidth when ehci work as hi-speed host.
102  *
103  * @param ehciInstance         ehci instance pointer.
104  * @param frameIndex      frame index.
105  * @param frameBandwidths return frame bandwidth data.
106  */
107 static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
108                                                        uint16_t frameIndex,
109                                                        uint16_t frameBandwidths[8]);
110 
111 /*!
112  * @brief allocate HS bandwidth when host work as high-speed host.
113  *
114  * @param ehciInstance         ehci instance pointer.
115  * @param uframeInterval  micro-frame interval.
116  * @param timeData        time for allocating.
117  * @param uframe_index_out return start uframe index.
118  *
119  * @return kStatus_USB_Success or error codes.
120  */
121 static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
122                                                             uint16_t uframeInterval,
123                                                             uint16_t timeData,
124                                                             uint16_t *uframeIndexOut);
125 
126 /*!
127  * @brief allocate HS interrupt bandwidth when host work as high-speed host.
128  *
129  * @param ehciInstance         ehci instance pointer.
130  * @param ehciPipePointer    ehci pipe pointer.
131  *
132  * @return kStatus_USB_Success or error codes.
133  */
134 static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
135                                                              usb_host_ehci_pipe_t *ehciPipePointer);
136 
137 /*!
138  * @brief allocate bandwidth when host work as full-speed or low-speed host.
139  *
140  * @param ehciInstance         ehci instance pointer.
141  * @param ehciPipePointer    ehci pipe pointer.
142  *
143  * @return kStatus_USB_Success or error codes.
144  */
145 static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
146                                                       usb_host_ehci_pipe_t *ehciPipePointer);
147 
148 /*!
149  * @brief get the 2 power value of uint8_t.
150  *
151  * @param value     input uint8_t value.
152  */
153 static uint8_t USB_HostEhciGet2PowerValue(uint8_t value);
154 
155 /*!
156  * @brief memory zero.
157  *
158  * @param buffer     buffer pointer.
159  * @param length     buffer length.
160  */
161 static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length);
162 
163 /*!
164  * @brief host ehci delay.
165  *
166  * @param ehciIpBase     ehci ip base address.
167  * @param ms          millisecond.
168  */
169 static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms);
170 
171 /*!
172  * @brief host ehci start async schedule.
173  *
174  * @param ehciInstance    ehci instance pointer.
175  */
176 static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance);
177 
178 /*!
179  * @brief host ehci stop async schedule.
180  *
181  * @param ehciInstance    ehci instance pointer.
182  */
183 static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance);
184 
185 /*!
186  * @brief host ehci start periodic schedule.
187  *
188  * @param ehciInstance    ehci instance pointer.
189  */
190 static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance);
191 
192 /*!
193  * @brief host ehci stop periodic schedule.
194  *
195  * @param ehciInstance    ehci instance pointer.
196  */
197 static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance);
198 
199 /*!
200  * @brief initialize the qtd for one transfer.
201  *
202  * @param ehciInstance      ehci instance pointer.
203  * @param ehciPipePointer ehci pipe pointer.
204  * @param transfer      transfer information.
205  *
206  *@return kStatus_USB_Success or error codes.
207  */
208 static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
209                                               usb_host_ehci_pipe_t *ehciPipePointer,
210                                               usb_host_transfer_t *transfer);
211 
212 /*!
213  * @brief release the qtd list.
214  *
215  * @param ehciInstance   ehci instance pointer.
216  * @param ehciQtdStart   qtd list start pointer.
217  * @param ehciQtdEnd     qtd list end pointer.
218  *
219  *@return the transfer's length.
220  */
221 static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
222                                            usb_host_ehci_qtd_t *ehciQtdStart,
223                                            usb_host_ehci_qtd_t *ehciQtdEnd);
224 
225 /*!
226  * @brief de-initialize qh's linking qtd list.
227  * 1. remove qtd from qh; 2. remove transfer from qh; 3. release qtd; 4. transfer callback.
228  *
229  * @param ehciInstance    ehci instance pointer.
230  * @param ehciPipePointer ehci pipe.
231  *
232  *@return kStatus_USB_Success or error codes.
233  */
234 static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
235                                                 usb_host_ehci_pipe_t *ehciPipePointer);
236 
237 /*!
238  * @brief de-initialize transfer's linking qtd list.
239  * 1. stop this qh schedule; 2. remove qtd from qh; 3. remove transfer from qh; 4. release qtd; 5. transfer callback; 6.
240  *start this qh schedule.
241  *
242  * @param ehciInstance    ehci instance pointer.
243  * @param ehciPipePointer ehci pipe pointer.
244  * @param transfer        transfer information.
245  *
246  *@return kStatus_USB_Success or error codes.
247  */
248 static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
249                                                       usb_host_ehci_pipe_t *ehciPipePointer,
250                                                       usb_host_transfer_t *transfer);
251 
252 /*!
253  * @brief initialize QH when opening one control, bulk or interrupt pipe.
254  *
255  * @param ehciInstance       ehci instance pointer.
256  * @param ehciPipePointer    ehci pipe pointer.
257  *
258  * @return kStatus_USB_Success or error codes.
259  */
260 static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
261 
262 /*!
263  * @brief de-initialize QH when closing one control, bulk or interrupt pipe.
264  *
265  * @param ehciInstance       ehci instance pointer.
266  * @param ehciPipePointer    ehci pipe pointer.
267  *
268  * @return kStatus_USB_Success or error codes.
269  */
270 static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
271 
272 /*!
273  * @brief add qh to one frame entry.
274  *
275  * @param ehciInstance      ehci instance pointer.
276  * @param entryPointerValue entry pointer value.
277  * @param framePos          frame index.
278  * @param uframeInterval    micro-frame interval.
279  */
280 static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
281                                      uint32_t entryPointerValue,
282                                      uint16_t framePos,
283                                      uint16_t uframeInterval);
284 
285 /*!
286  * @brief remove entry from frame list.
287  *
288  * @param ehciInstance      ehci instance pointer.
289  * @param entryPointerValue entry pointer value.
290  * @param framePos          frame index.
291  */
292 static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
293                                         uint32_t entryPointerValue,
294                                         uint16_t framePos);
295 
296 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
297 /*!
298  * @brief add sitd array to the frame list.
299  *
300  * @param ehciInstance      ehci instance pointer.
301  * @param entryPointerValue entry pointer value.
302  * @param startEntryPointer sitd entry pointer.
303  */
304 static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
305                                  usb_host_ehci_pipe_t *ehciPipePointer,
306                                  void *startEntryPointer);
307 
308 /*!
309  * @brief initialize sitd array for one transfer.
310  *
311  * @param ehciInstance      ehci instance pointer.
312  * @param ehciPipePointer   ehci pipe pointer.
313  * @param transfer          transfer information.
314  */
315 static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
316                                               usb_host_ehci_pipe_t *ehciPipePointer,
317                                               usb_host_transfer_t *transfer);
318 
319 /*!
320  * @brief release sitd list.
321  *
322  * @param ehciInstance     ehci instance pointer.
323  * @param startSitdPointer start sitd pointer.
324  * @param endSitdPointer   end sitd pointer.
325  *
326  * @return transfer's result length.
327  */
328 static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
329                                              usb_host_ehci_sitd_t *startSitdPointer,
330                                              usb_host_ehci_sitd_t *endSitdPointer);
331 
332 /*!
333  * @brief de-initialize sitd list.
334  * 1. remove transfer; 2. remove sitd from frame list and release sitd; 3. transfer callback
335  *
336  * @param ehciInstance    ehci instance pointer.
337  * @param ehciPipePointer ehci pipe pointer.
338  *
339  * @return kStatus_USB_Success or error codes.
340  */
341 static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
342                                                 usb_host_ehci_pipe_t *ehciPipePointer);
343 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
344 
345 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
346 /*!
347  * @brief compute the frame index when inserting itd.
348  *
349  * @param ehciInstance    ehci instance pointer.
350  * @param lastLinkUframe  last inserted micro-frame.
351  * @param startUframe     start micro-frame.
352  * @param uframeInterval  micro-frame interval.
353  *
354  * @return frame index
355  */
356 static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
357                                             uint32_t lastLinkUframe,
358                                             uint16_t startUframe,
359                                             uint16_t uframeInterval);
360 
361 /*!
362  * @brief initialize itd list for one transfer.
363  * 1. initialize itd list; 2. insert itd to frame list.
364  *
365  * @param ehciInstance    ehci instance pointer.
366  * @param ehciPipePointer ehci pipe pointer.
367  * @param transfer        transfer information.
368  *
369  * @return kStatus_USB_Success or error codes.
370  */
371 static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
372                                              usb_host_ehci_pipe_t *ehciPipePointer,
373                                              usb_host_transfer_t *transfer);
374 
375 /*!
376  * @brief release itd list.
377  *
378  * @param ehciInstance    ehci instance pointer.
379  * @param startItdPointer start itd pointer.
380  * @param endItdPointer   end itd pointer.
381  *
382  * @return transfer's result length.
383  */
384 static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
385                                             usb_host_ehci_itd_t *startItdPointer,
386                                             usb_host_ehci_itd_t *endItdPointer);
387 
388 /*!
389  * @brief de-initialize itd list.
390  * 1. remove transfer; 2. remove itd from frame list and release itd; 3. transfer callback
391  *
392  * @param ehciInstance    ehci instance pointer.
393  * @param ehciPipePointer ehci pipe pointer.
394  *
395  * @return kStatus_USB_Success or error codes.
396  */
397 static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
398                                                usb_host_ehci_pipe_t *ehciPipePointer);
399 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
400 
401 /*!
402  * @brief open control or bulk pipe.
403  *
404  * @param ehciInstance    ehci instance pointer.
405  * @param ehciPipePointer ehci pipe pointer.
406  *
407  * @return kStatus_USB_Success or error codes.
408  */
409 static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
410                                                 usb_host_ehci_pipe_t *ehciPipePointer);
411 
412 /*!
413  * @brief close control or bulk pipe.
414  *
415  * @param ehciInstance    ehci instance pointer.
416  * @param ehciPipePointer ehci pipe pointer.
417  *
418  * @return kStatus_USB_Success or error codes.
419  */
420 static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
421                                                  usb_host_ehci_pipe_t *ehciPipePointer);
422 
423 /*!
424  * @brief open interrupt pipe.
425  *
426  * @param ehciInstance    ehci instance pointer.
427  * @param ehciPipePointer ehci pipe pointer.
428  *
429  * @return kStatus_USB_Success or error codes.
430  */
431 static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
432                                               usb_host_ehci_pipe_t *ehciPipePointer);
433 
434 /*!
435  * @brief close interrupt pipe.
436  *
437  * @param ehciInstance    ehci instance pointer.
438  * @param ehciPipePointer ehci pipe pointer.
439  *
440  * @return kStatus_USB_Success or error codes.
441  */
442 static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
443                                                usb_host_ehci_pipe_t *ehciPipePointer);
444 
445 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
446      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
447 /*!
448  * @brief open iso pipe.
449  *
450  * @param ehciInstance    ehci instance pointer.
451  * @param ehciPipePointer ehci pipe pointer.
452  *
453  * @return kStatus_USB_Success or error codes.
454  */
455 static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
456 
457 /*!
458  * @brief close iso pipe.
459  *
460  * @param ehciInstance    ehci instance pointer.
461  * @param ehciPipePointer ehci pipe pointer.
462  *
463  * @return kStatus_USB_Success or error codes.
464  */
465 static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer);
466 
467 /*!
468  * @brief allocate HS iso bandwidth when host work as high-speed host.
469  *
470  * @param ehciInstance         ehci instance pointer.
471  * @param ehciPipePointer    ehci pipe pointer.
472  *
473  * @return kStatus_USB_Success or error codes.
474  */
475 static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
476                                                        usb_host_ehci_pipe_t *ehciPipePointer);
477 
478 #endif
479 
480 /*!
481  * @brief reset ehci ip.
482  *
483  * @param ehciInstance      ehci instance pointer.
484  *
485  * @return kStatus_USB_Success or error codes.
486  */
487 static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance);
488 
489 /*!
490  * @brief start ehci ip.
491  *
492  * @param ehciInstance      ehci instance pointer.
493  *
494  * @return kStatus_USB_Success or error codes.
495  */
496 static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance);
497 
498 /*!
499  * @brief cancel pipe's transfers.
500  *
501  * @param ehciInstance    ehci instance pointer.
502  * @param ehciPipePointer ehci pipe pointer.
503  * @param transfer        the canceling transfer.
504  *
505  * @return kStatus_USB_Success or error codes.
506  */
507 static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
508                                            usb_host_ehci_pipe_t *ehciPipePointer,
509                                            usb_host_transfer_t *transfer);
510 
511 /*!
512  * @brief control ehci bus.
513  *
514  * @param ehciInstance  ehci instance pointer.
515  * @param bus_control   control code.
516  *
517  * @return kStatus_USB_Success or error codes.
518  */
519 static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl);
520 
521 /*!
522  * @brief ehci transaction done process function.
523  *
524  * @param ehciInstance      ehci instance pointer.
525  */
526 void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance);
527 
528 /*!
529  * @brief ehci port change interrupt process function.
530  *
531  * @param ehciInstance      ehci instance pointer.
532  */
533 static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance);
534 
535 /*!
536  * @brief ehci timer0 interrupt process function.
537  * cancel control/bulk transfer that time out.
538  *
539  * @param ehciInstance      ehci instance pointer.
540  */
541 static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance);
542 
543 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
544 /*!
545  * @brief ehci timer1 interrupt process function.
546  * cancel control/bulk transfer that time out.
547  *
548  * @param ehciInstance      ehci instance pointer.
549  */
550 static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance);
551 
552 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
553 /*!
554  * @brief ehci host completed LPM interrupt process function
555  *
556  * @param ehciInstance      ehci instance pointer.
557  */
558 static void USB_HostEhciCompletedLPM(usb_host_ehci_instance_t *ehciInstance);
559 #endif
560 
561 #endif
562 
563 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
564 /*!
565  * @brief suspend bus.
566  *
567  * @param ehciInstance      ehci instance pointer.
568  */
569 static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance);
570 
571 /*!
572  * @brief resume bus.
573  *
574  * @param ehciInstance      ehci instance pointer.
575  */
576 static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance);
577 
578 extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
579                                                      usb_host_transfer_t *transfer,
580                                                      void *param);
581 #endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
582 
583 /*!
584  * @brief transfer callback.
585  *
586  * @param transfer    transfer information.
587  * @param status      transfer status.
588  */
589 static void USB_HostEhciTransferCallback(usb_host_transfer_t *transfer, usb_status_t status);
590 
591 /*******************************************************************************
592  * Variables
593  ******************************************************************************/
594 
595 /* EHCI controller driver instances. */
596 #if (USB_HOST_CONFIG_EHCI == 1U)
597 USB_RAM_ADDRESS_ALIGNMENT(4096)
598 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
599 
600 static uint8_t usbHostEhciFramListStatus[1] = {0};
601 
602 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
603 #elif (USB_HOST_CONFIG_EHCI == 2U)
604 USB_RAM_ADDRESS_ALIGNMENT(4096)
605 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
606 USB_RAM_ADDRESS_ALIGNMENT(4096)
607 USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4];
608 static uint8_t usbHostEhciFramListStatus[2] = {0, 0};
609 
610 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1;
611 USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2;
612 #else
613 #error "Please increase the instance count."
614 #endif
615 #define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
616 #define USB_HOST_EHCI_MAX_MICRFRAME_VALUE    ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3U) - 1U)
617 
618 static uint8_t s_SlotMaxBandwidth[8]   = {125, 125, 125, 125, 125, 125, 50, 0};
619 static uint8_t s_SlotMaxBandwidthHs[8] = {100, 100, 100, 100, 100, 100, 100, 100};
620 
621 /*******************************************************************************
622  * Code
623  ******************************************************************************/
624 /*!
625  * @brief EHCI NC get USB NC bass address.
626  *
627  * This function is used to get USB NC bass address.
628  *
629  * @param[in] controllerId    EHCI controller ID; See the #usb_controller_index_t.
630  *
631  * @retval USB NC bass address.
632  */
633 #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
634 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
USB_EhciNCGetBase(uint8_t controllerId)635 static void *USB_EhciNCGetBase(uint8_t controllerId)
636 {
637     void *usbNCBase = NULL;
638 #if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
639     uint32_t instance_count;
640 #if defined(USBNC_STACK_BASE_ADDRS)
641     uint32_t usbnc_base[] = USBNC_STACK_BASE_ADDRS;
642 #else
643     uint32_t usbnc_base[] = USBNC_BASE_ADDRS;
644 #endif
645 
646     if (controllerId < (uint8_t)kUSB_ControllerEhci0)
647     {
648         return NULL;
649     }
650 
651     controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
652 
653     instance_count = sizeof(usbnc_base) / sizeof(usbnc_base[0]);
654     if (controllerId >= instance_count)
655     {
656         return NULL;
657     }
658 
659     usbNCBase = (void *)(uint8_t *)usbnc_base[controllerId];
660 #endif
661     return usbNCBase;
662 }
663 #endif
664 #endif
665 
666 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
667 
USB_HostEhciTestSetMode(usb_host_ehci_instance_t * ehciInstance,uint32_t testMode)668 usb_status_t USB_HostEhciTestSetMode(usb_host_ehci_instance_t *ehciInstance, uint32_t testMode)
669 {
670     uint32_t ehciPortSC;
671 
672     ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
673     ehciPortSC &= ~((uint32_t)USBHS_PORTSC1_PTC_MASK);   /* clear test mode bits */
674     ehciPortSC |= (testMode << USBHS_PORTSC1_PTC_SHIFT); /* set test mode bits */
675     ehciInstance->ehciIpBase->PORTSC1 = ehciPortSC;
676     return kStatus_USB_Success;
677 }
678 
USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t * ehciInstance)679 static void USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t *ehciInstance)
680 {
681     uint8_t timeCount;
682     timeCount = 15; /* 15s */
683     while (timeCount--)
684     {
685         USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
686     }
687     USB_HostEhciSuspendBus(ehciInstance);
688     timeCount = 15; /* 15s */
689     while (timeCount--)
690     {
691         USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
692     }
693 
694     USB_HostEhciResumeBus(ehciInstance);
695 }
696 
USB_HostEhciTestCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)697 static void USB_HostEhciTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
698 {
699     USB_HostFreeTransfer(param, transfer);
700 }
701 
USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t * ehciInstance,usb_device_handle deviceHandle)702 static void USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t *ehciInstance,
703                                                     usb_device_handle deviceHandle)
704 {
705     usb_host_process_descriptor_param_t getDescriptorParam;
706     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
707     usb_host_transfer_t *transfer;
708     uint8_t timeCount;
709     USB_HostEhciLock();
710     /* disable periodic shedule */
711     USB_HostEhciStopPeriodic(ehciInstance);
712     USB_HostEhciUnlock();
713 
714     timeCount = 15; /* 15s */
715     while (timeCount--)
716     {
717         USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
718     }
719 
720     /* malloc one transfer */
721     if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
722     {
723 #ifdef HOST_ECHO
724         usb_echo("allocate transfer error\r\n");
725 #endif
726         return;
727     }
728 
729     getDescriptorParam.descriptorLength  = sizeof(usb_descriptor_device_t);
730     getDescriptorParam.descriptorLength  = 18;
731     getDescriptorParam.descriptorBuffer  = (uint8_t *)&deviceInstance->deviceDescriptor;
732     getDescriptorParam.descriptorType    = USB_DESCRIPTOR_TYPE_DEVICE;
733     getDescriptorParam.descriptorIndex   = 0;
734     getDescriptorParam.languageId        = 0;
735     transfer->callbackFn                 = USB_HostEhciTestCallback;
736     transfer->callbackParam              = ehciInstance->hostHandle;
737     transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
738     transfer->setupPacket->bRequest      = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
739     transfer->setupPacket->wIndex        = 0;
740     transfer->setupPacket->wLength       = 0;
741     transfer->setupPacket->wValue        = 0;
742     USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
743 }
744 
USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer,uint8_t setupPhase)745 static usb_status_t USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t *ehciInstance,
746                                                       usb_host_ehci_pipe_t *ehciPipePointer,
747                                                       usb_host_transfer_t *transfer,
748                                                       uint8_t setupPhase)
749 {
750     volatile usb_host_ehci_qh_t *vltQhPointer;
751     usb_host_ehci_qtd_t *qtdPointer = NULL;
752     volatile uint32_t *entryPointer;
753     uint32_t qtdNumber;
754     uint32_t dataLength;
755     uint32_t dataAddress;
756     uint8_t index;
757 
758     /* compute the qtd number */
759     qtdNumber = 1;
760 
761     vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
762     /* get qtd list */
763     USB_HostEhciLock();
764     if (qtdNumber <= ehciInstance->ehciQtdNumber)
765     {
766         ehciInstance->ehciQtdNumber -= qtdNumber;
767         qtdPointer = NULL;
768         do
769         {
770             if (qtdPointer != NULL)
771             {
772                 qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
773             }
774             qtdPointer                 = ehciInstance->ehciQtdHead;
775             ehciInstance->ehciQtdHead  = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
776             qtdPointer->nextQtdPointer = 0;
777         } while (--qtdNumber);
778     }
779     else
780     {
781         USB_HostEhciUnlock();
782         return kStatus_USB_Error;
783     }
784     USB_HostEhciUnlock();
785 
786     /* int qTD */
787     if (setupPhase == 1) /* setup transaction qtd init */
788     {
789         qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
790         /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
791         qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
792         qtdPointer->transferResults[0] =
793             ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
794              (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
795         dataAddress                    = (uint32_t)(transfer->setupPacket);
796         qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
797         /* set buffer pointer no matter data length */
798         for (index = 0; index < 4; ++index)
799         {
800             qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
801         }
802     }
803     else if (setupPhase == 2) /* data transaction qtd */
804     {
805         dataLength = transfer->transferLength;
806         if (dataLength != 0)
807         {
808             qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
809             /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
810             qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
811 
812             qtdPointer->transferResults[0] =
813                 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
814                  (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
815 
816             dataAddress                    = (uint32_t)(transfer->transferBuffer);
817             qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
818             /* set buffer pointer no matter data length */
819             for (index = 0; index < 4; ++index)
820             {
821                 qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000);
822             }
823         }
824     }
825     else if (setupPhase == 3)
826     {
827         /* status transaction qtd */
828         qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
829         /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
830         qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0;
831 
832         qtdPointer->transferResults[0] =
833             ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
834              (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
835 
836         qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
837     }
838     qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
839     qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* set IOC */
840 
841     /* save qtd to transfer */
842     transfer->union1.unitHead = (uint32_t)qtdPointer;
843     transfer->union2.unitTail = (uint32_t)qtdPointer;
844     /* link transfer to qh */
845     transfer->next = NULL;
846     if (vltQhPointer->ehciTransferHead == NULL)
847     {
848         transfer->next                 = NULL;
849         vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer;
850     }
851     else
852     {
853         transfer->next                       = NULL;
854         vltQhPointer->ehciTransferTail->next = transfer;
855         vltQhPointer->ehciTransferTail       = transfer;
856     }
857 
858     USB_HostEhciLock();
859     /* link qtd to qh (link to end) */
860     entryPointer = &(vltQhPointer->nextQtdPointer);
861     dataAddress  = *entryPointer; /* dataAddress variable means entry value here */
862     while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE)))
863     {
864         entryPointer = (volatile uint32_t *)dataAddress;
865         dataAddress  = *entryPointer;
866     }
867 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
868     *entryPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(qtdPointer);
869 #else
870     *entryPointer = (uint32_t)qtdPointer;
871 #endif
872     USB_HostEhciStartAsync(ehciInstance);
873     USB_HostEhciUnlock();
874 
875     return kStatus_USB_Success;
876 }
877 
USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t * ehciInstance,usb_device_handle deviceHandle)878 static void USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t *ehciInstance,
879                                                         usb_device_handle deviceHandle)
880 {
881     static uint8_t buffer[USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH];
882     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
883     usb_host_transfer_t *transfer;
884     uint8_t timeCount;
885     USB_HostEhciLock();
886     USB_HostEhciStopPeriodic(ehciInstance);
887     USB_HostEhciUnlock();
888 
889     if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
890     {
891         return;
892     }
893     transfer->callbackFn                 = USB_HostEhciTestCallback;
894     transfer->callbackParam              = ehciInstance->hostHandle;
895     transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN;
896     transfer->setupPacket->bRequest      = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
897     transfer->setupPacket->wLength       = USB_SHORT_TO_LITTLE_ENDIAN(USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH);
898     transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)((uint16_t)USB_DESCRIPTOR_TYPE_DEVICE << 8));
899     transfer->setupPacket->wIndex = 0;
900     USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 1);
901 
902     timeCount = 15; /* 15s */
903     while (timeCount--)
904     {
905         USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
906     }
907 
908     if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
909     {
910         return;
911     }
912     transfer->callbackFn     = USB_HostEhciTestCallback;
913     transfer->callbackParam  = ehciInstance->hostHandle;
914     transfer->transferBuffer = buffer;
915     transfer->transferLength = USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH;
916     USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 2);
917 
918     if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success)
919     {
920         return;
921     }
922     transfer->callbackFn     = USB_HostEhciTestCallback;
923     transfer->callbackParam  = ehciInstance->hostHandle;
924     transfer->transferBuffer = NULL;
925     transfer->transferLength = 0;
926     USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 3);
927 
928     timeCount = 15; /* 15s */
929     while (timeCount--)
930     {
931         USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U);
932     }
933 
934     usb_echo("test_single_step_get_dev_desc_data finished\r\n");
935 
936     return;
937 }
938 
USB_HostEhciTestModeInit(usb_device_handle deviceHandle)939 static void USB_HostEhciTestModeInit(usb_device_handle deviceHandle)
940 {
941     uint32_t productId;
942     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
943     usb_host_ehci_instance_t *ehciInstance =
944         (usb_host_ehci_instance_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle);
945 
946     USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
947 
948     usb_echo("usb host ehci test mode init  product id:0x%x\r\n", productId);
949 
950     switch (productId)
951     {
952         case 0x0101U:
953             USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_SE0_NAK);
954             break;
955         case 0x0102U:
956             USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_J_STATE);
957             break;
958         case 0x0103U:
959             USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_K_STATE);
960             break;
961         case 0x0104U:
962             USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_PACKET);
963             break;
964         case 0x0105U:
965             usb_echo("set test mode FORCE_ENALBE_HS\r\n");
966             USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS);
967             break;
968         case 0x0106U:
969             USB_HostEhciTestSuspendResume(ehciInstance);
970             break;
971         case 0x0107U:
972             usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n");
973             USB_HostEhciTestSingleStepGetDeviceDesc(ehciInstance, deviceHandle);
974             break;
975         case 0x0108U:
976             usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n");
977             USB_HostEhciTestSingleStepGetDeviceDescData(ehciInstance, deviceHandle);
978             break;
979         default:
980             /*no action */
981             break;
982     }
983 
984     return;
985 }
986 
USB_HostEhciSuspendBus(usb_host_ehci_instance_t * ehciInstance)987 static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance)
988 {
989     uint32_t ehciPortSC;
990 
991     USB_HostEhciLock();
992     ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
993     if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
994     {
995         ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
996         ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
997         ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_SUSP_MASK);
998     }
999     USB_HostEhciUnlock();
1000 }
1001 
USB_HostEhciResumeBus(usb_host_ehci_instance_t * ehciInstance)1002 static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance)
1003 {
1004     uint32_t ehciPortSC;
1005 
1006     USB_HostEhciLock();
1007     /* Resume port */
1008     ehciPortSC = ehciInstance->ehciIpBase->PORTSC1;
1009     if (ehciPortSC & USBHS_PORTSC1_PE_MASK)
1010     {
1011         ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS);
1012         ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_FPR_MASK);
1013     }
1014     USB_HostEhciUnlock();
1015 }
1016 #endif
1017 
USB_HostBandwidthComputeTime(uint8_t speed,uint8_t pipeType,uint8_t direction,uint32_t dataLength)1018 static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
1019 {
1020     uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
1021 
1022     if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
1023     {
1024         if (speed == USB_SPEED_HIGH)
1025         {
1026             result = 38U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1027         }
1028         else if (speed == USB_SPEED_FULL)
1029         {
1030             if (direction == USB_IN)
1031             {
1032                 result = 7268000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1033             }
1034             else
1035             {
1036                 result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1037             }
1038         }
1039         else
1040         {
1041             /*no action*/
1042         }
1043     }
1044     else /* interrupt */
1045     {
1046         if (speed == USB_SPEED_HIGH)
1047         {
1048             result = 55U * 8U * 2083U + 2083U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1049         }
1050         else if (speed == USB_SPEED_FULL)
1051         {
1052             result = 9107000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1053         }
1054         else if (speed == USB_SPEED_LOW)
1055         {
1056             if (direction == USB_IN)
1057             {
1058                 result = 64060000U + 2000U * USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP + 676670U * result +
1059                          USB_HOST_EHCI_BANDWIDTH_DELAY;
1060             }
1061             else
1062             {
1063                 result = 6265000U + 83540U * result + USB_HOST_EHCI_BANDWIDTH_DELAY;
1064             }
1065         }
1066         else
1067         {
1068             /*no action*/
1069         }
1070     }
1071 
1072     result /= 1000000U;
1073     if (result == 0U)
1074     {
1075         result = 1U;
1076     }
1077 
1078     return result;
1079 }
1080 
USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t * ehciInstance,uint16_t frameIndex,uint16_t * frameBandwidth)1081 static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance,
1082                                                     uint16_t frameIndex,
1083                                                     uint16_t *frameBandwidth)
1084 {
1085     usb_host_ehci_pipe_t *ehciPipePointer;
1086     void *temp;
1087     /* clear the bandwidth */
1088     *frameBandwidth = 0;
1089 
1090     ehciPipePointer = ehciInstance->ehciRunningPipeList;
1091     while (ehciPipePointer != NULL)
1092     {
1093         /* only compute iso and interrupt pipe */
1094         if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1095             (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1096         {
1097             /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
1098             if ((frameIndex >= ehciPipePointer->startFrame) &&
1099                 (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1100                         ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
1101             {
1102                 *frameBandwidth += ehciPipePointer->dataTime;
1103             }
1104         }
1105         temp            = (void *)ehciPipePointer->pipeCommon.next;
1106         ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1107     }
1108 }
1109 
USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t * ehciInstance,uint32_t hubNumber,uint16_t frameIndex,uint16_t frameBandwidths[8])1110 static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance,
1111                                                       uint32_t hubNumber,
1112                                                       uint16_t frameIndex,
1113                                                       uint16_t frameBandwidths[8])
1114 {
1115     usb_host_ehci_pipe_t *ehciPipePointer;
1116     uint8_t index;
1117     uint32_t deviceInfo = 0U;
1118     void *temp;
1119 
1120     for (index = 0; index < 8U; ++index)
1121     {
1122         frameBandwidths[index] = 0;
1123     }
1124 
1125     ehciPipePointer = ehciInstance->ehciRunningPipeList;
1126     while (ehciPipePointer != NULL)
1127     {
1128         /* only compute iso and interrupt pipe */
1129         if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1130             (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1131         {
1132             /* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from
1133              * first parent high-speed hub */
1134             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1135                                                          (uint32_t)kUSB_HostGetDeviceHSHubNumber, &deviceInfo);
1136             if (deviceInfo != hubNumber)
1137             {
1138                 temp            = (void *)ehciPipePointer->pipeCommon.next;
1139                 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1140                 continue;
1141             }
1142             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1143                                                          (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1144             if (deviceInfo == USB_SPEED_HIGH)
1145             {
1146                 temp            = (void *)ehciPipePointer->pipeCommon.next;
1147                 ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1148                 continue;
1149             }
1150 
1151             /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */
1152             if ((frameIndex >= ehciPipePointer->startFrame) &&
1153                 (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1154                         ((uint32_t)ehciPipePointer->pipeCommon.interval - 1U))))
1155             {
1156                 if (ehciPipePointer->pipeCommon.pipeType ==
1157                     USB_ENDPOINT_ISOCHRONOUS) /* iso bandwidth is allocated once */
1158                 {
1159                     frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
1160                 }
1161                 else /* iso bandwidth is allocated three times */
1162                 {
1163                     frameBandwidths[ehciPipePointer->startUframe + 1U] += ehciPipePointer->dataTime;
1164                     frameBandwidths[ehciPipePointer->startUframe + 2U] += ehciPipePointer->dataTime;
1165                     frameBandwidths[ehciPipePointer->startUframe + 3U] += ehciPipePointer->dataTime;
1166                 }
1167             }
1168         }
1169         temp            = (void *)ehciPipePointer->pipeCommon.next;
1170         ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1171     }
1172 
1173     for (index = 0; index < 7U; ++index) /*  */
1174     {
1175         if (frameBandwidths[index] > s_SlotMaxBandwidth[index])
1176         {
1177             frameBandwidths[index + 1U] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]);
1178             frameBandwidths[index] = s_SlotMaxBandwidth[index];
1179         }
1180     }
1181 }
1182 
USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t * ehciInstance,uint16_t frameIndex,uint16_t frameBandwidths[8])1183 static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance,
1184                                                        uint16_t frameIndex,
1185                                                        uint16_t frameBandwidths[8])
1186 {
1187     usb_host_ehci_pipe_t *ehciPipePointer;
1188     uint16_t index;
1189     uint32_t deviceInfo = 0U;
1190     uint16_t frameInterval;
1191     void *temp;
1192     for (index = 0; index < 8U; ++index)
1193     {
1194         frameBandwidths[index] = 0;
1195     }
1196 
1197     ehciPipePointer = ehciInstance->ehciRunningPipeList;
1198     while (ehciPipePointer != NULL)
1199     {
1200         /* only compute iso and interrupt pipe */
1201         if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
1202             (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
1203         {
1204             frameInterval = ehciPipePointer->pipeCommon.interval;
1205             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1206                                                          (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1207             if (deviceInfo == USB_SPEED_HIGH) /* high-speed data bandwidth */
1208             {
1209                 /* frameInterval means micro-frame here */
1210                 if (frameIndex >= ehciPipePointer->startFrame)
1211                 {
1212                     if ((frameInterval > 8U) &&
1213                         (frameIndex * 8U - ehciPipePointer->startFrame * 8U >= ehciPipePointer->startUframe))
1214                     {
1215                         if (0U == ((((uint32_t)frameIndex) * 8U - ehciPipePointer->startFrame * 8U -
1216                                     ehciPipePointer->startUframe) &
1217                                    ((uint32_t)frameInterval - 1U)))
1218                         {
1219                             frameBandwidths[ehciPipePointer->startUframe] += ehciPipePointer->dataTime;
1220                         }
1221                     }
1222                     else
1223                     {
1224                         for (index = ehciPipePointer->startUframe; index < 8U; index += frameInterval)
1225                         {
1226                             frameBandwidths[index] += ehciPipePointer->dataTime;
1227                         }
1228                     }
1229                 }
1230             }
1231             else /* full-speed split bandwidth */
1232             {
1233                 if ((frameIndex >= ehciPipePointer->startFrame) &&
1234                     (0U == ((uint32_t)((uint32_t)frameIndex - ehciPipePointer->startFrame) &
1235                             (uint32_t)((uint32_t)frameInterval - 1U))))
1236                 {
1237                     for (index = 0; index < 8U; ++index)
1238                     {
1239                         if (0U != ((uint32_t)(ehciPipePointer->uframeSmask) &
1240                                    (uint32_t)(0x01UL << index))) /* start-split micro-frames */
1241                         {
1242                             frameBandwidths[index] += ehciPipePointer->startSplitTime;
1243                         }
1244                         if (0U != ((uint32_t)(ehciPipePointer->uframeCmask) &
1245                                    (uint32_t)(0x01UL << index))) /* complete-split micro-frames */
1246                         {
1247                             frameBandwidths[index] += ehciPipePointer->completeSplitTime;
1248                         }
1249                     }
1250                 }
1251             }
1252         }
1253         temp            = (void *)ehciPipePointer->pipeCommon.next;
1254         ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
1255     }
1256 
1257 #if 0
1258     for (index = 0; index < 7; ++index) /*  */
1259     {
1260         if (frameBandwidths[index] > s_SlotMaxBandwidthHs[index])
1261         {
1262             frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidthHs[index]);
1263             frameBandwidths[index] = s_SlotMaxBandwidthHs[index];
1264         }
1265     }
1266 #endif
1267 }
1268 
1269 /*!
1270  * @brief allocate HS bandwidth when host work as high-speed host.
1271  *
1272  * @param ehciInstance         ehci instance pointer.
1273  * @param uframeInterval  micro-frame interval.
1274  * @param timeData        time for allocating.
1275  * @param uframeIndexOut return start uframe index.
1276  *
1277  * @return kStatus_USB_Success or error codes.
1278  */
USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t * ehciInstance,uint16_t uframeInterval,uint16_t timeData,uint16_t * uframeIndexOut)1279 static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance,
1280                                                             uint16_t uframeInterval,
1281                                                             uint16_t timeData,
1282                                                             uint16_t *uframeIndexOut)
1283 {
1284     uint16_t uframeIntervalIndex;
1285     uint16_t uframeIndex;
1286     uint16_t frameIndex;
1287     uint16_t frameTimes[8];
1288 
1289     frameIndex = 0;
1290     for (uint8_t i = 0; i < 8U; ++i)
1291     {
1292         frameTimes[i] = 0U;
1293     }
1294     USB_HostBandwidthHsHostComputeCurrentHsAll(
1295         ehciInstance, frameIndex, frameTimes); /* compute the allocated bandwidths in the frameIndex frame */
1296     for (uframeIntervalIndex = 0; (uframeIntervalIndex < uframeInterval); ++uframeIntervalIndex) /* start micro-frame */
1297     {
1298         /* for all the micro-frame in interval uframeInterval */
1299         for (uframeIndex = uframeIntervalIndex; uframeIndex < (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U);
1300              uframeIndex += uframeInterval)
1301         {
1302             if (frameIndex != (uframeIndex >> 3))
1303             {
1304                 frameIndex = (uframeIndex >> 3);
1305                 USB_HostBandwidthHsHostComputeCurrentHsAll(
1306                     ehciInstance, frameIndex,
1307                     frameTimes); /* compute the allocated bandwidths in the new frameIndex frame */
1308             }
1309             if (frameTimes[uframeIndex & 0x0007U] + timeData >
1310                 s_SlotMaxBandwidthHs[(uframeIndex & 0x0007U)]) /* micro-frame has enough idle bandwidth? */
1311             {
1312                 break; /* fail */
1313             }
1314         }
1315         if (uframeIndex >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8U)) /* success? */
1316         {
1317             break;
1318         }
1319     }
1320 
1321     if (uframeIntervalIndex < uframeInterval)
1322     {
1323         *uframeIndexOut = (uframeIntervalIndex);
1324         return kStatus_USB_Success;
1325     }
1326     else
1327     {
1328         return kStatus_USB_Error;
1329     }
1330 }
1331 
1332 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
1333      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
1334 
USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1335 static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance,
1336                                                        usb_host_ehci_pipe_t *ehciPipePointer)
1337 {
1338     usb_status_t status;
1339     uint32_t deviceInfo          = 0;
1340     uint32_t hubNumber           = 0;
1341     uint16_t uframeIntervalIndex = 0;
1342     uint16_t frameIntervalIndex  = 0;
1343     uint16_t frameIndex;
1344     uint16_t timeCompleteSplit;
1345     uint16_t timeStartSplit;
1346     uint32_t timeData;
1347     uint8_t SsCsNumber = 0;
1348     uint16_t frameInterval;
1349     uint16_t frameTimes[8];
1350     uint8_t allocateOk = 1;
1351     uint16_t index;
1352 
1353     for (uint8_t i = 0; i < 8U; ++i)
1354     {
1355         frameTimes[i] = 0U;
1356     }
1357     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1358                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1359 
1360     timeData = USB_HostBandwidthComputeTime(
1361         (uint8_t)deviceInfo, USB_ENDPOINT_ISOCHRONOUS, ehciPipePointer->pipeCommon.direction,
1362         (((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize) * ehciPipePointer->pipeCommon.numberPerUframe));
1363     /* pipe is high-speed */
1364     if (deviceInfo == USB_SPEED_HIGH)
1365     {
1366         uframeIntervalIndex = 0;
1367         status              = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
1368                                                          (uint16_t)timeData, &uframeIntervalIndex);
1369         if (status == kStatus_USB_Success)
1370         {
1371             ehciPipePointer->startFrame  = (uframeIntervalIndex / 8U);
1372             ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1373             ehciPipePointer->dataTime    = (uint16_t)timeData;
1374 
1375             return kStatus_USB_Success;
1376         }
1377     }
1378     else /* pipe is full-speed or low-speed */
1379     {
1380         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1381                                                      (uint32_t)kUSB_HostGetHubThinkTime,
1382                                                      &deviceInfo); /* deviceInfo variable means hub think time */
1383         timeData += (deviceInfo * 7U / (6U * 12U));
1384         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1385                                                      (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
1386         frameInterval = ehciPipePointer->pipeCommon.interval;
1387 
1388         /* compute start-split and complete-split bandwidth */
1389         if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1390         {
1391             timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_OUT,
1392                                                                     ehciPipePointer->pipeCommon.maxPacketSize);
1393             timeCompleteSplit = 0;
1394         }
1395         else
1396         {
1397             timeStartSplit =
1398                 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, 1);
1399             timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN,
1400                                                                        ehciPipePointer->pipeCommon.maxPacketSize);
1401         }
1402         /* note: bandwidth must put in one frame */
1403         for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 5U; ++uframeIntervalIndex) /* uframe interval */
1404         {
1405             for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
1406             {
1407                 allocateOk = 1;
1408                 for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1409                      frameIndex += frameInterval) /* check all the frames */
1410                 {
1411                     /* compute start-split and complete-split number */
1412                     SsCsNumber = (uint8_t)((ehciPipePointer->pipeCommon.maxPacketSize + 187U) /
1413                                            188U); /* ss number for iso out; cs number for iso in */
1414                     if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
1415                     {
1416                         if (uframeIntervalIndex + SsCsNumber > 8U)
1417                         {
1418                             allocateOk = 0U;
1419                         }
1420                     }
1421                     else
1422                     {
1423                         if (uframeIntervalIndex + 2U + SsCsNumber >
1424                             8U) /* ISO IN: there are two micro-frame interval between start-split and complete-split */
1425                         {
1426                             allocateOk = 0U;
1427                         }
1428                     }
1429                     if (0U != allocateOk)
1430                     {
1431                         /* allocate start-split and complete-split bandwidth */
1432                         USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
1433                         if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */
1434                         {
1435                             index = uframeIntervalIndex;
1436                             for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
1437                             {
1438                                 if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
1439                                 {
1440                                     allocateOk = 0U;
1441                                     break;
1442                                 }
1443                             }
1444                         }
1445                         else /* ISO IN */
1446                         {
1447                             index = uframeIntervalIndex;
1448                             if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidthHs[index])
1449                             {
1450                                 allocateOk = 0U;
1451                             }
1452                             if (0U != allocateOk)
1453                             {
1454                                 index =
1455                                     uframeIntervalIndex +
1456                                     2U; /* there are two micro-frames interval between start-split and complete-split */
1457                                 for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
1458                                 {
1459                                     if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
1460                                     {
1461                                         allocateOk = 0U;
1462                                         break;
1463                                     }
1464                                 }
1465                             }
1466                         }
1467                     }
1468 
1469                     /* allocate data bandwidth */
1470                     if (0U != allocateOk)
1471                     {
1472                         USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
1473                         index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
1474                         /* iso must occupy all the uframe bandwidth */
1475                         {
1476                             deviceInfo = timeData; /* note: deviceInfo variable means bandwidth here */
1477                             while ((index < 8U) && (deviceInfo > s_SlotMaxBandwidth[index]))
1478                             {
1479                                 if (frameTimes[index] > 0U)
1480                                 {
1481                                     allocateOk = 0U;
1482                                     break;
1483                                 }
1484                                 else
1485                                 {
1486                                     deviceInfo -= s_SlotMaxBandwidth[index];
1487                                 }
1488                                 ++index;
1489                             }
1490                         }
1491                     }
1492                     if (0U != allocateOk)
1493                     {
1494                         /* data bandwidth can be put in the frame? */
1495                         index = uframeIntervalIndex + 1U; /* timeData bandwidth start position */
1496                         frameTimes[index] += (uint16_t)timeData;
1497                         for (; index < 7U; ++index)
1498                         {
1499                             if (frameTimes[index] > s_SlotMaxBandwidth[index])
1500                             {
1501                                 frameTimes[index + 1U] += (frameTimes[index] - s_SlotMaxBandwidth[index]);
1502                                 frameTimes[index] = s_SlotMaxBandwidth[index];
1503                             }
1504                             else
1505                             {
1506                                 break;
1507                             }
1508                         }
1509                         if (frameTimes[index] > s_SlotMaxBandwidth[index])
1510                         {
1511                             allocateOk = 0;
1512                         }
1513                     }
1514 
1515                     if (0U != allocateOk)
1516                     {
1517                         break;
1518                     }
1519                 }
1520                 if (0U != allocateOk)
1521                 {
1522                     break;
1523                 }
1524             }
1525             if (0U != allocateOk)
1526             {
1527                 break;
1528             }
1529         }
1530 
1531         if (0U != allocateOk)
1532         {
1533             ehciPipePointer->startFrame        = frameIntervalIndex;
1534             ehciPipePointer->startUframe       = (uint8_t)uframeIntervalIndex;
1535             ehciPipePointer->dataTime          = (uint16_t)timeData;
1536             ehciPipePointer->startSplitTime    = timeStartSplit;
1537             ehciPipePointer->completeSplitTime = timeCompleteSplit;
1538             if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1539             {
1540                 index = uframeIntervalIndex;
1541                 for (; index < (uframeIntervalIndex + SsCsNumber); ++index)
1542                 {
1543                     ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
1544                 }
1545             }
1546             else
1547             {
1548                 index                        = uframeIntervalIndex;
1549                 ehciPipePointer->uframeSmask = ehciPipePointer->uframeSmask | (uint8_t)(0x01UL << index);
1550                 index                        = uframeIntervalIndex + 2U;
1551                 for (; index < (uframeIntervalIndex + 2U + SsCsNumber); ++index)
1552                 {
1553                     ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (uint8_t)(0x01UL << index);
1554                 }
1555             }
1556 
1557             return kStatus_USB_Success;
1558         }
1559     }
1560 
1561     return kStatus_USB_Error;
1562 }
1563 
1564 #endif
1565 
USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1566 static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance,
1567                                                              usb_host_ehci_pipe_t *ehciPipePointer)
1568 {
1569     usb_status_t status;
1570     uint32_t deviceInfo          = 0;
1571     uint32_t hubNumber           = 0;
1572     uint16_t uframeIntervalIndex = 0;
1573     uint16_t frameIntervalIndex  = 0;
1574     uint16_t frameIndex;
1575     uint16_t timeCompleteSplit;
1576     uint16_t timeStartSplit;
1577     uint32_t timeData;
1578     uint8_t SsCsNumber;
1579     uint16_t frameInterval;
1580     uint16_t frameTimes[8];
1581     uint8_t allocateOk = 1;
1582     uint8_t index;
1583 
1584     for (uint8_t i = 0; i < 8U; ++i)
1585     {
1586         frameTimes[i] = 0U;
1587     }
1588     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1589                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &deviceInfo);
1590 
1591     timeData = USB_HostBandwidthComputeTime(
1592         (uint8_t)deviceInfo, USB_ENDPOINT_INTERRUPT, ehciPipePointer->pipeCommon.direction,
1593         (uint32_t)ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe);
1594     /* pipe is high-speed */
1595     if (deviceInfo == USB_SPEED_HIGH)
1596     {
1597         uframeIntervalIndex = 0;
1598         status              = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval,
1599                                                          (uint16_t)timeData, &uframeIntervalIndex);
1600         if (status == kStatus_USB_Success)
1601         {
1602             ehciPipePointer->startFrame  = (uframeIntervalIndex / 8U);
1603             ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1604             /* for HS interrupt start transaction position */
1605             if (ehciPipePointer->uframeInterval >= 8U)
1606             {
1607                 ehciPipePointer->uframeSmask = (0x01U << ehciPipePointer->startUframe);
1608             }
1609             else
1610             {
1611                 ehciPipePointer->uframeSmask = 0x00U;
1612                 for (index = ehciPipePointer->startUframe; index < 8U;
1613                      index += (uint8_t)ehciPipePointer->uframeInterval)
1614                 {
1615                     ehciPipePointer->uframeSmask |= (0x01U << index);
1616                 }
1617             }
1618             ehciPipePointer->dataTime = (uint16_t)timeData;
1619 
1620             return kStatus_USB_Success;
1621         }
1622     }
1623     else /* pipe is full-speed or low-speed */
1624     {
1625         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1626                                                      (uint32_t)kUSB_HostGetHubThinkTime, &deviceInfo);
1627         timeData += (deviceInfo * 7U / (6U * 12U));
1628         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1629                                                      (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
1630         frameInterval = ehciPipePointer->pipeCommon.interval;
1631         SsCsNumber    = 3U; /* complete split number */
1632 
1633         /* compute start-split and complete-split bandwidth */
1634         if (ehciPipePointer->pipeCommon.direction == USB_OUT)
1635         {
1636             timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT,
1637                                                                     ehciPipePointer->pipeCommon.maxPacketSize);
1638             timeStartSplit +=
1639                 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 1U);
1640             timeCompleteSplit =
1641                 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 0U);
1642         }
1643         else
1644         {
1645             timeStartSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 1U);
1646             timeCompleteSplit = (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN,
1647                                                                        ehciPipePointer->pipeCommon.maxPacketSize);
1648             timeCompleteSplit +=
1649                 (uint16_t)USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 0U);
1650         }
1651         /* note: bandwidth must put in one frame */
1652         for (uframeIntervalIndex = 0U; uframeIntervalIndex <= 4U; ++uframeIntervalIndex) /* uframe interval */
1653         {
1654             for (frameIntervalIndex = 0U; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */
1655             {
1656                 allocateOk = 1U;
1657                 for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1658                      frameIndex += frameInterval) /* check all the frames */
1659                 {
1660                     /* allocate data bandwidth */
1661                     USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes);
1662                     index = (uint8_t)(uframeIntervalIndex + 1U);
1663                     for (; index <= (uframeIntervalIndex + 3U); ++index) /* data bandwidth number is 3.
1664                                                                              uframeIntervalIndex don't exceed 4, so
1665                                                                              index cannot exceed 7 */
1666                     {
1667                         if (frameTimes[index] + timeData > s_SlotMaxBandwidth[index])
1668                         {
1669                             allocateOk = 0;
1670                             break;
1671                         }
1672                     }
1673 
1674                     if (0U != allocateOk)
1675                     {
1676                         USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes);
1677                         /* allocate start_split bandwidth */
1678                         if (frameTimes[uframeIntervalIndex] + timeStartSplit >
1679                             s_SlotMaxBandwidthHs[uframeIntervalIndex])
1680                         {
1681                             allocateOk = 0U;
1682                         }
1683                         if (0U != allocateOk)
1684                         {
1685                             /* allocate complete_split bandwidth */
1686                             index = (uint8_t)uframeIntervalIndex + 2U;
1687                             /* complete-split number is normal 3. When uframeIntervalIndex is 4, complete-split number
1688                              * is 2. */
1689                             for (; (index <= (uframeIntervalIndex + 1U + SsCsNumber)) && (index < 8U); ++index)
1690                             {
1691                                 if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidthHs[index])
1692                                 {
1693                                     allocateOk = 0U;
1694                                     break;
1695                                 }
1696                             }
1697                         }
1698                     }
1699 
1700                     if (0U == allocateOk)
1701                     {
1702                         break; /* allocate fail */
1703                     }
1704                 }
1705                 if (0U != allocateOk)
1706                 {
1707                     break;
1708                 }
1709             }
1710             if (0U != allocateOk)
1711             {
1712                 break;
1713             }
1714         }
1715 
1716         if (0U != allocateOk)
1717         {
1718             ehciPipePointer->startFrame  = frameIntervalIndex;
1719             ehciPipePointer->startUframe = (uint8_t)uframeIntervalIndex;
1720             ehciPipePointer->uframeSmask = (0x01u << ehciPipePointer->startUframe);
1721             ehciPipePointer->uframeCmask = 0u;
1722             index                        = (uint8_t)uframeIntervalIndex + 2u;
1723             for (; (index <= (uframeIntervalIndex + 1u + SsCsNumber)) && (index < 8u); ++index)
1724             {
1725                 ehciPipePointer->uframeCmask = ehciPipePointer->uframeCmask | (0x01U << index);
1726             }
1727             ehciPipePointer->dataTime          = (uint16_t)timeData;
1728             ehciPipePointer->startSplitTime    = timeStartSplit;
1729             ehciPipePointer->completeSplitTime = timeCompleteSplit;
1730 
1731             return kStatus_USB_Success;
1732         }
1733     }
1734 
1735     return kStatus_USB_BandwidthFail;
1736 }
1737 
USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)1738 static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance,
1739                                                       usb_host_ehci_pipe_t *ehciPipePointer)
1740 {
1741     uint32_t FslsTime = 0;
1742     uint32_t speed    = 0;
1743     uint16_t uframeIntervalIndex;
1744     uint16_t frameIndex;
1745     uint16_t frameInterval;
1746     uint16_t frameTime;
1747 
1748     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1749                                                  (uint32_t)kUSB_HostGetHubThinkTime, &FslsTime);
1750     FslsTime += (FslsTime * 7U / (6U * 12U));
1751     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
1752                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
1753     FslsTime = FslsTime + USB_HostBandwidthComputeTime((uint8_t)speed, ehciPipePointer->pipeCommon.pipeType,
1754                                                        ehciPipePointer->pipeCommon.direction,
1755                                                        ehciPipePointer->pipeCommon.maxPacketSize);
1756 
1757     frameInterval = ehciPipePointer->pipeCommon.interval;
1758     for (uframeIntervalIndex = 0; uframeIntervalIndex < ehciPipePointer->uframeInterval;
1759          ++uframeIntervalIndex) /* uframeIntervalIndex can exceed 8 */
1760     {
1761         for (frameIndex = (uframeIntervalIndex >> 3); frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
1762              frameIndex += frameInterval)
1763         {
1764             USB_HostBandwidthFslsHostComputeCurrent(ehciInstance, frameIndex, &frameTime);
1765             if (frameTime + FslsTime > USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME)
1766             {
1767                 break;
1768             }
1769         }
1770         if (frameIndex >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
1771         {
1772             break;
1773         }
1774     }
1775     if (uframeIntervalIndex < ehciPipePointer->uframeInterval)
1776     {
1777         ehciPipePointer->startFrame  = (uframeIntervalIndex >> 3);
1778         ehciPipePointer->startUframe = (uint8_t)(uframeIntervalIndex & 0x0007U);
1779         ehciPipePointer->uframeSmask = 0; /* useless */
1780         ehciPipePointer->uframeCmask = 0;
1781         ehciPipePointer->dataTime    = (uint16_t)FslsTime;
1782 
1783         return kStatus_USB_Success;
1784     }
1785 
1786     return kStatus_USB_BandwidthFail;
1787 }
1788 
USB_HostEhciGet2PowerValue(uint8_t value)1789 static uint8_t USB_HostEhciGet2PowerValue(uint8_t value)
1790 {
1791     if ((value == 0U) || (value == 1U))
1792     {
1793         return value;
1794     }
1795     if (0U != (value & 0xf0U))
1796     {
1797         if (0U != (value & 0x80U))
1798         {
1799             return 128U;
1800         }
1801         else if (0U != (value & 0x40U))
1802         {
1803             return 64U;
1804         }
1805         else if (0U != (value & 0x20U))
1806         {
1807             return 32U;
1808         }
1809         else
1810         {
1811             return 16U;
1812         }
1813     }
1814     else
1815     {
1816         if (0U != (value & 0x08U))
1817         {
1818             return 8U;
1819         }
1820         else if (0U != (value & 0x04U))
1821         {
1822             return 4U;
1823         }
1824         else if (0U != (value & 0x02U))
1825         {
1826             return 2U;
1827         }
1828         else
1829         {
1830             return 1U;
1831         }
1832     }
1833 }
1834 
USB_HostEhciZeroMem(uint32_t * buffer,uint32_t length)1835 static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length)
1836 {
1837     /* note: the zero unit is uint32_t */
1838     while (0U != length)
1839     {
1840         length--;
1841         *buffer = 0;
1842         buffer++;
1843     }
1844 }
1845 
USB_HostEhciDelay(USBHS_Type * ehciIpBase,uint32_t ms)1846 static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms)
1847 {
1848     /* note: the max delay time cannot exceed half of max value (0x4000) */
1849     uint32_t sofStart;
1850     uint32_t SofEnd;
1851     uint32_t distance;
1852 
1853     sofStart = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
1854 
1855     do
1856     {
1857         SofEnd   = (ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
1858         distance = (SofEnd + EHCI_MAX_UFRAME_VALUE + 1U - sofStart);
1859     } while ((distance & EHCI_MAX_UFRAME_VALUE) < (ms * 8U)); /* compute the distance between sofStart and SofEnd */
1860 }
1861 
USB_HostEhciStartAsync(usb_host_ehci_instance_t * ehciInstance)1862 static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance)
1863 {
1864     uint32_t stateSync;
1865 
1866     if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1867     {
1868         /* the status must be same when change USBCMD->ASE */
1869         do
1870         {
1871             stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
1872                          (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
1873         } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
1874 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1875         ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->shedFirstQh);
1876 #else
1877         ehciInstance->ehciIpBase->ASYNCLISTADDR    = (uint32_t)(ehciInstance->shedFirstQh);
1878 #endif
1879         ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_ASE_MASK;
1880         while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1881         {
1882         }
1883     }
1884 }
1885 
USB_HostEhciStopAsync(usb_host_ehci_instance_t * ehciInstance)1886 static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance)
1887 {
1888     uint32_t stateSync;
1889 
1890     /* the status must be same when change USBCMD->ASE */
1891     do
1892     {
1893         stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) |
1894                      (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK));
1895     } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK));
1896 
1897     ehciInstance->ehciIpBase->USBCMD &= (uint32_t)(~(uint32_t)USBHS_USBCMD_ASE_MASK); /* disable async schedule */
1898     while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
1899     {
1900     }
1901 }
1902 
USB_HostEhciStartPeriodic(usb_host_ehci_instance_t * ehciInstance)1903 static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance)
1904 {
1905     uint32_t stateSync;
1906 
1907     if (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1908     {
1909         /* the status must be same when change USBCMD->PSE */
1910         do
1911         {
1912             stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
1913                          (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
1914         } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
1915 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1916         ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->ehciFrameList);
1917 #else
1918         ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)(ehciInstance->ehciFrameList);
1919 #endif
1920         if (0U == (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK))
1921         {
1922             ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_PSE_MASK; /* start periodic schedule */
1923         }
1924         while (0U == (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1925         {
1926         }
1927     }
1928     return;
1929 }
1930 
USB_HostEhciStopPeriodic(usb_host_ehci_instance_t * ehciInstance)1931 static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance)
1932 {
1933     uint32_t stateSync;
1934 
1935     /* the status must be same when change USBCMD->PSE */
1936     do
1937     {
1938         stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) |
1939                      (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK));
1940     } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK));
1941 
1942     ehciInstance->ehciIpBase->USBCMD &= (~USBHS_USBCMD_PSE_MASK); /* stop periodic schedule */
1943     while (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK))
1944     {
1945     }
1946 }
1947 
USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)1948 static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance,
1949                                               usb_host_ehci_pipe_t *ehciPipePointer,
1950                                               usb_host_transfer_t *transfer)
1951 {
1952     volatile usb_host_ehci_qh_t *vltQhPointer;
1953     usb_host_ehci_qtd_t *qtdPointer     = NULL;
1954     usb_host_ehci_qtd_t *BaseQtdPointer = NULL;
1955     volatile uint32_t *entryPointer;
1956 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
1957     uint32_t convert_addr = 0U;
1958 #endif
1959     uint32_t qtdNumber;
1960     uint32_t dataLength;
1961     uint32_t dataAddress;
1962     uint32_t endAddress;
1963     uint8_t index;
1964 
1965     /* compute the qtd number */
1966     if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
1967     {
1968         /* assume setup data don't exceed one qtd data size, one qtd can transfer least 16k data */
1969         if (transfer->transferLength == 0U)
1970         {
1971             qtdNumber = 2U;
1972         }
1973         else
1974         {
1975             qtdNumber = 3U;
1976         }
1977     }
1978     else
1979     {
1980         qtdNumber = (((transfer->transferLength) & 0xFFFFC000U) >> 14U) +
1981                     (0U != ((transfer->transferLength) & 0x00003FFFU) ? 1U : 0U);
1982         if (0U == qtdNumber)
1983         {
1984             qtdNumber = 1U;
1985         }
1986     }
1987 
1988     vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
1989     /* get qtd list */
1990     USB_HostEhciLock();
1991     if (qtdNumber <= ehciInstance->ehciQtdNumber)
1992     {
1993         ehciInstance->ehciQtdNumber -= (uint8_t)qtdNumber;
1994         BaseQtdPointer = ehciInstance->ehciQtdHead;
1995         qtdPointer     = NULL;
1996         do
1997         {
1998             if (qtdPointer != NULL)
1999             {
2000 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2001                 qtdPointer->nextQtdPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->ehciQtdHead);
2002 #else
2003                 qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead;
2004 #endif
2005             }
2006             qtdPointer = ehciInstance->ehciQtdHead;
2007 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2008             ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2009 #else
2010             ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
2011 #endif
2012             qtdPointer->nextQtdPointer = 0;
2013             --qtdNumber;
2014         } while (0U != qtdNumber);
2015         if (ehciInstance->ehciQtdNumber == 0U)
2016         {
2017             ehciInstance->ehciQtdTail = NULL;
2018         }
2019     }
2020     else
2021     {
2022         USB_HostEhciUnlock();
2023         return kStatus_USB_Error;
2024     }
2025     USB_HostEhciUnlock();
2026 
2027     /* int qTD list */
2028     if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
2029     {
2030         /* setup transaction qtd */
2031         qtdPointer                          = BaseQtdPointer;
2032         qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2033         /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */
2034         qtdPointer->transferResults[1] = 0U;
2035         qtdPointer->transferResults[0] =
2036             ((0x00000000UL << EHCI_HOST_QTD_DT_SHIFT) | (8UL << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2037              (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2038         dataAddress = ((uint32_t)transfer->setupPacket);
2039 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2040         convert_addr                   = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2041         qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2042 #else
2043         qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
2044 #endif
2045 
2046         /* set buffer pointer no matter data length */
2047         for (index = 0; index < 4U; ++index)
2048         {
2049 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2050             qtdPointer->bufferPointers[index] = ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2051 #else
2052             qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2053 #endif
2054         }
2055 
2056         /* data transaction qtd */
2057         dataLength = transfer->transferLength;
2058         if (dataLength != 0U)
2059         {
2060 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2061             qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2062 #else
2063             qtdPointer                        = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2064 #endif
2065             qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2066             /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
2067             qtdPointer->transferResults[1] = 0U;
2068             if (transfer->direction == USB_OUT)
2069             {
2070                 qtdPointer->transferResults[0] =
2071                     ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2072                      (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2073             }
2074             else
2075             {
2076                 qtdPointer->transferResults[0] =
2077                     ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2078                      (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2079             }
2080 
2081             dataAddress = (uint32_t)transfer->transferBuffer;
2082 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2083             convert_addr                   = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2084             qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2085 #else
2086             qtdPointer->transferResults[1]    = dataAddress; /* current offset is set too */
2087 #endif
2088             /* set buffer pointer no matter data length */
2089             for (index = 0; index < 4U; ++index)
2090             {
2091 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2092                 qtdPointer->bufferPointers[index] =
2093                     ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2094 #else
2095                 qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2096 #endif
2097             }
2098         }
2099 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2100         /* status transaction qtd */
2101         qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2102 #else
2103         /* status transaction qtd */
2104         qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2105 #endif
2106         qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2107         /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */
2108         qtdPointer->transferResults[1] = 0;
2109         if ((dataLength == 0U) || (transfer->direction == USB_OUT))
2110         {
2111             qtdPointer->transferResults[0] =
2112                 ((0x00000001UL << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) |
2113                  (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2114         }
2115         else
2116         {
2117             qtdPointer->transferResults[0] =
2118                 ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) |
2119                  (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2120         }
2121         qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
2122     }
2123     else
2124     {
2125         dataAddress = (uint32_t)transfer->transferBuffer;
2126         qtdPointer  = BaseQtdPointer;
2127         while (1U == 1U)
2128         {
2129             endAddress = dataAddress + (16U * 1024U);
2130             if (endAddress > (uint32_t)(transfer->transferBuffer + transfer->transferLength))
2131             {
2132                 endAddress = (uint32_t)(transfer->transferBuffer + transfer->transferLength);
2133             }
2134 
2135             qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2136             /* dt: set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */
2137             qtdPointer->transferResults[1] = 0U;
2138             if (transfer->direction == USB_OUT)
2139             {
2140                 qtdPointer->transferResults[0] =
2141                     (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2142                      ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
2143                      (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
2144                      (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2145             }
2146             else
2147             {
2148                 qtdPointer->transferResults[0] =
2149                     (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) |
2150                      ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) |
2151                      (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) |
2152                      (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK));
2153             }
2154 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2155             convert_addr                   = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataAddress);
2156             qtdPointer->transferResults[1] = convert_addr; /* current offset is set too */
2157 #else
2158             qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */
2159 #endif
2160             /* set buffer pointer no matter data length */
2161             for (index = 0; index < 4U; ++index)
2162             {
2163 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2164                 qtdPointer->bufferPointers[index] =
2165                     ((convert_addr + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2166 #else
2167                 qtdPointer->bufferPointers[index] = ((dataAddress + ((uint32_t)index + 1U) * 4U * 1024U) & 0xFFFFF000U);
2168 #endif
2169             }
2170             dataAddress = endAddress; /* for next qtd */
2171 
2172             if (qtdPointer->nextQtdPointer == 0U)
2173             {
2174                 break;
2175             }
2176 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2177             qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2178 #else
2179             qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer);
2180 #endif
2181         }
2182 
2183         qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;
2184         qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* last one set IOC */
2185     }
2186 
2187     /* save qtd to transfer */
2188     transfer->union1.unitHead = (uint32_t)BaseQtdPointer;
2189     transfer->union2.unitTail = (uint32_t)qtdPointer;
2190     /* link transfer to qh */
2191     transfer->next = NULL;
2192     if (vltQhPointer->ehciTransferHead == NULL)
2193     {
2194         transfer->next                 = NULL;
2195         vltQhPointer->ehciTransferTail = transfer;
2196         vltQhPointer->ehciTransferHead = transfer;
2197     }
2198     else
2199     {
2200         transfer->next                       = NULL;
2201         vltQhPointer->ehciTransferTail->next = transfer;
2202         vltQhPointer->ehciTransferTail       = transfer;
2203     }
2204 
2205     USB_HostEhciLock();
2206     /* link qtd to qh (link to end) */
2207     entryPointer = &(vltQhPointer->nextQtdPointer);
2208     dataAddress  = *entryPointer; /* dataAddress variable means entry value here */
2209     while ((0U != dataAddress) && (0U == (dataAddress & EHCI_HOST_T_INVALID_VALUE)))
2210     {
2211 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2212         entryPointer = (volatile uint32_t *)USB_HOST_MEMORY_DMA_2_CPU(dataAddress);
2213 #else
2214         entryPointer = (volatile uint32_t *)dataAddress;
2215 #endif
2216         dataAddress = *entryPointer;
2217     }
2218 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2219     *entryPointer = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(BaseQtdPointer);
2220 #else
2221     *entryPointer = (uint32_t)BaseQtdPointer;
2222 #endif
2223     USB_HostEhciStartAsync(ehciInstance);
2224     USB_HostEhciUnlock();
2225 
2226     return kStatus_USB_Success;
2227 }
2228 
USB_HostEhciQtdListRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_qtd_t * ehciQtdStart,usb_host_ehci_qtd_t * ehciQtdEnd)2229 static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance,
2230                                            usb_host_ehci_qtd_t *ehciQtdStart,
2231                                            usb_host_ehci_qtd_t *ehciQtdEnd)
2232 {
2233     uint32_t length = 0;
2234     usb_host_ehci_qtd_t *qtdPointer;
2235 
2236     ehciQtdEnd->nextQtdPointer = 0U;
2237 
2238     /* compute remaining length */
2239     qtdPointer = ehciQtdStart;
2240     while (qtdPointer != ehciQtdEnd)
2241     {
2242         length +=
2243             ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
2244 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2245         qtdPointer = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(qtdPointer->nextQtdPointer);
2246 #else
2247         qtdPointer   = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer;
2248 #endif
2249     }
2250     qtdPointer = ehciQtdEnd;
2251     length += ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);
2252 
2253     /* put releasing qtd to idle qtd list */
2254     USB_HostEhciLock();
2255     if (ehciInstance->ehciQtdNumber == 0U)
2256     {
2257         ehciInstance->ehciQtdHead = ehciQtdStart;
2258         ehciInstance->ehciQtdTail = ehciQtdEnd;
2259     }
2260     else
2261     {
2262         ehciInstance->ehciQtdTail->nextQtdPointer = (uint32_t)ehciQtdStart;
2263         ehciInstance->ehciQtdTail                 = ehciQtdEnd;
2264     }
2265 
2266     while (ehciQtdStart != ehciQtdEnd)
2267     {
2268         ehciInstance->ehciQtdNumber++;
2269 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2270         ehciQtdStart = (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(ehciQtdStart->nextQtdPointer);
2271 #else
2272         ehciQtdStart = (usb_host_ehci_qtd_t *)ehciQtdStart->nextQtdPointer;
2273 #endif
2274     }
2275     ehciInstance->ehciQtdNumber++;
2276     USB_HostEhciUnlock();
2277 
2278     return length;
2279 }
2280 
USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2281 static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
2282                                                 usb_host_ehci_pipe_t *ehciPipePointer)
2283 {
2284     volatile usb_host_ehci_qh_t *vltQhPointer;
2285     usb_host_transfer_t *transfer;
2286     usb_host_transfer_t *nextTransfer;
2287     uint32_t currentQtdPointer;
2288     uint8_t needStop = 0U;
2289 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2290     uint32_t convert_addr = 0U;
2291 #endif
2292 
2293     vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2294 
2295     USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
2296     /* remove qtd from qh */
2297     /*for misra 13.5*/
2298 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2299     currentQtdPointer = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
2300 #else
2301     currentQtdPointer = vltQhPointer->currentQtdPointer;
2302 #endif
2303 
2304 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2305     convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->nextQtdPointer);
2306     if ((0U == ((uint32_t)convert_addr & EHCI_HOST_T_INVALID_VALUE)) ||
2307 #else
2308     if ((0U == ((uint32_t)vltQhPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
2309 #endif
2310         (0U == ((uint32_t)currentQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
2311     {
2312 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2313         convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->horizontalLinkPointer);
2314         /* need stop async schedule */
2315         if ((0U == (convert_addr & EHCI_HOST_T_INVALID_VALUE)) &&
2316 #else
2317         /* need stop async schedule */
2318         if ((0U == (vltQhPointer->horizontalLinkPointer & EHCI_HOST_T_INVALID_VALUE)) &&
2319 #endif
2320             (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT))
2321         {
2322             needStop = 1U;
2323         }
2324         if (0U != needStop)
2325         {
2326             USB_HostEhciStopAsync(ehciInstance);
2327         }
2328         vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;             /* invalid current qtd */
2329         vltQhPointer->nextQtdPointer    = EHCI_HOST_T_INVALID_VALUE;             /* invalid next qtd */
2330         vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
2331         if (0U != needStop)
2332         {
2333             USB_HostEhciStartAsync(ehciInstance);
2334         }
2335     }
2336 
2337     /* remove transfer from the QH transfer list */
2338     transfer                       = vltQhPointer->ehciTransferHead;
2339     vltQhPointer->ehciTransferTail = NULL;
2340     vltQhPointer->ehciTransferHead = NULL;
2341     USB_HostEhciUnlock();
2342 
2343     /* release qtd  and transfer callback*/
2344     while (transfer != NULL)
2345     {
2346         nextTransfer = transfer->next; /* the transfer is released when call back */
2347         transfer->transferSofar =
2348             USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
2349                                        (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
2350         transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
2351                                       0U :
2352                                       (transfer->transferLength - transfer->transferSofar);
2353         /* callback function is different from the current condition */
2354         USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferCancel);
2355         transfer = nextTransfer;
2356     }
2357 
2358     return kStatus_USB_Success;
2359 }
2360 
USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)2361 static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance,
2362                                                       usb_host_ehci_pipe_t *ehciPipePointer,
2363                                                       usb_host_transfer_t *transfer)
2364 {
2365     volatile usb_host_ehci_qh_t *vltQhPointer;
2366     usb_host_transfer_t *preSearchTransfer;
2367     uint32_t qhNextQtdValue;
2368     uint32_t qtdPointerEntry;
2369     uint32_t *searchQtdEntryPointer;
2370 
2371     vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2372 
2373     USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */
2374     /* remove qtd from qh */
2375 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2376     qhNextQtdValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
2377 #else
2378     qhNextQtdValue = (uint32_t)vltQhPointer->currentQtdPointer;
2379 #endif
2380 
2381     qtdPointerEntry = *((uint32_t *)qhNextQtdValue + 2); /* note: qtdPointerEntry means qtd status */
2382     if ((0U != (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) ||
2383         (0U == (qtdPointerEntry & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)))
2384     {
2385         qhNextQtdValue = (uint32_t)vltQhPointer->nextQtdPointer;
2386     }
2387     if (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) /* there is pending qtd in the qh */
2388     {
2389         /* this qh don't schedule temporarily */
2390         if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
2391         {
2392             USB_HostEhciStopAsync(ehciInstance);
2393         }
2394         vltQhPointer->currentQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */
2395         vltQhPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE;    /* invalid next qtd */
2396         if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)
2397         {
2398             USB_HostEhciStartAsync(ehciInstance);
2399         }
2400 
2401         /* remove qtd from qh one by one */
2402         qtdPointerEntry = transfer->union1.unitHead;
2403         while (1U == 1U)
2404         {
2405             /* search qh's qtd list for qtdPointerEntry */
2406             searchQtdEntryPointer = &qhNextQtdValue;
2407             while (0U == ((*searchQtdEntryPointer) & EHCI_HOST_T_INVALID_VALUE))
2408             {
2409                 if ((*searchQtdEntryPointer) == qtdPointerEntry)
2410                 {
2411                     *searchQtdEntryPointer = *((uint32_t *)qtdPointerEntry); /* remove the qtd from qh */
2412                     break;
2413                 }
2414                 else
2415                 {
2416                     searchQtdEntryPointer = (uint32_t *)(*searchQtdEntryPointer);
2417                 }
2418             }
2419             if (qtdPointerEntry == transfer->union2.unitTail)
2420             {
2421                 break;
2422             }
2423             qtdPointerEntry = *((uint32_t *)qtdPointerEntry);
2424         }
2425     }
2426 
2427     /* remove transfer from the QH transfer list */
2428     preSearchTransfer = vltQhPointer->ehciTransferHead;
2429     if (preSearchTransfer == transfer)
2430     {
2431         vltQhPointer->ehciTransferHead = preSearchTransfer->next;
2432     }
2433     else
2434     {
2435         while (preSearchTransfer != NULL)
2436         {
2437             if (preSearchTransfer->next == transfer)
2438             {
2439                 preSearchTransfer->next = transfer->next;
2440                 break;
2441             }
2442             else
2443             {
2444                 preSearchTransfer = preSearchTransfer->next;
2445             }
2446         }
2447     }
2448     USB_HostEhciUnlock();
2449 
2450     /* release qtd and callback */
2451     transfer->transferSofar =
2452         USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
2453                                    (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
2454     transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
2455                                   0U :
2456                                   (transfer->transferLength - transfer->transferSofar);
2457     /* callback function is different from the current condition */
2458     USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferCancel);
2459 
2460     /* start this qh schedule */
2461     vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
2462     if ((qhNextQtdValue != 0U) && (0U == (qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)))
2463     {
2464         vltQhPointer->nextQtdPointer = qhNextQtdValue;
2465     }
2466 
2467     return kStatus_USB_Success;
2468 }
2469 
USB_HostEhciQhInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2470 static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
2471 {
2472     usb_host_ehci_qh_t *qhPointer = NULL;
2473     uint32_t address              = 0;
2474     uint32_t speed                = 0;
2475     uint32_t portNumber           = 0;
2476     uint32_t hubNumber            = 0;
2477     ;
2478     uint32_t controlBits1 = 0U;
2479     uint32_t controlBits2 = 0U;
2480 
2481     /* get qh */
2482     USB_HostEhciLock();
2483     if (ehciInstance->ehciQhList != NULL)
2484     {
2485         qhPointer = (usb_host_ehci_qh_t *)ehciInstance->ehciQhList;
2486         ehciInstance->ehciQhList =
2487             (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
2488     }
2489     USB_HostEhciUnlock();
2490     if (qhPointer == NULL)
2491     {
2492 #ifdef HOST_EHCO
2493         usb_echo("get qh error\r\n");
2494 #endif
2495         return kStatus_USB_Error;
2496     }
2497     ehciPipePointer->ehciQh = (void *)qhPointer;
2498 
2499     /* initialize qh */
2500     USB_HostEhciZeroMem((void *)qhPointer, sizeof(usb_host_ehci_qh_t) / 4U);
2501     qhPointer->horizontalLinkPointer   = EHCI_HOST_T_INVALID_VALUE;
2502     qhPointer->currentQtdPointer       = EHCI_HOST_T_INVALID_VALUE;
2503     qhPointer->nextQtdPointer          = EHCI_HOST_T_INVALID_VALUE;
2504     qhPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
2505     qhPointer->ehciPipePointer         = ehciPipePointer;
2506     qhPointer->timeOutLabel            = 0;
2507     qhPointer->timeOutValue            = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
2508     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2509                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
2510     /* initialize staticEndpointStates[0] */
2511     if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)
2512     {
2513         /* Software should set the RL field to zero if the queue head is an interrupt endpoint. */
2514         controlBits1 |= ((0UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2515     }
2516     else
2517     {
2518         if (ehciPipePointer->pipeCommon.nakCount >= 16U)
2519         {
2520             controlBits1 |= ((15UL << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2521         }
2522         else
2523         {
2524             controlBits1 |=
2525                 (((uint32_t)ehciPipePointer->pipeCommon.nakCount << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK);
2526         }
2527     }
2528     if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
2529     {
2530         if (speed != USB_SPEED_HIGH)
2531         {
2532             controlBits1 |= (1UL << EHCI_HOST_QH_C_SHIFT);
2533         }
2534         controlBits1 |= (1UL << EHCI_HOST_QH_DTC_SHIFT);
2535     }
2536     controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT);
2537     controlBits1 |= (speed << EHCI_HOST_QH_EPS_SHIFT);
2538     controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_QH_ENDPT_SHIFT);
2539     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2540                                                  (uint32_t)kUSB_HostGetDeviceAddress, &address);
2541     controlBits1 |= (address << EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT);
2542     qhPointer->staticEndpointStates[0] = controlBits1;
2543     if (speed == USB_SPEED_HIGH)
2544     {
2545         controlBits2 |= ((uint32_t)ehciPipePointer->pipeCommon.numberPerUframe << EHCI_HOST_QH_MULT_SHIFT);
2546     }
2547     else
2548     {
2549         controlBits2 |= (0x00000001UL << EHCI_HOST_QH_MULT_SHIFT);
2550     }
2551     /*initialize staticEndpointStates[1] */
2552     if (speed != USB_SPEED_HIGH)
2553     {
2554         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2555                                                      (uint32_t)kUSB_HostGetDeviceHSHubNumber, &hubNumber);
2556         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2557                                                      (uint32_t)kUSB_HostGetDeviceHSHubPort, &portNumber);
2558     }
2559     else
2560     {
2561         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2562                                                      (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
2563         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2564                                                      (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
2565     }
2566     controlBits2 |= (portNumber << EHCI_HOST_QH_PORT_NUMBER_SHIFT);
2567     controlBits2 |= (hubNumber << EHCI_HOST_QH_HUB_ADDR_SHIFT);
2568     controlBits2 |= ((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_QH_UFRAME_CMASK_SHIFT);
2569     controlBits2 |= ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_QH_UFRAME_SMASK_SHIFT);
2570     qhPointer->staticEndpointStates[1] = controlBits2;
2571 
2572     return kStatus_USB_Success;
2573 }
2574 
USB_HostEhciQhDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2575 static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
2576 {
2577     usb_host_ehci_qh_t *qhPointer;
2578 
2579     qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
2580     /* de-initialize qtd from qh */
2581     (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer);
2582 
2583     /* release QH */
2584     USB_HostEhciLock();
2585     qhPointer->horizontalLinkPointer = (uint32_t)ehciInstance->ehciQhList;
2586     ehciInstance->ehciQhList         = qhPointer;
2587     USB_HostEhciUnlock();
2588 
2589     return kStatus_USB_Success;
2590 }
2591 
USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t entryPointerValue,uint16_t framePos,uint16_t uframeInterval)2592 static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance,
2593                                      uint32_t entryPointerValue,
2594                                      uint16_t framePos,
2595                                      uint16_t uframeInterval)
2596 {
2597     volatile uint32_t *frameEntryPointer;
2598     uint32_t frameEntryValue;
2599 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2600     uint32_t convert_addr = 0U;
2601 #endif
2602     void *temp;
2603 
2604     /* search for the inserting point by interval */
2605     temp              = (void *)ehciInstance->ehciFrameList;
2606     frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
2607     while (NULL != frameEntryPointer)
2608     {
2609         frameEntryValue = *frameEntryPointer;
2610 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2611         frameEntryValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(frameEntryValue);
2612 #endif
2613         if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
2614         {
2615             /* insert into the end */
2616             *((uint32_t *)entryPointerValue) = EHCI_HOST_T_INVALID_VALUE;
2617 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2618             convert_addr       = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(entryPointerValue);
2619             *frameEntryPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
2620 #else
2621             *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
2622 #endif
2623             break;
2624         }
2625 
2626         if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
2627         {
2628             return; /* has inserted */
2629         }
2630         if (((frameEntryValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_QH) &&
2631             (((usb_host_ehci_qh_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK))
2632                  ->ehciPipePointer->uframeInterval <= uframeInterval))
2633         {
2634             /* insert into this point */
2635 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2636             frameEntryValue = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(frameEntryValue);
2637 #endif
2638             *((uint32_t *)entryPointerValue) = frameEntryValue;
2639 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2640             convert_addr       = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(entryPointerValue);
2641             *frameEntryPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
2642 #else
2643             *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH);
2644 #endif
2645             return;
2646         }
2647         else
2648         {
2649             frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
2650         }
2651     }
2652 }
2653 
USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t entryPointerValue,uint16_t framePos)2654 static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance,
2655                                         uint32_t entryPointerValue,
2656                                         uint16_t framePos)
2657 {
2658     volatile uint32_t *frameEntryPointer;
2659     uint32_t frameEntryValue;
2660     void *temp;
2661     /* search for the qh/itd/sitd entry */
2662     temp              = (void *)ehciInstance->ehciFrameList;
2663     frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)temp)[framePos]);
2664 
2665 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2666     frameEntryPointer = (volatile uint32_t *)USB_HOST_MEMORY_DMA_2_CPU(frameEntryPointer);
2667 #endif
2668 
2669     while (NULL != frameEntryPointer)
2670     {
2671 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2672         frameEntryValue = *((uint32_t *)frameEntryPointer);
2673         frameEntryValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(frameEntryValue);
2674 #else
2675         frameEntryValue = *frameEntryPointer;
2676 #endif
2677         if (0U != (frameEntryValue & EHCI_HOST_T_INVALID_VALUE))
2678         {
2679             return;
2680         }
2681 
2682         if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue)
2683         {
2684             /* remove the entry */
2685             *frameEntryPointer = *((uint32_t *)entryPointerValue);
2686             break;
2687         }
2688         else
2689         {
2690             frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK);
2691         }
2692     }
2693 }
2694 
2695 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
USB_HostEhciLinkSitd(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,void * startEntryPointer)2696 static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance,
2697                                  usb_host_ehci_pipe_t *ehciPipePointer,
2698                                  void *startEntryPointer)
2699 {
2700     usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2701     usb_host_ehci_sitd_t *sitdPointer;
2702     uint32_t distance;
2703     uint32_t frameInterval;
2704     uint32_t shouldLinkFrame;
2705     uint32_t currentFrame;
2706     uint8_t sitdPointerIndex = 0U;
2707 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2708     uint32_t convert_addr = 0U;
2709 #endif
2710     void *temp;
2711 
2712     frameInterval = ((uint32_t)ehciPipePointer->uframeInterval >> 3U);
2713 
2714     if (isoPointer->lastLinkFrame == 0xFFFFU) /* first link */
2715     {
2716         currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
2717         currentFrame = ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) &
2718                         (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)); /* add USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER */
2719         /* frame should align with interval */
2720         if (currentFrame <= ehciPipePointer->startFrame)
2721         {
2722             currentFrame = ehciPipePointer->startFrame;
2723         }
2724         else
2725         {
2726             currentFrame -= ehciPipePointer->startFrame;
2727             currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
2728             currentFrame += ehciPipePointer->startFrame;
2729         }
2730     }
2731     else
2732     {
2733         shouldLinkFrame = isoPointer->lastLinkFrame + frameInterval; /* continuous next should link frame */
2734         if (shouldLinkFrame > USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U)
2735         {
2736             shouldLinkFrame = shouldLinkFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U);
2737         }
2738         currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE) >> 3U);
2739         distance =
2740             ((shouldLinkFrame + (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3U) + 1U - currentFrame) &
2741              (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3)); /* get the distance from shouldLinkFrame to currentFrame */
2742         /* shouldLinkFrame has add frameInterval, think about the align with interval, so here add (frameInterval *
2743          * 2) */
2744         if ((distance <=
2745              (USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER + frameInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER)) &&
2746             (distance > 0U))
2747         {
2748             currentFrame = shouldLinkFrame;
2749         }
2750         else /* re-link */
2751         {
2752             currentFrame =
2753                 ((currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3));
2754 
2755             /*if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
2756             {
2757                 currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
2758             }*/
2759             /* frame should align with interval */
2760             if (currentFrame <= ehciPipePointer->startFrame)
2761             {
2762                 currentFrame = ehciPipePointer->startFrame;
2763             }
2764             else
2765             {
2766                 currentFrame -= ehciPipePointer->startFrame;
2767                 currentFrame = ((currentFrame + frameInterval - 1U) & (~(frameInterval - 1U)));
2768                 currentFrame += ehciPipePointer->startFrame;
2769             }
2770         }
2771     }
2772     if (currentFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) /* frame turn around */
2773     {
2774         shouldLinkFrame =
2775             (currentFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); /* shouldLinkFrame means inserted frame position */
2776     }
2777     else
2778     {
2779         shouldLinkFrame = currentFrame; /* shouldLinkFrame means inserted frame position */
2780     }
2781 
2782     sitdPointer = (usb_host_ehci_sitd_t *)startEntryPointer;
2783     while (NULL != sitdPointer)
2784     {
2785         sitdPointer->frameEntryIndex = (uint16_t)shouldLinkFrame;
2786         /* add to frame list head */
2787         temp                         = (void *)ehciInstance->ehciFrameList;
2788         sitdPointer->nextLinkPointer = ((uint32_t *)temp)[shouldLinkFrame];
2789 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2790         convert_addr                        = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(sitdPointer);
2791         ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)convert_addr | EHCI_HOST_POINTER_TYPE_SITD);
2792 #else
2793         ((uint32_t *)temp)[shouldLinkFrame] = ((uint32_t)sitdPointer | EHCI_HOST_POINTER_TYPE_SITD);
2794 #endif
2795         sitdPointerIndex = sitdPointer->nextSitdIndex;
2796         if (sitdPointerIndex == 0xFFU) /* 0xFF is invalid value */
2797         {
2798             break;
2799         }
2800         sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointerIndex]); /* next sitd */
2801 
2802         shouldLinkFrame += frameInterval;
2803         currentFrame += frameInterval;
2804         if (shouldLinkFrame >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE)
2805         {
2806             shouldLinkFrame = (shouldLinkFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE);
2807         }
2808     }
2809 
2810     if (currentFrame > (USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3))
2811     {
2812         currentFrame = currentFrame - ((USB_HOST_EHCI_MAX_MICRFRAME_VALUE >> 3) + 1U);
2813     }
2814     isoPointer->lastLinkFrame = (uint16_t)currentFrame; /* save the last link frame value */
2815 }
2816 
USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)2817 static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance,
2818                                               usb_host_ehci_pipe_t *ehciPipePointer,
2819                                               usb_host_transfer_t *transfer)
2820 {
2821     usb_host_ehci_iso_t *isoPointer;
2822     uint32_t sitdNumber = 0;
2823     usb_host_ehci_sitd_t *sitdPointer;
2824     uint32_t dataLength = 0;
2825     uint32_t sitdLength = 0;
2826     uint32_t dataBufferValue;
2827     uint32_t hubNumber  = 0U;
2828     uint32_t portNumber = 0U;
2829     uint32_t address    = 0U;
2830     uint32_t tmp;
2831     uint32_t *temp;
2832     uint32_t index;
2833     int32_t tempIndex;
2834     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2835                                                  (uint32_t)kUSB_HostGetDeviceAddress, &address);
2836 
2837     sitdNumber = ((transfer->transferLength - 1U + (ehciPipePointer->pipeCommon.maxPacketSize)) /
2838                   (ehciPipePointer->pipeCommon.maxPacketSize));
2839     /* get sitd array */
2840     /* USB_HostEhciLock(); */
2841     if (ehciInstance->ehciSitdNumber >= sitdNumber)
2842     {
2843         sitdPointer               = ehciInstance->ehciSitdList;
2844         transfer->union1.unitHead = (uint32_t)sitdPointer;
2845         for (index = 1U; index < sitdNumber; ++index)
2846         {
2847             /*misra 10.8*/
2848             tempIndex                  = (((usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU)) -
2849                          ehciInstance->ehciSitdIndexBase);
2850             sitdPointer->nextSitdIndex = (uint8_t)tempIndex;
2851             sitdPointer                = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
2852         }
2853         sitdPointer->nextSitdIndex = 0xFF;
2854         ehciInstance->ehciSitdList = (usb_host_ehci_sitd_t *)(sitdPointer->nextLinkPointer & 0xFFFFFFFEU);
2855         ehciInstance->ehciSitdNumber -= (uint8_t)sitdNumber;
2856     }
2857     else
2858     {
2859         /* USB_HostEhciUnlock(); */
2860         return kStatus_USB_Error;
2861     }
2862     /* USB_HostEhciUnlock(); */
2863     transfer->union2.unitTail = (uint32_t)sitdPointer;
2864     /* initialize sitd array */
2865     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2866                                                  (uint32_t)kUSB_HostGetDeviceHubNumber, &hubNumber);
2867     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
2868                                                  (uint32_t)kUSB_HostGetDevicePortNumber, &portNumber);
2869     sitdPointer = (usb_host_ehci_sitd_t *)transfer->union1.unitHead;
2870     dataLength  = transfer->transferLength;
2871     while (0U != sitdNumber)
2872     {
2873         sitdNumber--;
2874         USB_HostEhciZeroMem((void *)sitdPointer, 7);
2875         sitdLength = dataLength;
2876         if (sitdLength > ehciPipePointer->pipeCommon.maxPacketSize)
2877         {
2878             sitdLength = ehciPipePointer->pipeCommon.maxPacketSize;
2879         }
2880         dataBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
2881 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
2882         dataBufferValue = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(dataBufferValue);
2883 #endif
2884         dataLength -= sitdLength; /* update left data length */
2885         sitdPointer->transferResults[1] = dataBufferValue;
2886         sitdPointer->transferResults[2] = ((dataBufferValue + 4U * 1024U) & 0xFFFFF000U);
2887         sitdPointer->endpointStates[0] =
2888             (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_SITD_DIRECTION_SHIFT) |
2889              (portNumber << EHCI_HOST_SITD_PORT_NUMBER_SHIFT) | (hubNumber << EHCI_HOST_SITD_HUB_ADDR_SHIFT) |
2890              ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_SITD_ENDPT_SHIFT) |
2891              (address << EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT));
2892         sitdPointer->transferResults[0] =
2893             ((sitdLength << EHCI_HOST_SITD_TOTAL_BYTES_SHIFT) | (EHCI_HOST_SITD_STATUS_ACTIVE_MASK));
2894 
2895         if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
2896         {
2897             sitdPointer->endpointStates[1] = (((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_SITD_CMASK_SHIFT) |
2898                                               ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_SITD_SMASK_SHIFT));
2899 
2900             tmp = (sitdLength + 187U) / 188U;
2901             if (tmp > 1U)
2902             {
2903                 sitdPointer->transferResults[2] |= (0x01U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
2904             }
2905             else
2906             {
2907                 sitdPointer->transferResults[2] |= (0x00U << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */
2908             }
2909             sitdPointer->transferResults[2] |= (tmp << EHCI_HOST_SITD_TCOUNT_SHIFT); /* for iso split */
2910         }
2911 
2912         sitdPointer->backPointer = EHCI_HOST_T_INVALID_VALUE;
2913 
2914         sitdPointer = (ehciInstance->ehciSitdIndexBase + sitdPointer->nextSitdIndex);
2915     }
2916     sitdPointer = (usb_host_ehci_sitd_t *)transfer->union2.unitTail;
2917     sitdPointer->transferResults[0] |= (1UL << EHCI_HOST_SITD_IOC_SHIFT); /* last set IOC */
2918 
2919     /* link transfer to usb_host_ehci_iso_t transfer list */
2920     isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2921     USB_HostEhciLock();
2922     if (isoPointer->ehciTransferHead == NULL)
2923     {
2924         transfer->next               = NULL;
2925         isoPointer->ehciTransferTail = transfer;
2926         isoPointer->ehciTransferHead = transfer;
2927     }
2928     else
2929     {
2930         transfer->next                     = NULL;
2931         isoPointer->ehciTransferTail->next = transfer;
2932         isoPointer->ehciTransferTail       = transfer;
2933     }
2934     USB_HostEhciUnlock();
2935 
2936     /* link itd to frame list (note: initialize frameEntryIndex)*/
2937     /*misra 11.6*/
2938     temp = (uint32_t *)(transfer->union1.unitHead);
2939     USB_HostEhciLinkSitd(ehciInstance, ehciPipePointer, (void *)temp);
2940 
2941     return kStatus_USB_Success;
2942 }
2943 
USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_sitd_t * startSitdPointer,usb_host_ehci_sitd_t * endSitdPointer)2944 static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
2945                                              usb_host_ehci_sitd_t *startSitdPointer,
2946                                              usb_host_ehci_sitd_t *endSitdPointer)
2947 {
2948     usb_host_ehci_sitd_t *sitdPointer = startSitdPointer;
2949     uint32_t leftLength               = 0;
2950     /* remove itd from frame list */
2951     while (1U == 1U)
2952     {
2953         /* record the transfer's result length */
2954         leftLength +=
2955             ((sitdPointer->transferResults[0] & EHCI_HOST_SITD_TOTAL_BYTES_MASK) >> EHCI_HOST_SITD_TOTAL_BYTES_SHIFT);
2956         USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)sitdPointer,
2957                                     sitdPointer->frameEntryIndex); /* remove from the inserted frame list */
2958 
2959         /* release itd */
2960         /* USB_HostEhciLock(); */
2961         /*set next link pointer to invalid in case hardware access invalid sitd structure in special case*/
2962         sitdPointer->nextLinkPointer = (((uint32_t)ehciInstance->ehciSitdList) | EHCI_HOST_T_INVALID_VALUE);
2963         ehciInstance->ehciSitdList   = sitdPointer;
2964         ehciInstance->ehciSitdNumber++;
2965         /* USB_HostEhciUnlock(); */
2966 
2967         if (sitdPointer == endSitdPointer)
2968         {
2969             break;
2970         }
2971 
2972         sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]);
2973     }
2974 
2975     return leftLength;
2976 }
2977 
USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)2978 static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
2979                                                 usb_host_ehci_pipe_t *ehciPipePointer)
2980 {
2981     usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
2982     usb_host_transfer_t *transfer;
2983     usb_host_transfer_t *nextTransfer;
2984 
2985     /* firstly remove the transfer (because host task may occupy to access the resource) */
2986     USB_HostEhciLock();
2987     transfer                     = isoPointer->ehciTransferHead;
2988     isoPointer->ehciTransferTail = NULL;
2989     isoPointer->ehciTransferHead = NULL;
2990     USB_HostEhciUnlock();
2991 
2992     while (transfer != NULL)
2993     {
2994         nextTransfer = transfer->next;
2995         /* remove sitd from frame list and release itd */
2996         transfer->transferSofar =
2997             transfer->transferLength - USB_HostEhciSitdArrayRelease(ehciInstance,
2998                                                                     (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
2999                                                                     (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
3000         /* callback function is different from the current condition */
3001         USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferCancel);
3002         /* next transfer */
3003         transfer = nextTransfer;
3004     }
3005 
3006     return kStatus_USB_Success;
3007 }
3008 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
3009 
3010 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t * ehciInstance,uint32_t lastLinkUframe,uint16_t startUframe,uint16_t uframeInterval)3011 static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance,
3012                                             uint32_t lastLinkUframe,
3013                                             uint16_t startUframe,
3014                                             uint16_t uframeInterval)
3015 {
3016     uint32_t shouldLinkUframe;
3017     uint32_t currentUframe;
3018     uint32_t distance;
3019 
3020     if (lastLinkUframe != 0xFFFFU)
3021     {
3022         shouldLinkUframe = lastLinkUframe + uframeInterval;
3023         if (shouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3024         {
3025             shouldLinkUframe = shouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3026         }
3027         currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3028         distance      = ((shouldLinkUframe + USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U - currentUframe) &
3029                     USB_HOST_EHCI_MAX_MICRFRAME_VALUE); /* get the distance */
3030         /* shouldLinkUframe has add uframeInterval, think about the align with interval, so here add (uframeInterval
3031          * * 2) */
3032         if ((distance <= ((uint32_t)USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER +
3033                           ((uint32_t)uframeInterval * USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER))) &&
3034             (distance > 2U))
3035         {
3036             currentUframe = shouldLinkUframe;
3037         }
3038         else /* re-link */
3039         {
3040             currentUframe =
3041                 ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3042             /*if (currentUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3043             {
3044                 currentUframe = currentUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3045             }*/
3046             /* uframe should align with interval */
3047             if (currentUframe <= startUframe)
3048             {
3049                 currentUframe = startUframe;
3050             }
3051             else
3052             {
3053                 currentUframe -= startUframe;
3054                 currentUframe = ((uint32_t)(currentUframe + uframeInterval) &
3055                                  (~((uint32_t)uframeInterval - 1U))); /* uframeInterval is power of 2 */
3056                 currentUframe += startUframe;
3057             }
3058         }
3059     }
3060     else
3061     {
3062         currentUframe = (ehciInstance->ehciIpBase->FRINDEX & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3063         currentUframe = ((currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & USB_HOST_EHCI_MAX_MICRFRAME_VALUE);
3064         /* uframe should align with interval */
3065         if (currentUframe <= startUframe)
3066         {
3067             currentUframe = startUframe;
3068         }
3069         else
3070         {
3071             currentUframe -= startUframe;
3072             currentUframe =
3073                 ((currentUframe + uframeInterval) & (~(uframeInterval - 1U))); /* uframeInterval is power of 2 */
3074             currentUframe += startUframe;
3075         }
3076     }
3077 
3078     return currentUframe;
3079 }
3080 
USB_HostEhciItdArrayInit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)3081 static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance,
3082                                              usb_host_ehci_pipe_t *ehciPipePointer,
3083                                              usb_host_transfer_t *transfer)
3084 {
3085     usb_host_ehci_iso_t *isoPointer;
3086     usb_host_ehci_itd_t *itdPointer = NULL;
3087     usb_host_ehci_itd_t *itdHead    = NULL;
3088     usb_host_ehci_itd_t *tmpItdPointer;
3089     uint32_t dataLength;        /* the remaining data for sending */
3090     uint32_t transactionLength; /* the initializing transaction descriptor data length */
3091     uint32_t itdBufferValue;
3092     uint32_t itdBufferBaseValue; /* for calculating PG value */
3093     uint32_t address = 0U;
3094     uint32_t lastShouldLinkUframe;
3095     uint32_t linkUframe;
3096     uint32_t minDataPerItd =
3097         (uint32_t)ehciPipePointer->pipeCommon.numberPerUframe * ehciPipePointer->pipeCommon.maxPacketSize;
3098 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3099     uint32_t convert_addr  = 0U;
3100     uint32_t convert_addr1 = 0U;
3101 #endif
3102     uint8_t maxItdNumber;
3103     uint16_t index = 0;
3104 
3105     isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3106     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3107                                                  (uint32_t)kUSB_HostGetDeviceAddress, &address);
3108 
3109     /* max needed itd number, the actual needed number may be less because micro-frame interval may be less than 8 */
3110     maxItdNumber = (uint8_t)((transfer->transferLength - 1U + minDataPerItd) / minDataPerItd);
3111     if (ehciPipePointer->uframeInterval < 8U)
3112     {
3113         maxItdNumber = (uint8_t)((maxItdNumber * ehciPipePointer->uframeInterval + 7U) / 8U) + 1U;
3114     }
3115     if (maxItdNumber > ehciInstance->ehciItdNumber)
3116     {
3117         return kStatus_USB_Error;
3118     }
3119 
3120     /* link transfer to usb_host_ehci_iso_t transfer list */
3121     transfer->next = NULL;
3122     /* USB_HostEhciLock(); */
3123     if (isoPointer->ehciTransferHead == NULL)
3124     {
3125         isoPointer->ehciTransferTail = transfer;
3126         isoPointer->ehciTransferHead = transfer;
3127     }
3128     else
3129     {
3130         isoPointer->ehciTransferTail->next = transfer;
3131         isoPointer->ehciTransferTail       = transfer;
3132     }
3133     /* USB_HostEhciUnlock(); */
3134 
3135     dataLength                = transfer->transferLength;
3136     transfer->union1.unitHead = 0U;
3137     /* get the link micro-frame */
3138     lastShouldLinkUframe = USB_HostEhciGetItdLinkFrame(
3139         ehciInstance, isoPointer->lastLinkFrame,
3140         (uint16_t)((ehciPipePointer->startFrame << 3) + ehciPipePointer->startUframe), ehciPipePointer->uframeInterval);
3141     if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3142     {
3143         linkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3144     }
3145     else
3146     {
3147         linkUframe = lastShouldLinkUframe;
3148     }
3149     itdHead = ehciInstance->ehciItdList;
3150     while (0U != dataLength)
3151     {
3152         /* get one idle itd */
3153         tmpItdPointer = ehciInstance->ehciItdList;
3154         if (tmpItdPointer == NULL)
3155         {
3156             return kStatus_USB_Error; /* this should not reach */
3157         }
3158         ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)tmpItdPointer->nextItdPointer;
3159         ehciInstance->ehciItdNumber -= 1U;
3160 
3161         tmpItdPointer->nextItdPointer = NULL;
3162 
3163         /* use the itd */
3164         if (transfer->union1.unitHead == 0U) /* first itd */
3165         {
3166             transfer->union1.unitHead = (uint32_t)tmpItdPointer;
3167         }
3168         else /* link itd list */
3169         {
3170             itdPointer->nextItdPointer = tmpItdPointer;
3171         }
3172         itdPointer = tmpItdPointer;
3173 
3174         /* itd has been set to all zero when releasing */
3175         itdBufferValue     = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength));
3176         itdBufferBaseValue = itdBufferValue;
3177 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3178         convert_addr  = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(itdBufferBaseValue);
3179         convert_addr1 = convert_addr;
3180 #endif
3181         for (index = 0; index < 7U; ++index)
3182         {
3183 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3184             itdPointer->bufferPointers[index] = ((convert_addr + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
3185 #else
3186             itdPointer->bufferPointers[index] = ((itdBufferBaseValue + ((uint32_t)index * 4U * 1024U)) & 0xFFFFF000U);
3187 #endif
3188         }
3189         /* initialize iTD common fields */
3190         itdPointer->bufferPointers[0] |=
3191             (((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_ITD_ENDPT_SHIFT) |
3192              (address << EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT));
3193         itdPointer->bufferPointers[1] |=
3194             (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_ITD_DIRECTION_SHIFT) |
3195              ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT));
3196         itdPointer->bufferPointers[2] |= (ehciPipePointer->pipeCommon.numberPerUframe);
3197         /* initialize transaction descriptors */
3198         for (index = (uint8_t)(linkUframe & 0x0007U); index < 8U; index += ehciPipePointer->uframeInterval)
3199         {
3200             transactionLength = ((dataLength > minDataPerItd) ? minDataPerItd : dataLength);
3201 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3202             /* initialize the uframeIndex's transaction descriptor in itd */
3203             itdPointer->transactions[index] =
3204                 ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
3205                  ((((convert_addr1 & 0xFFFFF000U) - (convert_addr & 0xFFFFF000U)) >> EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
3206                   << EHCI_HOST_ITD_PG_SHIFT) |
3207                  (convert_addr1 & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
3208             dataLength -= transactionLength;
3209             convert_addr1 += transactionLength;
3210 #else
3211             /* initialize the uframeIndex's transaction descriptor in itd */
3212             itdPointer->transactions[index] =
3213                 ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) |
3214                  ((((itdBufferValue & 0xFFFFF000U) - (itdBufferBaseValue & 0xFFFFF000U)) >>
3215                    EHCI_HOST_ITD_BUFFER_POINTER_SHIFT)
3216                   << EHCI_HOST_ITD_PG_SHIFT) |
3217                  (itdBufferValue & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK));
3218             dataLength -= transactionLength;
3219             itdBufferValue += transactionLength;
3220 #endif
3221             if (dataLength <= 0U)
3222             {
3223                 break;
3224             }
3225         }
3226     }
3227 
3228     transfer->union2.unitTail = (uint32_t)itdPointer;
3229     itdPointer->transactions[index] |= (1UL << EHCI_HOST_ITD_IOC_SHIFT); /* last set IOC */
3230 
3231     itdPointer = itdHead;
3232     /* link itd to frame list (note: initialize frameEntryIndex)*/
3233     while (NULL != itdPointer)
3234     {
3235         void *temp            = (void *)ehciInstance->ehciFrameList;
3236         uint32_t *linkPointer = &((uint32_t *)temp)[linkUframe >> 3];
3237         uint32_t linkValue    = *linkPointer;
3238 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3239         linkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(linkValue);
3240 #endif
3241         itdPointer->frameEntryIndex = linkUframe >> 3;
3242         while ((0U == (linkValue & EHCI_HOST_T_INVALID_VALUE)) &&
3243                ((linkValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_ITD))
3244         {
3245             linkPointer = (uint32_t *)(linkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
3246             linkValue   = *linkPointer;
3247 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3248             linkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(linkValue);
3249 #endif
3250         }
3251         itdPointer->nextLinkPointer = *linkPointer;
3252 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3253         convert_addr = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(itdPointer);
3254         *linkPointer = ((uint32_t)convert_addr | EHCI_HOST_POINTER_TYPE_ITD);
3255 #else
3256         *linkPointer = ((uint32_t)itdPointer | EHCI_HOST_POINTER_TYPE_ITD);
3257 #endif
3258         itdPointer = itdPointer->nextItdPointer;
3259         if (itdPointer == NULL)
3260         {
3261             break;
3262         }
3263 
3264         linkUframe += ehciPipePointer->uframeInterval;
3265         lastShouldLinkUframe += ehciPipePointer->uframeInterval;
3266         if (linkUframe >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3))
3267         {
3268             linkUframe = (linkUframe - (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3));
3269         }
3270     }
3271 
3272     if (lastShouldLinkUframe > USB_HOST_EHCI_MAX_MICRFRAME_VALUE)
3273     {
3274         lastShouldLinkUframe = lastShouldLinkUframe - (USB_HOST_EHCI_MAX_MICRFRAME_VALUE + 1U);
3275     }
3276     isoPointer->lastLinkFrame = (uint16_t)lastShouldLinkUframe;
3277 
3278     return kStatus_USB_Success;
3279 }
3280 
USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_itd_t * startItdPointer,usb_host_ehci_itd_t * endItdPointer)3281 static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance,
3282                                             usb_host_ehci_itd_t *startItdPointer,
3283                                             usb_host_ehci_itd_t *endItdPointer)
3284 {
3285     usb_host_ehci_itd_t *itdPointer = startItdPointer;
3286     uint8_t index;
3287     uint32_t doneLength = 0;
3288 
3289     /* remove itd from frame list */
3290     while (1U == 1U)
3291     {
3292         /* record the transfer's result length */
3293         for (index = 0U; index < 8U; ++index)
3294         {
3295             doneLength += ((itdPointer->transactions[index] & EHCI_HOST_ITD_TRANSACTION_LEN_MASK) >>
3296                            EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT);
3297         }
3298 
3299         USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)itdPointer,
3300                                     (uint16_t)itdPointer->frameEntryIndex); /* remove from the inserted frame list */
3301 
3302         /* release itd */
3303         /* USB_HostEhciLock(); */
3304         /*set next link pointer to invalid in case hardware access invalid itd structure in special case*/
3305         itdPointer->nextLinkPointer = EHCI_HOST_T_INVALID_VALUE;
3306         USB_HostEhciZeroMem((uint32_t *)(void *)itdPointer + 1, ((sizeof(usb_host_ehci_itd_t) >> 2) - 4U));
3307         itdPointer->nextItdPointer = (usb_host_ehci_itd_t *)ehciInstance->ehciItdList;
3308         ehciInstance->ehciItdList  = itdPointer;
3309         ehciInstance->ehciItdNumber++;
3310         /* USB_HostEhciUnlock(); */
3311 
3312         if (itdPointer == endItdPointer)
3313         {
3314             break;
3315         }
3316         itdPointer = itdPointer->nextItdPointer;
3317     }
3318 
3319     return doneLength;
3320 }
3321 
USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3322 static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance,
3323                                                usb_host_ehci_pipe_t *ehciPipePointer)
3324 {
3325     usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3326     usb_host_transfer_t *transfer;
3327     usb_host_transfer_t *nextTransfer;
3328     uint32_t doneLength = 0;
3329 
3330     /* firstly remove the transfer (because host task may occupy to access the resource) */
3331     USB_HostEhciLock();
3332     transfer                     = isoPointer->ehciTransferHead;
3333     isoPointer->ehciTransferTail = NULL;
3334     isoPointer->ehciTransferHead = NULL;
3335     USB_HostEhciUnlock();
3336 
3337     while (transfer != NULL)
3338     {
3339         nextTransfer = transfer->next;
3340         doneLength   = 0;
3341         /* remove itd from frame list and release itd */
3342         doneLength = USB_HostEhciItdArrayRelease(ehciInstance, (usb_host_ehci_itd_t *)transfer->union1.unitHead,
3343                                                  (usb_host_ehci_itd_t *)transfer->union2.unitTail);
3344 
3345         /* transfer callback */
3346         if (ehciPipePointer->pipeCommon.direction == USB_OUT)
3347         {
3348             doneLength = transfer->transferLength;
3349         }
3350         transfer->transferSofar = doneLength;
3351         /* callback function is different from the current condition */
3352         USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferCancel);
3353 
3354         /* next transfer */
3355         transfer = nextTransfer;
3356     }
3357 
3358     return kStatus_USB_Success;
3359 }
3360 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
3361 
USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3362 static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance,
3363                                                 usb_host_ehci_pipe_t *ehciPipePointer)
3364 {
3365     usb_host_ehci_qh_t *qhPointer;
3366 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3367     uint32_t convert_addr = 0U;
3368 #endif
3369 
3370     if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) /* initialize control/bulk qh */
3371     {
3372         return kStatus_USB_Error;
3373     }
3374 
3375     qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
3376 
3377     /* add qh to async */
3378 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3379     qhPointer->horizontalLinkPointer =
3380         (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(ehciInstance->shedFirstQh->horizontalLinkPointer);
3381     convert_addr                                     = (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(qhPointer);
3382     ehciInstance->shedFirstQh->horizontalLinkPointer = (convert_addr | EHCI_HOST_POINTER_TYPE_QH);
3383 #else
3384     qhPointer->horizontalLinkPointer                 = ehciInstance->shedFirstQh->horizontalLinkPointer;
3385     ehciInstance->shedFirstQh->horizontalLinkPointer = ((uint32_t)qhPointer | EHCI_HOST_POINTER_TYPE_QH);
3386 #endif
3387 
3388     return kStatus_USB_Success;
3389 }
3390 
USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3391 static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance,
3392                                                  usb_host_ehci_pipe_t *ehciPipePointer)
3393 {
3394     volatile usb_host_ehci_qh_t *vltPrevQhPointer;
3395     uint32_t horizontalLinkValue;
3396     uint32_t *temp;
3397 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3398     uint32_t convert_addr = 0U;
3399 #endif
3400 
3401     /* remove qh from async schedule */
3402     temp = (uint32_t *)ehciPipePointer->ehciQh;
3403 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3404     convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(ehciInstance->shedFirstQh->horizontalLinkPointer);
3405     if ((convert_addr & EHCI_HOST_POINTER_ADDRESS_MASK) ==
3406 #else
3407     if ((ehciInstance->shedFirstQh->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK) ==
3408 #endif
3409         (uint32_t)temp) /* the removing qh is the first qh in the async list */
3410     {
3411         USB_HostEhciLock();
3412         USB_HostEhciStopAsync(ehciInstance);
3413         ehciInstance->shedFirstQh->horizontalLinkPointer =
3414             ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
3415         USB_HostEhciStartAsync(ehciInstance);
3416         USB_HostEhciUnlock();
3417     }
3418     else
3419     {
3420         /* search for the removing qh from the async list */
3421         vltPrevQhPointer = ehciInstance->shedFirstQh;
3422         while (vltPrevQhPointer != NULL)
3423         {
3424 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
3425             horizontalLinkValue = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltPrevQhPointer->horizontalLinkPointer);
3426 #else
3427             horizontalLinkValue = vltPrevQhPointer->horizontalLinkPointer;
3428 #endif
3429             if ((0U != (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) ||
3430                 ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp) ||
3431                 ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciInstance->shedFirstQh))
3432             {
3433                 break;
3434             }
3435 
3436             vltPrevQhPointer = (volatile usb_host_ehci_qh_t *)(horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK);
3437         }
3438 
3439         /* remove the qh from async list */
3440         /*for misra 11.6*/
3441         temp = (uint32_t *)ehciPipePointer->ehciQh;
3442         if ((vltPrevQhPointer != NULL) && (0U == (horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) &&
3443             ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)temp))
3444         {
3445             USB_HostEhciLock();
3446             USB_HostEhciStopAsync(ehciInstance);
3447             vltPrevQhPointer->horizontalLinkPointer =
3448                 ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer;
3449             USB_HostEhciStartAsync(ehciInstance);
3450             USB_HostEhciUnlock();
3451         }
3452     }
3453     ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer =
3454         EHCI_HOST_T_INVALID_VALUE;                              /* invalid next qh link */
3455     return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initialize qh and release qh */
3456 }
3457 
USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3458 static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance,
3459                                               usb_host_ehci_pipe_t *ehciPipePointer)
3460 {
3461     usb_status_t status = kStatus_USB_Success;
3462     uint32_t frameIndex;
3463     uint32_t *temp;
3464 
3465     /* allocate bandwidth */
3466     if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
3467     {
3468         status = USB_HostBandwidthHsHostAllocateInterrupt(ehciInstance, ehciPipePointer); /* host works as high-speed */
3469     }
3470     else
3471     {
3472         status = USB_HostBandwidthFslsHostAllocate(ehciInstance,
3473                                                    ehciPipePointer); /* host works as full-speed or low-speed */
3474     }
3475 
3476     if (status != kStatus_USB_Success)
3477     {
3478         return status;
3479     }
3480     if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success)
3481     {
3482         return kStatus_USB_Error;
3483     }
3484 
3485     /* insert QH to frame list */
3486     for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
3487          frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
3488     {
3489         temp = (uint32_t *)ehciPipePointer->ehciQh;
3490         USB_HostEhciAddQhToFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex, ehciPipePointer->uframeInterval);
3491     }
3492 
3493     return kStatus_USB_Success;
3494 }
3495 
USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3496 static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance,
3497                                                usb_host_ehci_pipe_t *ehciPipePointer)
3498 {
3499     uint32_t frameIndex;
3500     uint32_t *temp;
3501     /* remove from frame list */
3502     for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE;
3503          frameIndex += (((uint32_t)ehciPipePointer->uframeInterval + 7U) / 8U))
3504     {
3505         temp = (uint32_t *)ehciPipePointer->ehciQh;
3506         USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)temp, (uint16_t)frameIndex);
3507     }
3508     ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer |=
3509         EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */
3510 
3511     return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initilaze qh and release qh */
3512 }
3513 
3514 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3515      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3516 
USB_HostEhciOpenIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3517 static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
3518 {
3519     usb_host_ehci_iso_t *isoPointer;
3520     usb_status_t status = kStatus_USB_Success;
3521 
3522     if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
3523     {
3524         status = USB_HostBandwidthHsHostAllocateIso(
3525             ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as high-speed */
3526     }
3527     else
3528     {
3529         status = USB_HostBandwidthFslsHostAllocate(
3530             ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as full-speed or low-speed */
3531     }
3532 
3533     if (status != kStatus_USB_Success)
3534     {
3535         return status;
3536     }
3537 
3538     /* get usb_host_ehci_iso_t */
3539     if (ehciInstance->ehciIsoList == NULL)
3540     {
3541         return kStatus_USB_Error;
3542     }
3543     USB_HostEhciLock();
3544     isoPointer                = ehciInstance->ehciIsoList;
3545     ehciInstance->ehciIsoList = ehciInstance->ehciIsoList->next;
3546     USB_HostEhciUnlock();
3547     isoPointer->lastLinkFrame = 0xFFFF;
3548     ehciPipePointer->ehciQh   = isoPointer;
3549 
3550     return status;
3551 }
3552 
USB_HostEhciCloseIso(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer)3553 static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer)
3554 {
3555     usb_host_ehci_iso_t *isoPointer;
3556     uint32_t speed = 0U;
3557 
3558     isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3559 
3560     if (isoPointer->ehciTransferHead != NULL)
3561     {
3562         (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3563                                                      (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
3564         if (speed == USB_SPEED_HIGH)
3565         {
3566 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3567             (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd list and free them */
3568 #endif
3569         }
3570         else
3571         {
3572 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3573             (void)USB_HostEhciSitdArrayDeinit(ehciInstance,
3574                                               ehciPipePointer); /* de-initialize sitd list and free them */
3575 #endif
3576         }
3577     }
3578 
3579     /* release usb_host_ehci_iso_t */
3580     USB_HostEhciLock();
3581     isoPointer->next          = ehciInstance->ehciIsoList;
3582     ehciInstance->ehciIsoList = isoPointer;
3583     USB_HostEhciUnlock();
3584     return kStatus_USB_Success;
3585 }
3586 
3587 #endif
3588 
USB_HostEhciResetIP(usb_host_ehci_instance_t * ehciInstance)3589 static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance)
3590 {
3591     /* For eUSB, do not need to reset controller. */
3592 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
3593     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
3594 #endif
3595     {
3596 	    /* reset controller */
3597 	    ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RST_MASK;
3598 	    while (0U != (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_RST_MASK))
3599 	    {
3600 	    }
3601 	}
3602 
3603 /* set host mode */
3604 #if (ENDIANNESS == USB_LITTLE_ENDIAN)
3605     ehciInstance->ehciIpBase->USBMODE |= 0x03U;
3606 #else
3607     ehciInstance->ehciIpBase->USBMODE |= (0x03U | (0x01U << USBHS_USBMODE_ES_SHIFT));
3608 #endif
3609     /* check frame list size */
3610     if (0U == (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
3611     {
3612 #if ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE < 8) || (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE > 1024))
3613         return kStatus_USB_Error;
3614 #endif
3615 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE & (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE - 1))
3616         return kStatus_USB_Error; /* frame size must be 1024/512/256/128/64/32/16/8 */
3617 #endif
3618     }
3619     return kStatus_USB_Success;
3620 }
3621 
USB_HostEhciStartIP(usb_host_ehci_instance_t * ehciInstance)3622 static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance)
3623 {
3624     uint32_t tmp = 0;
3625 
3626     if (0U != (ehciInstance->ehciIpBase->HCSPARAMS & USBHS_HCSPARAMS_PPC_MASK)) /* Ports have power port switches */
3627     {
3628         /* only has one port */
3629         tmp = ehciInstance->ehciIpBase->PORTSC1;
3630         tmp &= (~EHCI_PORTSC1_W1_BITS);
3631         ehciInstance->ehciIpBase->PORTSC1 = (tmp | USBHS_PORTSC1_PP_MASK); /* turn on port power */
3632     }
3633 
3634     /* set frame list size */
3635     if (0U != (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK))
3636     {
3637 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE <= 64)
3638         ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_FS2_MASK);
3639 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 64)
3640         ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
3641 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 32)
3642         ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
3643 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 16)
3644         ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
3645 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 8)
3646         ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
3647 #endif
3648 #else
3649 #if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 1024)
3650         ehciInstance->ehciIpBase->USBCMD |= (0x00U << USBHS_USBCMD_FS_SHIFT);
3651 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 512)
3652         ehciInstance->ehciIpBase->USBCMD |= (0x01U << USBHS_USBCMD_FS_SHIFT);
3653 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 256)
3654         ehciInstance->ehciIpBase->USBCMD |= (0x02U << USBHS_USBCMD_FS_SHIFT);
3655 #elif (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 128)
3656         ehciInstance->ehciIpBase->USBCMD |= (0x03U << USBHS_USBCMD_FS_SHIFT);
3657 #endif
3658 #endif
3659     }
3660     /* no interrupt threshold */
3661     ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK;
3662     /* start the controller */
3663     ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_RS_MASK;
3664     /* set timer0 */
3665     ehciInstance->ehciIpBase->GPTIMER0LD = (100U * 1000U - 1U); /* 100ms */
3666 
3667     /* enable interrupt (USB interrupt enable + USB error interrupt enable + port change detect enable + system error
3668      * enable + interrupt on async advance enable) + general purpos Timer 0 Interrupt enable */
3669     ehciInstance->ehciIpBase->USBINTR |= (0x1000037U);
3670 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
3671 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
3672     ehciInstance->ehciIpBase->USBINTR |= USB_USBINTR_LPM_HST_COMPIE_MASK;
3673     ehciInstance->registerNcBase->LPM_CSR0 |= USBNC_LPM_CSR0_LPM_EN_MASK;
3674 #endif
3675 #endif
3676 
3677     return kStatus_USB_Success;
3678 }
3679 
USB_HostEhciCancelPipe(usb_host_ehci_instance_t * ehciInstance,usb_host_ehci_pipe_t * ehciPipePointer,usb_host_transfer_t * transfer)3680 static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance,
3681                                            usb_host_ehci_pipe_t *ehciPipePointer,
3682                                            usb_host_transfer_t *transfer)
3683 {
3684     usb_host_ehci_qh_t *qhPointer;
3685 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3686      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3687     usb_host_ehci_iso_t *isoPointer;
3688     uint32_t speed = 0U;
3689 #endif
3690     uint8_t cancelPipe = 0;
3691 
3692     switch (ehciPipePointer->pipeCommon.pipeType)
3693     {
3694         case USB_ENDPOINT_BULK:
3695         case USB_ENDPOINT_CONTROL:
3696         case USB_ENDPOINT_INTERRUPT:
3697             qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
3698             if (qhPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
3699             {
3700                 return kStatus_USB_Success;
3701             }
3702             if (transfer != NULL)
3703             {
3704                 if ((qhPointer->ehciTransferHead == transfer) &&
3705                     (qhPointer->ehciTransferHead == qhPointer->ehciTransferTail)) /* only has this one transfer */
3706                 {
3707                     cancelPipe = 1U;
3708                 }
3709                 else
3710                 {
3711                     cancelPipe = 0U;
3712                 }
3713             }
3714             else
3715             {
3716                 cancelPipe = 1U;
3717             }
3718             if (cancelPipe == 1U) /* cancel all pipe */
3719             {
3720                 (void)USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); /* release all the qtd */
3721             }
3722             else /* cancel one transfer */
3723             {
3724                 (void)USB_HostEhciTransferQtdListDeinit(ehciInstance, ehciPipePointer, transfer);
3725             }
3726             break;
3727 
3728 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3729      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3730         case USB_ENDPOINT_ISOCHRONOUS:
3731             isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh;
3732             if (isoPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */
3733             {
3734                 return kStatus_USB_Success;
3735             }
3736             /* cancel all pipe, don't implement canceling transfer for iso */
3737             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
3738                                                          (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
3739             if (speed == USB_SPEED_HIGH)
3740             {
3741 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3742                 (void)USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd */
3743 #endif
3744             }
3745             else
3746             {
3747 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3748                 (void)USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd */
3749 #endif
3750             }
3751             break;
3752 #endif
3753 
3754         default:
3755             /*no action*/
3756             break;
3757     }
3758 
3759     return kStatus_USB_Success;
3760 }
3761 
USB_HostEhciControlBus(usb_host_ehci_instance_t * ehciInstance,uint8_t busControl)3762 static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl)
3763 {
3764     usb_status_t status = kStatus_USB_Success;
3765     uint32_t portScRegister;
3766     usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
3767     switch (controlCode)
3768     {
3769         case kUSB_HostBusReset:
3770             /* reset port */
3771             portScRegister = ehciInstance->ehciIpBase->PORTSC1;
3772             portScRegister &= (~EHCI_PORTSC1_W1_BITS);
3773             ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
3774             while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
3775             {
3776             }
3777             break;
3778 
3779         case kUSB_HostBusRestart:
3780             ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
3781             ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
3782             break;
3783 
3784         case kUSB_HostBusEnableAttach: /* enable device attach */
3785             if (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceDetached)
3786             {
3787                 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */
3788             }
3789             break;
3790 
3791         case kUSB_HostBusDisableAttach:                                     /* disable device attach */
3792             ehciInstance->ehciIpBase->USBINTR &= (~USBHS_USBINTR_PCE_MASK); /* disable ehci port change interrupt */
3793             break;
3794 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
3795         case kUSB_HostBusSuspend:
3796             if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
3797             {
3798                 /* set timer1 */
3799                 ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */
3800                 ehciInstance->ehciIpBase->GPTIMER1CTL |=
3801                     (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
3802                 USB_HostEhciLock();
3803                 USB_HostEhciStopAsync(ehciInstance);
3804                 USB_HostEhciStopPeriodic(ehciInstance);
3805                 USB_HostEhciUnlock();
3806                 while (0U != (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)))
3807                 {
3808                     __NOP();
3809                 }
3810                 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK;
3811                 ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK;
3812                 ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_SUSP_MASK); /* Suspend the device */
3813 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
3814                 PMU->WAKEUP_PM2_MASK1 |= PMU_WAKEUP_PM2_MASK1_USB(1);
3815 #endif
3816                 ehciInstance->matchTick = 0U;
3817                 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK);
3818                 ehciInstance->busSuspendStatus = kBus_EhciStartSuspend;
3819             }
3820             else
3821             {
3822                 status = kStatus_USB_Error;
3823             }
3824             break;
3825         case kUSB_HostBusResume:
3826             ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */
3827             ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
3828             if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
3829             {
3830                 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
3831 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
3832                 ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
3833 #else
3834 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
3835 #else
3836                 ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
3837 #endif
3838 #endif
3839                 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
3840                 ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */
3841             }
3842             else
3843             {
3844                 status = kStatus_USB_Error;
3845             }
3846             break;
3847 
3848 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
3849         case kUSB_HostBusL1Sleep:
3850             if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
3851             {
3852                 volatile uint32_t lpm_count = 200000U;
3853                 OSA_SR_ALLOC();
3854                  /* set timer1 */
3855                 ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */
3856                 ehciInstance->ehciIpBase->GPTIMER1CTL |=
3857                     (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
3858                 USB_HostEhciLock();
3859                 USB_HostEhciStopAsync(ehciInstance);
3860                 USB_HostEhciStopPeriodic(ehciInstance);
3861                 USB_HostEhciUnlock();
3862                 while (0U != (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)))
3863                 {
3864                     __NOP();
3865                 }
3866                 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK;
3867                 ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK;
3868                 ehciInstance->matchTick = 0U;
3869                 ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK);
3870                 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
3871                 portScRegister = ehciInstance->registerNcBase->LPM_CSR2;
3872                 portScRegister &= ~(USBNC_LPM_CSR2_LPM_HST_BESL_MASK | USBNC_LPM_CSR2_LPM_HST_RWKEN_MASK);
3873                 portScRegister |= (uint32_t)(
3874                     ((uint32_t)ehciInstance->hirdValue << USBNC_LPM_CSR2_LPM_HST_BESL_SHIFT) |
3875                     ((uint32_t)ehciInstance->L1remoteWakeupEnable << USBNC_LPM_CSR2_LPM_HST_RWKEN_SHIFT));
3876                 ehciInstance->registerNcBase->LPM_CSR2 = portScRegister;
3877 
3878                 usb_host_device_instance_t *deviceInstance;
3879 
3880                 ehciInstance->busSuspendStatus = kBus_EhciL1StartSleep;
3881                 deviceInstance = (usb_host_device_instance_t *)hostPointer->suspendedDevice;
3882                  OSA_ENTER_CRITICAL();
3883                 /* Workaroud for TKT0634948: begin */
3884                 ehciInstance->ehciIpBase->USBSTS |= USB_USBSTS_SRI_MASK;
3885                 /* wait the next SOF */
3886                 while ((0U == (ehciInstance->ehciIpBase->USBSTS & USB_USBSTS_SRI_MASK)) && (0U != lpm_count))
3887                 {
3888                     lpm_count--;
3889                 }
3890                 ehciInstance->registerNcBase->LPM_CSR2 |= ((uint32_t)USBNC_LPM_CSR2_LPM_HST_SEND_MASK |
3891                   (((uint32_t)deviceInstance->setAddress << USBNC_LPM_CSR2_LPM_HST_DEVADD_SHIFT) &
3892                   (uint32_t)USBNC_LPM_CSR2_LPM_HST_DEVADD_MASK));
3893                 /* Workaroud for TKT0634948: end */
3894                 OSA_EXIT_CRITICAL();
3895             }
3896             else
3897             {
3898                 status = kStatus_USB_Error;
3899             }
3900             break;
3901 
3902         case kUSB_HostBusL1Resume:
3903             ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */
3904             ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK;
3905             if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
3906             {
3907                 ehciInstance->busSuspendStatus = kBus_EhciL1StartResume;
3908                 ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
3909                 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
3910                 ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */
3911             }
3912             else
3913             {
3914                 status = kStatus_USB_Error;
3915             }
3916             break;
3917 #endif /* USB_HOST_CONFIG_LPM_L1 */
3918 #endif /* USB_HOST_CONFIG_LOW_POWER_MODE */
3919         default:
3920             status = kStatus_USB_Error;
3921             break;
3922     }
3923     return status;
3924 }
3925 
USB_HostEhciTransferCallback(usb_host_transfer_t * transfer,usb_status_t status)3926 static void USB_HostEhciTransferCallback(usb_host_transfer_t *transfer, usb_status_t status)
3927 {
3928 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
3929     if ((transfer->direction == USB_IN) && (transfer->transferSofar > 0U))
3930     {
3931         DCACHE_InvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferSofar);
3932     }
3933 #endif
3934     transfer->callbackFn(transfer->callbackParam, transfer, status);
3935 }
3936 
USB_HostEhciTransactionDone(usb_host_ehci_instance_t * ehciInstance)3937 void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance)
3938 {
3939     /* process async QH */
3940     usb_host_ehci_pipe_t *ehciPipePointer;
3941     usb_host_ehci_pipe_t *ehciClearPipePointer = NULL;
3942     volatile usb_host_ehci_qh_t *vltQhPointer;
3943     volatile usb_host_ehci_qtd_t *vltQtdPointer;
3944     usb_host_transfer_t *transfer;
3945     usb_host_transfer_t *nextTransfer;
3946     uint32_t qtdStatus = 0;
3947 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
3948     volatile usb_host_ehci_itd_t *vltItdPointer;
3949     uint8_t index = 0;
3950 #endif
3951 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
3952     volatile usb_host_ehci_sitd_t *vltSitdPointer;
3953 #endif
3954 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
3955      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
3956     usb_host_ehci_iso_t *isoPointer;
3957     uint32_t dataLength;
3958     uint32_t speed = 0U;
3959 #endif
3960     void *temp;
3961     uint32_t transferResults;
3962     uint32_t transferOverlayResults;
3963 
3964     ehciPipePointer = ehciInstance->ehciRunningPipeList; /* check all the running pipes */
3965     while (ehciPipePointer != NULL)
3966     {
3967         switch (ehciPipePointer->pipeCommon.pipeType)
3968         {
3969             case USB_ENDPOINT_BULK:
3970             case USB_ENDPOINT_INTERRUPT:
3971             case USB_ENDPOINT_CONTROL:
3972                 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
3973                 transfer     = vltQhPointer->ehciTransferHead;                         /* qh's transfer */
3974                 while (transfer != NULL)
3975                 {
3976                     nextTransfer = transfer->next;
3977                     /* normal case */
3978                     vltQtdPointer          = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail;
3979                     transferResults        = vltQtdPointer->transferResults[0];
3980                     transferOverlayResults = vltQhPointer->transferOverlayResults[0];
3981                     if ((0U != (transferResults & (EHCI_HOST_QTD_IOC_MASK))) &&
3982                         (0U == (transferResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) /* transfer is done */
3983                     {
3984                         qtdStatus = (transferResults & EHCI_HOST_QTD_STATUS_ERROR_MASK);
3985                         transfer->transferSofar =
3986                             USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
3987                                                        (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
3988                         transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
3989                                                       0U :
3990                                                       (transfer->transferLength - transfer->transferSofar);
3991 
3992                         vltQhPointer->ehciTransferHead = transfer->next;
3993                         vltQhPointer->timeOutLabel     = 0U;
3994                         vltQhPointer->timeOutValue     = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
3995                         if (0U != qtdStatus) /* has errors */
3996                         {
3997                             if (0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
3998                             {
3999                                 vltQhPointer->transferOverlayResults[0] &=
4000                                     (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4001                             }
4002                             if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
4003                             {
4004                                 /* callback function is different from the current condition */
4005                                 USB_HostEhciTransferCallback(transfer,
4006                                                      kStatus_USB_TransferFailed); /* transfer fail */
4007                             }
4008                             else
4009                             {
4010                                 /* callback function is different from the current condition */
4011                                 USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferStall);
4012                             }
4013                         }
4014                         else
4015                         {
4016                             if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) &&
4017                                 (transfer->setupPacket->bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) &&
4018                                 (transfer->setupPacket->bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
4019                                 ((USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wValue) & 0x00FFu) ==
4020                                  USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT))
4021                             {
4022                                 ehciClearPipePointer = ehciInstance->ehciRunningPipeList;
4023                                 while (ehciClearPipePointer != NULL)
4024                                 {
4025                                     /* only compute bulk and interrupt pipe */
4026                                     if (((ehciClearPipePointer->pipeCommon.endpointAddress |
4027                                           (ehciClearPipePointer->pipeCommon.direction
4028                                            << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
4029                                          (uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wIndex))) &&
4030                                         (ehciClearPipePointer->pipeCommon.deviceHandle ==
4031                                          ehciPipePointer->pipeCommon.deviceHandle))
4032                                     {
4033                                         break;
4034                                     }
4035                                     temp                 = (void *)ehciClearPipePointer->pipeCommon.next;
4036                                     ehciClearPipePointer = (usb_host_ehci_pipe_t *)temp;
4037                                 }
4038 
4039                                 if ((ehciClearPipePointer != NULL) &&
4040                                     ((ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) ||
4041                                      (ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_BULK)))
4042                                 {
4043                                     ((volatile usb_host_ehci_qh_t *)(ehciClearPipePointer->ehciQh))
4044                                         ->transferOverlayResults[0] &= (~EHCI_HOST_QTD_DT_MASK);
4045                                 }
4046                             }
4047                             /* callback function is different from the current condition */
4048                             USB_HostEhciTransferCallback(transfer,
4049                                                  kStatus_USB_Success); /* transfer success */
4050                         }
4051                     }
4052                     else if ((0U == (transferOverlayResults & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) &&
4053                              (0U != (transferOverlayResults &
4054                                      EHCI_HOST_QH_STATUS_ERROR_MASK))) /* there is error and transfer is done */
4055                     {
4056                         qtdStatus     = (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QH_STATUS_ERROR_MASK);
4057                         vltQtdPointer = (volatile usb_host_ehci_qtd_t *)(vltQhPointer->currentQtdPointer);
4058 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4059                         vltQtdPointer = (volatile usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer);
4060 #endif
4061                         if ((0U != ((uint32_t)vltQtdPointer & EHCI_HOST_T_INVALID_VALUE)) ||
4062                             (vltQtdPointer == NULL)) /* the error status is unreasonable */
4063                         {
4064                             vltQhPointer->transferOverlayResults[0] &=
4065                                 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4066                         }
4067                         else
4068                         {
4069                             /* remove qtd from qh */
4070                             do
4071                             {
4072                                 if (vltQtdPointer == NULL)
4073                                 {
4074                                     break;
4075                                 }
4076                                 else if (0U != (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK))
4077                                 {
4078                                     break;
4079                                 }
4080                                 else
4081                                 {
4082                                     /* no action */
4083                                 }
4084                                 vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
4085 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4086                                 vltQtdPointer =
4087                                     (volatile usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer);
4088 #endif
4089                             } while (true);
4090 
4091                             vltQhPointer->nextQtdPointer    = EHCI_HOST_T_INVALID_VALUE;
4092                             vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE;
4093                             vltQhPointer->transferOverlayResults[0] &=
4094                                 (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4095                             if (vltQtdPointer != NULL)
4096                             {
4097 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4098                                 vltQhPointer->nextQtdPointer =
4099                                     (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
4100 #else
4101                                 vltQhPointer->nextQtdPointer = vltQtdPointer->nextQtdPointer;
4102 #endif
4103                             }
4104 
4105                             transfer->transferSofar = USB_HostEhciQtdListRelease(
4106                                 ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
4107                                 (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
4108                             transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
4109                                                           0U :
4110                                                           (transfer->transferLength - transfer->transferSofar);
4111                             vltQhPointer->ehciTransferHead = transfer->next;
4112                             vltQhPointer->timeOutLabel     = 0U;
4113                             vltQhPointer->timeOutValue     = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
4114                             if (0U != (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK))
4115                             {
4116                                 /* callback function is different from the current condition */
4117                                 USB_HostEhciTransferCallback(transfer,
4118                                                      kStatus_USB_TransferFailed); /* transfer fail */
4119                             }
4120                             else
4121                             {
4122                                 /* callback function is different from the current condition */
4123                                 USB_HostEhciTransferCallback(transfer,
4124                                                      kStatus_USB_TransferStall); /* transfer stall */
4125                             }
4126                         }
4127                     }
4128                     else
4129                     {
4130                         break;
4131                     }
4132                     transfer = nextTransfer;
4133                 }
4134                 break;
4135 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
4136      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
4137             case USB_ENDPOINT_ISOCHRONOUS:
4138                 qtdStatus  = 0; /* qtdStatus means break here, because there is only one break in while for misra */
4139                 isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; /* pipe's usb_host_ehci_iso_t */
4140                 transfer   = isoPointer->ehciTransferHead;                   /* usb_host_ehci_iso_t's transfer */
4141                 while (transfer != NULL)
4142                 {
4143                     nextTransfer = transfer->next;
4144                     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
4145                                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
4146                     if (speed == USB_SPEED_HIGH)
4147                     {
4148 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4149                         vltItdPointer =
4150                             (volatile usb_host_ehci_itd_t *)(transfer->union2.unitTail); /* transfer's last itd */
4151                         for (index = 0; index < 8U; ++index)
4152                         {
4153                             if (0U != (vltItdPointer->transactions[index] & EHCI_HOST_ITD_STATUS_ACTIVE_MASK))
4154                             {
4155                                 break;
4156                             }
4157                         }
4158                         if (index == 8U) /* transfer is done */
4159                         {
4160                             /* remove itd from frame list and release itd */
4161                             dataLength                   = USB_HostEhciItdArrayRelease(ehciInstance,
4162                                                                      (usb_host_ehci_itd_t *)transfer->union1.unitHead,
4163                                                                      (usb_host_ehci_itd_t *)transfer->union2.unitTail);
4164                             transfer->transferSofar      = dataLength;
4165                             isoPointer->ehciTransferHead = transfer->next;
4166                             /* callback function is different from the current condition */
4167                             USB_HostEhciTransferCallback(transfer,
4168                                                  kStatus_USB_Success); /* transfer callback success */
4169                             /* TODO: iso callback error */
4170                         }
4171                         else
4172                         {
4173                             qtdStatus = 1U; /* break */
4174                         }
4175 #endif
4176                     }
4177                     else
4178                     {
4179 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
4180                         vltSitdPointer =
4181                             (volatile usb_host_ehci_sitd_t *)(transfer->union2.unitTail); /* transfer's last sitd */
4182                         if (0U == (vltSitdPointer->transferResults[0] &
4183                                    EHCI_HOST_SITD_STATUS_ACTIVE_MASK)) /* transfer is done */
4184                         {
4185                             /* remove sitd from frame list and release itd */
4186                             dataLength = USB_HostEhciSitdArrayRelease(
4187                                 ehciInstance, (usb_host_ehci_sitd_t *)transfer->union1.unitHead,
4188                                 (usb_host_ehci_sitd_t *)transfer->union2.unitTail);
4189                             transfer->transferSofar      = transfer->transferLength - dataLength;
4190                             isoPointer->ehciTransferHead = transfer->next;
4191                             /* callback function is different from the current condition */
4192                             USB_HostEhciTransferCallback(transfer,
4193                                                  kStatus_USB_Success); /* transfer callback success */
4194                             /* TODO: iso callback error */
4195                         }
4196                         else
4197                         {
4198                             qtdStatus = 1U; /* break */
4199                         }
4200 #endif
4201                     }
4202                     if (qtdStatus == 1U)
4203                     {
4204                         break;
4205                     }
4206                     transfer = nextTransfer;
4207                 }
4208                 break;
4209 #endif
4210 
4211             default:
4212                 /*no action*/
4213                 break;
4214         }
4215         temp            = (void *)ehciPipePointer->pipeCommon.next;
4216         ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
4217     }
4218 }
4219 
USB_HostEhciPortChange(usb_host_ehci_instance_t * ehciInstance)4220 static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance)
4221 {
4222     /* note: only has one port */
4223     uint32_t portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4224     uint32_t sofStart       = 0;
4225     uint32_t sofCount       = 0;
4226     uint32_t index;
4227 
4228     if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK)) /* connection status change */
4229     {
4230         sofStart = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
4231 
4232         /* process CSC bit */
4233         while (1U == 1U)
4234         {
4235             portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4236             if (0U != (portScRegister & USBHS_PORTSC1_CSC_MASK))
4237             {
4238                 /* clear csc bit */
4239                 portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4240                 portScRegister &= (~EHCI_PORTSC1_W1_BITS);
4241                 ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_CSC_MASK);
4242             }
4243             sofCount = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE);
4244             if (((sofCount + EHCI_MAX_UFRAME_VALUE + 1U - sofStart) & EHCI_MAX_UFRAME_VALUE) >
4245                 (1U * 8U)) /* delay 1ms to clear CSC */
4246             {
4247                 break;
4248             }
4249         }
4250     }
4251 
4252     /* process CCS bit */
4253     portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4254     if (0U != (portScRegister & USBHS_PORTSC1_CCS_MASK)) /* process attach */
4255     {
4256         if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
4257             (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
4258         {
4259             return;
4260         }
4261 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4262         ehciInstance->busSuspendStatus = kBus_EhciIdle;
4263         ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4264 #endif
4265         for (index = 0; index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY; ++index)
4266         {
4267             USB_HostEhciDelay(ehciInstance->ehciIpBase, 1);
4268             if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
4269             {
4270                 break;
4271             }
4272         }
4273         if (index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY) /* CCS is cleared */
4274         {
4275             ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
4276             return;
4277         }
4278         /* reset port */
4279         portScRegister = ehciInstance->ehciIpBase->PORTSC1;
4280         portScRegister &= (~EHCI_PORTSC1_W1_BITS);
4281         ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK);
4282         while (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK))
4283         {
4284         }
4285         ehciInstance->firstDeviceSpeed =
4286             (uint8_t)((ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PSPD_MASK) >> USBHS_PORTSC1_PSPD_SHIFT);
4287         /* enable ehci phy disconnection */
4288 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4289 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4290         if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4291 #endif
4292         {
4293             if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH)
4294             {
4295                 USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 1);
4296             }
4297         }
4298 #endif
4299 
4300         /* wait for reset */
4301         USB_HostEhciDelay(ehciInstance->ehciIpBase, USB_HOST_EHCI_PORT_RESET_DELAY);
4302         /* process attach */
4303         (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_ATTACH);
4304         /* gpt timer start */
4305         ehciInstance->ehciIpBase->GPTIMER0CTL |=
4306             (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK);
4307         ehciInstance->deviceAttached = (uint8_t)kEHCIDevicePhyAttached;
4308     }
4309     else
4310     {
4311         if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDevicePhyAttached) ||
4312             (ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
4313         {
4314 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4315             ehciInstance->busSuspendStatus = kBus_EhciIdle;
4316             ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4317 #endif
4318             /* disable ehci phy disconnection */
4319 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4320 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4321             if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4322 #endif
4323             {
4324                 USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 0);
4325             }
4326 #endif
4327             USB_HostEhciLock();
4328             /* disable async and periodic */
4329             USB_HostEhciStopAsync(ehciInstance);
4330             USB_HostEhciStopPeriodic(ehciInstance);
4331             USB_HostEhciUnlock();
4332             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_DETACH);
4333         }
4334     }
4335 }
4336 
USB_HostEhciTimer0(usb_host_ehci_instance_t * ehciInstance)4337 static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance)
4338 {
4339     volatile usb_host_ehci_qh_t *vltQhPointer;
4340     usb_host_ehci_qtd_t *vltQtdPointer;
4341     usb_host_transfer_t *transfer;
4342     uint32_t backValue;
4343 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4344     uint32_t convert_addr = 0U;
4345 #endif
4346     volatile uint32_t *totalBytesAddress  = NULL;
4347     usb_host_ehci_pipe_t *ehciPipePointer = ehciInstance->ehciRunningPipeList;
4348     void *temp;
4349     uint8_t timeoutLabel;
4350 
4351     while (ehciPipePointer != NULL)
4352     {
4353         switch (ehciPipePointer->pipeCommon.pipeType)
4354         {
4355             case USB_ENDPOINT_BULK:
4356             case USB_ENDPOINT_CONTROL:
4357                 vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */
4358                 transfer     = vltQhPointer->ehciTransferHead;                         /* qh's transfer */
4359                 if ((transfer != NULL))                                                /* there is transfering data */
4360                 {
4361                     timeoutLabel = 0U;
4362                     if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
4363                     {
4364                         vltQtdPointer = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
4365 
4366                         vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
4367                         vltQhPointer->transferOverlayResults[0] &=
4368                             (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4369                         timeoutLabel = 1;
4370                     }
4371                     else
4372                     {
4373                         if (0U != (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))
4374                         {
4375 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4376                             vltQtdPointer =
4377                                 (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQhPointer->currentQtdPointer);
4378 #else
4379                             vltQtdPointer = (usb_host_ehci_qtd_t *)vltQhPointer->currentQtdPointer;
4380 #endif
4381                             totalBytesAddress = &(vltQhPointer->transferOverlayResults[0]);
4382                         }
4383                         else
4384                         {
4385                             vltQtdPointer     = (usb_host_ehci_qtd_t *)transfer->union2.unitTail;
4386                             totalBytesAddress = &(vltQtdPointer->transferResults[0]);
4387                         }
4388 
4389                         backValue =
4390                             (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
4391                              EHCI_HOST_QTD_TOTAL_BYTES_SHIFT);       /* backValue is used for total bytes to transfer */
4392                         if (vltQhPointer->timeOutLabel != backValue) /* use total bytes to reflect the time out */
4393                         {
4394                             vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
4395                             vltQhPointer->timeOutLabel = (uint16_t)backValue;
4396                         }
4397                         else
4398                         {
4399                             /* time out when the total bytes don't change for the duration
4400                              * USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE
4401                              */
4402                             (vltQhPointer->timeOutValue)--;
4403                             if (vltQhPointer->timeOutValue == 0U)
4404                             {
4405                                 USB_HostEhciLock();
4406                                 /* stop the qh schedule */
4407                                 USB_HostEhciStopAsync(ehciInstance);
4408                                 if (backValue != (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >>
4409                                                   EHCI_HOST_QTD_TOTAL_BYTES_SHIFT))
4410                                 {
4411                                     USB_HostEhciStartAsync(ehciInstance);
4412                                 }
4413                                 else
4414                                 {
4415                                     vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */
4416                                     vltQhPointer->transferOverlayResults[0] &=
4417                                         (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */
4418                                     USB_HostEhciStartAsync(ehciInstance);
4419                                     timeoutLabel = 1U;
4420                                 }
4421                                 USB_HostEhciUnlock();
4422                             }
4423                         }
4424                     }
4425 
4426                     if (timeoutLabel == 1U)
4427                     {
4428                         /* remove qtd from qh */
4429                         temp = (void *)vltQhPointer->ehciTransferTail;
4430                         while ((vltQtdPointer != NULL) &&
4431                                (0U == (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK)) &&
4432                                (vltQtdPointer != (usb_host_ehci_qtd_t *)temp))
4433                         {
4434 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4435                             vltQtdPointer =
4436                                 (usb_host_ehci_qtd_t *)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
4437 #else
4438                             vltQtdPointer = (usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer;
4439 #endif
4440                         }
4441 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4442                         convert_addr = (uint32_t)USB_HOST_MEMORY_DMA_2_CPU(vltQtdPointer->nextQtdPointer);
4443                         if ((vltQtdPointer != NULL) && (0U == (convert_addr & EHCI_HOST_T_INVALID_VALUE)))
4444                         {
4445                             vltQhPointer->nextQtdPointer = convert_addr; /* start qh if there are other qtd that don't
4446                                                                             belong to the transfer */
4447                         }
4448 #else
4449                         if ((vltQtdPointer != NULL) &&
4450                             (0U == (vltQtdPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)))
4451                         {
4452                             vltQhPointer->nextQtdPointer =
4453                                 vltQtdPointer->nextQtdPointer; /* start qh if there are other qtd that don't belong to
4454                                                                   the transfer */
4455                         }
4456 #endif
4457                         transfer->transferSofar =
4458                             USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead),
4459                                                        (usb_host_ehci_qtd_t *)(transfer->union2.unitTail));
4460                         transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ?
4461                                                       0U :
4462                                                       (transfer->transferLength - transfer->transferSofar);
4463 
4464                         vltQhPointer->ehciTransferHead = transfer->next;
4465                         vltQhPointer->timeOutValue     = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE;
4466                         /* callback function is different from the current condition */
4467                         USB_HostEhciTransferCallback(transfer, kStatus_USB_TransferFailed);
4468                     }
4469                 }
4470                 break;
4471             default:
4472                 /*no action*/
4473                 break;
4474         }
4475         temp            = (void *)ehciPipePointer->pipeCommon.next;
4476         ehciPipePointer = (usb_host_ehci_pipe_t *)temp;
4477     }
4478 }
4479 
4480 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
USB_HostEhciTimer1(usb_host_ehci_instance_t * ehciInstance)4481 static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance)
4482 {
4483     if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceDetached)
4484     {
4485         if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
4486         {
4487             usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4488 
4489             if (0U == ehciInstance->matchTick)
4490             {
4491                 ehciInstance->matchTick = hostPointer->hwTick;
4492             }
4493             else
4494             {
4495                 if ((hostPointer->hwTick - ehciInstance->matchTick) >= 5U)
4496                 {
4497                     ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_RS_MASK;
4498                     ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
4499 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4500 #if 0
4501                     ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK
4502                                                       | USBPHY_CTRL_ENIDCHG_WKUP_MASK
4503                                                       | USBPHY_CTRL_ENDPDMCHG_WKUP_MASK
4504                                                       | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK
4505                                                       ;
4506 #endif
4507 #endif
4508 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
4509 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4510                     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4511 #endif
4512                     {
4513                         ehciInstance->registerPhyBase->USB1_VBUS_DETECT_SET |=
4514                             USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
4515                     }
4516 #endif
4517                     ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK;
4518 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4519 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4520                     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4521 #endif
4522                     {
4523                         ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU;
4524 
4525                         while (0U != (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)))
4526                         {
4527                             __NOP();
4528                         }
4529                     }
4530 #endif
4531 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4532 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4533                     ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
4534                                                                    USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
4535 #else
4536                     ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
4537                                                                    USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
4538                                                                    USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
4539 #endif
4540                     ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
4541 #else
4542 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
4543 #else
4544                     ehciInstance->ehciIpBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK;
4545 #endif
4546 #endif
4547 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4548 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4549                     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4550 #endif
4551                     {
4552                         ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
4553                     }
4554 #endif
4555                     (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4556                                                       kUSB_HostEventSuspended); /* call host callback function */
4557                     ehciInstance->busSuspendStatus = kBus_EhciSuspended;
4558                 }
4559             }
4560         }
4561         else if (kBus_EhciStartResume == ehciInstance->busSuspendStatus)
4562         {
4563             usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4564             if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
4565             {
4566                 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK;
4567                 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
4568                 {
4569                     USB_HostEhciLock();
4570                     USB_HostEhciStartAsync(ehciInstance);
4571                     USB_HostEhciStartPeriodic(ehciInstance);
4572                     USB_HostEhciUnlock();
4573                 }
4574                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4575                                                   kUSB_HostEventResumed); /* call host callback function */
4576                 hostPointer->suspendedDevice   = NULL;
4577                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4578                 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4579             }
4580         }
4581 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
4582         else if (kBus_EhciL1StartResume == ehciInstance->busSuspendStatus)
4583         {
4584             usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4585             if (0U == (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
4586             {
4587                 while (!(ehciInstance->ehciIpBase->USBSTS & USB_USBSTS_LPM_L1_EXITI_MASK))
4588                 {
4589                    __NOP();
4590                 }
4591                 /* clear L1 Exit Interrupt status */
4592                 ehciInstance->ehciIpBase->USBSTS |= USB_USBSTS_LPM_L1_EXITI_MASK;
4593                 ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK;
4594                 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
4595                 {
4596                     USB_HostEhciLock();
4597                     USB_HostEhciStartAsync(ehciInstance);
4598                     USB_HostEhciStartPeriodic(ehciInstance);
4599                     USB_HostEhciUnlock();
4600                 }
4601                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4602                                                   kUSB_HostEventL1Resumed); /* call host callback function */
4603                 hostPointer->suspendedDevice   = NULL;
4604                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4605                 ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4606             }
4607         }
4608 #endif
4609         else
4610         {
4611         }
4612     }
4613     else
4614     {
4615         ehciInstance->busSuspendStatus = kBus_EhciIdle;
4616         ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
4617     }
4618 }
4619 
4620 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
USB_HostEhciCompletedLPM(usb_host_ehci_instance_t * ehciInstance)4621 static void USB_HostEhciCompletedLPM(usb_host_ehci_instance_t *ehciInstance)
4622 {
4623     uint32_t portStatus;
4624     uint32_t portNcStatus;
4625 
4626     portStatus = ehciInstance->ehciIpBase->PORTSC1;
4627     portNcStatus = ehciInstance->registerNcBase->LPM_CSR2;
4628 
4629     if (0U != (portStatus & USBHS_PORTSC1_CCS_MASK))
4630     {
4631         if (((uint8_t)kBus_EhciL1StartSleep == ehciInstance->busSuspendStatus))
4632         {
4633             usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
4634             if (0x01U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT))  /* ACK */
4635             {
4636                 /* polling if host transitions to the L1 state and the PHY is put in L1 low power mode */
4637                 while (!(ehciInstance->ehciIpBase->USBSTS & USB_USBSTS_LPM_L1_ENTRYI_MASK))
4638                 {
4639                     __NOP();
4640                 }
4641                 ehciInstance->ehciIpBase->USBSTS |= USB_USBSTS_LPM_L1_ENTRYI_MASK;
4642                 /* TODO: maybe use 3us delay */
4643                 portStatus = ehciInstance->ehciIpBase->USBCMD;
4644                 portStatus &= ~USBHS_USBCMD_RS_MASK;
4645                 ehciInstance->ehciIpBase->USBCMD = portStatus;
4646                 ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK;
4647 #if (defined(FSL_FEATURE_USBPHY_28FDSOI) && (FSL_FEATURE_USBPHY_28FDSOI > 0U))
4648 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4649                 if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4650 #endif
4651                 {
4652                     ehciInstance->registerPhyBase->USB1_VBUS_DETECT_SET |=
4653                         USBPHY_USB1_VBUS_DETECT_VBUSVALID_TO_SESSVALID_MASK;
4654                 }
4655 #endif
4656 
4657 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4658 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4659                 if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4660 #endif
4661                 {
4662                     ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU;
4663 
4664                     while (0U != (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)))
4665                     {
4666                         __NOP();
4667                     }
4668                 }
4669 #endif
4670 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4671 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4672                 ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
4673                                                                USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
4674 #else
4675                 ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK |
4676                                                                USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK |
4677                                                                USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK;
4678 #endif
4679                 ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK;
4680 #endif
4681 
4682 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4683 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4684                 if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4685 #endif
4686                 {
4687                     ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK;
4688                 }
4689 #endif
4690                 /* call host callback function, function is initialized in USB_HostInit */
4691                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4692                                                   kUSB_HostEventL1Sleeped); /* call host callback function */
4693                 ehciInstance->busSuspendStatus = kBus_EhciL1Sleeped;
4694             }
4695             else if (0x03U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT))  /* STALL */
4696             {
4697                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4698                 /* call host callback function, function is initialized in USB_HostInit */
4699                 (void)hostPointer->deviceCallback(
4700                     hostPointer->suspendedDevice, NULL,
4701                     kUSB_HostEventL1SleepNotSupport); /* call host callback function */
4702             }
4703             else if (0x02U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT))  /* NYET */
4704             {
4705                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4706                 /* call host callback function, function is initialized in USB_HostInit */
4707                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4708                                                   kUSB_HostEventL1SleepNYET); /* call host callback function */
4709             }
4710             else if ((0x00U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT)) ||
4711               (0x04U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT)) ||
4712               (0x05U == ((portNcStatus & USBNC_LPM_CSR2_LPM_HST_STSRCVD_MASK) >> USBNC_LPM_CSR2_LPM_HST_STSRCVD_SHIFT)))  /* Invalid, Timeout, Error */
4713             {
4714                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4715                 /* call host callback function, function is initialized in USB_HostInit */
4716                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
4717                                                   kUSB_HostEventL1SleepError); /* call host callback function */
4718             }
4719             else
4720             {
4721                 ehciInstance->busSuspendStatus = kBus_EhciIdle;
4722             }
4723         }
4724         else
4725         {
4726             /* no action */
4727         }
4728     }
4729     else
4730     {
4731         /* no action */
4732     }
4733 }
4734 #endif
4735 #endif
4736 
USB_HostEhciCreate(uint8_t controllerId,usb_host_handle upperLayerHandle,usb_host_controller_handle * controllerHandle)4737 usb_status_t USB_HostEhciCreate(uint8_t controllerId,
4738                                 usb_host_handle upperLayerHandle,
4739                                 usb_host_controller_handle *controllerHandle)
4740 {
4741     uint32_t index = 0;
4742     osa_status_t osaStatus;
4743     usb_host_ehci_instance_t *ehciInstance;
4744 #if defined(USBHS_STACK_BASE_ADDRS)
4745     uint32_t usbhsBaseAddrs[] = USBHS_STACK_BASE_ADDRS;
4746 #else
4747     uint32_t usbhsBaseAddrs[] = USBHS_BASE_ADDRS;
4748 #endif
4749     usb_host_ehci_data_t *usbHostEhciData[USB_HOST_CONFIG_EHCI];
4750     uint32_t *framePointer;
4751     void *temp;
4752     uint8_t instanceIndex = 0U;
4753 
4754     if ((controllerId - (uint8_t)kUSB_ControllerEhci0) >= (sizeof(usbhsBaseAddrs) / sizeof(usbhsBaseAddrs[0])))
4755     {
4756         return kStatus_USB_ControllerNotFound;
4757     }
4758 
4759     *controllerHandle = NULL;
4760     ehciInstance      = (usb_host_ehci_instance_t *)OSA_MemoryAllocate(
4761         sizeof(usb_host_ehci_instance_t)); /* malloc host ehci instance */
4762     if (ehciInstance == NULL)
4763     {
4764         return kStatus_USB_AllocFail;
4765     }
4766     ehciInstance->controllerId   = controllerId;
4767     ehciInstance->hostHandle     = upperLayerHandle;
4768     ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
4769     ehciInstance->ehciIpBase     = (USBHS_Type *)
4770         usbhsBaseAddrs[controllerId - (uint8_t)kUSB_ControllerEhci0]; /* operate ehci ip through the base address */
4771 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4772     ehciInstance->busSuspendStatus = kBus_EhciIdle;
4773 
4774 #if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
4775 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
4776 #if defined(FSL_FEATURE_USBHS_SUPPORT_EUSBn)
4777     if (0U == (uint32_t)FSL_FEATURE_USBHS_SUPPORT_EUSBn(ehciInstance->ehciIpBase))
4778 #endif
4779     {
4780         ehciInstance->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
4781     }
4782 #endif
4783 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
4784     ehciInstance->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId);
4785 #endif
4786 
4787 #endif
4788 
4789 #endif
4790 
4791     if ((USB_HostEhciResetIP(ehciInstance) != kStatus_USB_Success) ||
4792         ((ehciInstance->controllerId < (uint8_t)kUSB_ControllerEhci0))) /* reset ehci ip */
4793     {
4794         OSA_MemoryFree(ehciInstance);
4795         return kStatus_USB_Error;
4796     }
4797 
4798 #if (USB_HOST_CONFIG_EHCI == 1U)
4799     if (0U == usbHostEhciFramListStatus[0])
4800     {
4801         usbHostEhciFramListStatus[0] = 1U;
4802         instanceIndex                = 0U;
4803         ehciInstance->ehciFrameList  = &s_UsbHostEhciFrameList1[0];
4804     }
4805 #elif (USB_HOST_CONFIG_EHCI == 2U)
4806     if (0U == usbHostEhciFramListStatus[0])
4807     {
4808         usbHostEhciFramListStatus[0] = 1U;
4809         instanceIndex                = 0U;
4810         ehciInstance->ehciFrameList  = &s_UsbHostEhciFrameList1[0];
4811     }
4812     else if (0U == usbHostEhciFramListStatus[1])
4813     {
4814         usbHostEhciFramListStatus[1] = 1U;
4815         instanceIndex                = 1U;
4816         ehciInstance->ehciFrameList  = &s_UsbHostEhciFrameList2[0];
4817     }
4818     else
4819     {
4820         /*no action*/
4821     }
4822 #endif
4823     if (ehciInstance->ehciFrameList == NULL)
4824     {
4825         OSA_MemoryFree(ehciInstance);
4826         return kStatus_USB_Error;
4827     }
4828 
4829 #if (USB_HOST_CONFIG_EHCI == 1U)
4830     usbHostEhciData[0] = &s_UsbHostEhciData1;
4831 #elif (USB_HOST_CONFIG_EHCI == 2U)
4832     usbHostEhciData[0] = &s_UsbHostEhciData1;
4833     usbHostEhciData[1] = &s_UsbHostEhciData2;
4834 #else
4835 #error "Please increase the instance count."
4836 #endif
4837 
4838     temp                       = (void *)usbHostEhciData[instanceIndex];
4839     ehciInstance->ehciUnitBase = (uint32_t *)(temp);
4840     /* initialize qh/qtd/itd/sitd/iso list */
4841     ehciInstance->ehciQhList  = (usb_host_ehci_qh_t *)((uint32_t)(ehciInstance->ehciUnitBase));
4842     ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)((uint32_t)ehciInstance->ehciQhList +
4843                                                         (sizeof(usb_host_ehci_qh_t) * USB_HOST_CONFIG_EHCI_MAX_QH));
4844     ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)((uint32_t)ehciInstance->ehciQtdHead +
4845                                                         (sizeof(usb_host_ehci_qtd_t) * USB_HOST_CONFIG_EHCI_MAX_QTD));
4846 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
4847     /* If one ITD's first 32 bytes and next 32 bytes are in different 4K region,
4848      * the ITD need move 32 bytes because the ITD cannot cross over 4K boundary.
4849      */
4850     index = ((((((uint32_t)(ehciInstance->ehciItdList)) + 4095U) & 0xFFFFF000U) -
4851               ((uint32_t)(ehciInstance->ehciItdList))) >>
4852              5U);
4853     if (((index / 3U) < USB_HOST_CONFIG_EHCI_MAX_ITD) && ((index % 3U) == 1U))
4854     {
4855         ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)(((uint32_t)(ehciInstance->ehciItdList)) + 32U);
4856     }
4857 #endif
4858     ehciInstance->ehciSitdIndexBase =
4859         (usb_host_ehci_sitd_t *)((uint32_t)ehciInstance->ehciItdList +
4860                                  (sizeof(usb_host_ehci_itd_t) * USB_HOST_CONFIG_EHCI_MAX_ITD));
4861     ehciInstance->ehciSitdList = ehciInstance->ehciSitdIndexBase;
4862     ehciInstance->ehciIsoList  = (usb_host_ehci_iso_t *)((uint32_t)ehciInstance->ehciSitdList +
4863                                                         (sizeof(usb_host_ehci_sitd_t) * USB_HOST_CONFIG_EHCI_MAX_SITD));
4864     ehciInstance->ehciPipeIndexBase =
4865         (usb_host_ehci_pipe_t *)((uint32_t)ehciInstance->ehciIsoList +
4866                                  (sizeof(usb_host_ehci_iso_t) * USB_HOST_EHCI_ISO_NUMBER));
4867     for (index = 1U; index < USB_HOST_CONFIG_EHCI_MAX_QH; ++index)
4868     {
4869         ehciInstance->ehciQhList[index - 1U].horizontalLinkPointer = (uint32_t)(&ehciInstance->ehciQhList[index]);
4870     }
4871     ehciInstance->ehciQhList[USB_HOST_CONFIG_EHCI_MAX_QH - 1U].horizontalLinkPointer = 0U;
4872     for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QTD; ++index)
4873     {
4874         ehciInstance->ehciQtdHead[index - 1U].nextQtdPointer = (uint32_t)(&ehciInstance->ehciQtdHead[index]);
4875     }
4876     ehciInstance->ehciQtdNumber                                                 = USB_HOST_CONFIG_EHCI_MAX_QTD;
4877     ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U].nextQtdPointer = 0U;
4878     ehciInstance->ehciQtdTail = &ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1U];
4879 
4880 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4881     for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_ITD; ++index)
4882     {
4883         ehciInstance->ehciItdList[index - 1U].nextItdPointer =
4884             (usb_host_ehci_itd_t *)(&ehciInstance->ehciItdList[index]);
4885     }
4886     ehciInstance->ehciItdNumber                                                 = USB_HOST_CONFIG_EHCI_MAX_ITD;
4887     ehciInstance->ehciItdList[USB_HOST_CONFIG_EHCI_MAX_ITD - 1U].nextItdPointer = NULL;
4888 #endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */
4889 
4890 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
4891     for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_SITD; ++index)
4892     {
4893         ehciInstance->ehciSitdList[index - 1U].nextLinkPointer = (uint32_t)(&ehciInstance->ehciSitdList[index]);
4894     }
4895     ehciInstance->ehciSitdNumber                                                   = USB_HOST_CONFIG_EHCI_MAX_SITD;
4896     ehciInstance->ehciSitdList[USB_HOST_CONFIG_EHCI_MAX_SITD - 1U].nextLinkPointer = 0U;
4897 #endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */
4898 
4899 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
4900     for (index = 1; index < USB_HOST_EHCI_ISO_NUMBER; ++index)
4901     {
4902         ehciInstance->ehciIsoList[index - 1U].next = &ehciInstance->ehciIsoList[index];
4903     }
4904     ehciInstance->ehciIsoList[USB_HOST_EHCI_ISO_NUMBER - 1U].next = NULL;
4905 #endif
4906 
4907     /* initialize pipes */
4908     ehciInstance->ehciPipeList = ehciInstance->ehciPipeIndexBase;
4909     for (index = 1; index < USB_HOST_CONFIG_MAX_PIPES; ++index)
4910     {
4911         temp                                                   = (void *)&ehciInstance->ehciPipeList[index];
4912         ehciInstance->ehciPipeList[index - 1U].pipeCommon.next = (usb_host_pipe_t *)temp;
4913     }
4914     /* initialize mutext */
4915     ehciInstance->ehciMutex = (osa_mutex_handle_t)(&ehciInstance->mutexBuffer[0]);
4916     osaStatus               = OSA_MutexCreate(ehciInstance->ehciMutex);
4917     if (osaStatus != KOSA_StatusSuccess)
4918     {
4919 #ifdef HOST_ECHO
4920         usb_echo("ehci mutex init fail\r\n");
4921 #endif
4922         OSA_MemoryFree(ehciInstance);
4923         return kStatus_USB_Error;
4924     }
4925     /* initialize task event */
4926     ehciInstance->taskEventHandle = (osa_event_handle_t)&ehciInstance->taskEventHandleBuffer[0];
4927     osaStatus                     = OSA_EventCreate(ehciInstance->taskEventHandle, 1);
4928     if (osaStatus != KOSA_StatusSuccess)
4929     {
4930 #ifdef HOST_ECHO
4931         usb_echo("ehci event init fail\r\n");
4932 #endif
4933         (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
4934         OSA_MemoryFree(ehciInstance);
4935         return kStatus_USB_Error;
4936     }
4937 
4938     /* initialize first qh */
4939     ehciInstance->shedFirstQh = ehciInstance->ehciQhList;
4940     ehciInstance->ehciQhList =
4941         (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK);
4942     ehciInstance->shedFirstQh->staticEndpointStates[0] |= (1UL << EHCI_HOST_QH_H_SHIFT); /* first qh */
4943     ehciInstance->shedFirstQh->horizontalLinkPointer   = EHCI_HOST_T_INVALID_VALUE;
4944     ehciInstance->shedFirstQh->currentQtdPointer       = EHCI_HOST_T_INVALID_VALUE;
4945     ehciInstance->shedFirstQh->nextQtdPointer          = EHCI_HOST_T_INVALID_VALUE;
4946     ehciInstance->shedFirstQh->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE;
4947 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET > 0U))
4948     ehciInstance->shedFirstQh->horizontalLinkPointer =
4949         (uint32_t)USB_HOST_MEMORY_CPU_2_DMA(((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH));
4950 #else
4951     ehciInstance->shedFirstQh->horizontalLinkPointer =
4952         (uint32_t)((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH);
4953 #endif
4954 
4955     /* initialize periodic list */
4956     temp         = (void *)ehciInstance->ehciFrameList;
4957     framePointer = (uint32_t *)temp;
4958     for (index = 0; index < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; ++index)
4959     {
4960         framePointer[index] = EHCI_HOST_T_INVALID_VALUE;
4961     }
4962 
4963     (void)USB_HostEhciStartIP(ehciInstance); /* start ehci ip */
4964 
4965     *controllerHandle = ehciInstance;
4966 
4967     return kStatus_USB_Success;
4968 }
4969 
USB_HostEhciDestory(usb_host_controller_handle controllerHandle)4970 usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle)
4971 {
4972     usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
4973 
4974     /* disable all interrupts */
4975     ehciInstance->ehciIpBase->USBINTR = 0;
4976     /* stop the controller */
4977     ehciInstance->ehciIpBase->USBCMD = 0;
4978 /* free memory */
4979 #if (USB_HOST_CONFIG_EHCI == 1U)
4980     if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
4981     {
4982         usbHostEhciFramListStatus[0] = 0;
4983     }
4984 #elif (USB_HOST_CONFIG_EHCI == 2U)
4985     if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList1[0])
4986     {
4987         usbHostEhciFramListStatus[0] = 0;
4988     }
4989     else if (ehciInstance->ehciFrameList == &s_UsbHostEhciFrameList2[0])
4990     {
4991         usbHostEhciFramListStatus[1] = 0;
4992     }
4993     else
4994     {
4995         /*no action*/
4996     }
4997 #endif
4998     (void)OSA_MutexDestroy(ehciInstance->ehciMutex);
4999     (void)OSA_EventDestroy(ehciInstance->taskEventHandle);
5000     OSA_MemoryFree(ehciInstance);
5001 
5002     return kStatus_USB_Success;
5003 }
5004 
USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)5005 usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
5006                                   usb_host_pipe_handle *pipeHandle,
5007                                   usb_host_pipe_init_t *pipeInit)
5008 {
5009     usb_host_ehci_pipe_t *ehciPipePointer = NULL;
5010     usb_status_t status;
5011     uint32_t speed                         = 0;
5012     usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
5013     void *temp;
5014     /* get one pipe */
5015     USB_HostEhciLock();
5016     if (ehciInstance->ehciPipeList != NULL)
5017     {
5018         ehciPipePointer            = ehciInstance->ehciPipeList;
5019         temp                       = (void *)ehciPipePointer->pipeCommon.next;
5020         ehciInstance->ehciPipeList = (usb_host_ehci_pipe_t *)temp;
5021     }
5022     USB_HostEhciUnlock();
5023     if (ehciPipePointer == NULL)
5024     {
5025 #ifdef HOST_ECHO
5026         usb_echo("ehci open pipe failed\r\n");
5027 #endif
5028         return kStatus_USB_Busy;
5029     }
5030 
5031     /* initialize pipe informations */
5032     USB_HostEhciZeroMem((void *)ehciPipePointer, sizeof(usb_host_ehci_pipe_t) / 4U);
5033     ehciPipePointer->pipeCommon.deviceHandle    = pipeInit->devInstance;
5034     ehciPipePointer->pipeCommon.endpointAddress = pipeInit->endpointAddress;
5035     ehciPipePointer->pipeCommon.direction       = pipeInit->direction;
5036     ehciPipePointer->pipeCommon.interval        = pipeInit->interval;
5037     ehciPipePointer->pipeCommon.maxPacketSize   = pipeInit->maxPacketSize;
5038     ehciPipePointer->pipeCommon.pipeType        = pipeInit->pipeType;
5039     ehciPipePointer->pipeCommon.numberPerUframe = pipeInit->numberPerUframe + 1U;
5040     if (ehciPipePointer->pipeCommon.numberPerUframe > 3U)
5041     {
5042         ehciPipePointer->pipeCommon.numberPerUframe = 3U;
5043     }
5044     ehciPipePointer->pipeCommon.nakCount   = pipeInit->nakCount;
5045     ehciPipePointer->pipeCommon.nextdata01 = 0U;
5046     ehciPipePointer->ehciQh                = NULL;
5047     (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
5048                                                  (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
5049     if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
5050         (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT))
5051     {
5052         if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS)
5053         {
5054             ehciPipePointer->pipeCommon.interval =
5055                 (uint16_t)(1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* iso interval is the power of 2 */
5056         }
5057         else
5058         {
5059             if (speed == USB_SPEED_HIGH)
5060             {
5061                 ehciPipePointer->pipeCommon.interval = (uint16_t)(
5062                     1UL << (ehciPipePointer->pipeCommon.interval - 1U)); /* HS interrupt interval is the power of 2 */
5063             }
5064             else
5065             {
5066                 ehciPipePointer->pipeCommon.interval = USB_HostEhciGet2PowerValue(
5067                     (uint8_t)ehciPipePointer->pipeCommon.interval); /* FS/LS interrupt interval should be the power of
5068                                                               2, it is used for ehci bandwidth */
5069             }
5070         }
5071     }
5072 
5073     /* save the micro-frame interval, it is convenient for the interval process */
5074     if (speed == USB_SPEED_HIGH)
5075     {
5076         ehciPipePointer->uframeInterval = ehciPipePointer->pipeCommon.interval;
5077     }
5078     else
5079     {
5080         ehciPipePointer->uframeInterval = 8U * ehciPipePointer->pipeCommon.interval;
5081     }
5082 
5083     /* open pipe */
5084     switch (ehciPipePointer->pipeCommon.pipeType)
5085     {
5086         case USB_ENDPOINT_CONTROL:
5087         case USB_ENDPOINT_BULK:
5088             status = USB_HostEhciOpenControlBulk(ehciInstance, ehciPipePointer);
5089             break;
5090 
5091 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
5092      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
5093         case USB_ENDPOINT_ISOCHRONOUS:
5094             status = USB_HostEhciOpenIso(ehciInstance, ehciPipePointer);
5095             break;
5096 #endif
5097 
5098         case USB_ENDPOINT_INTERRUPT:
5099             status = USB_HostEhciOpenInterrupt(ehciInstance, ehciPipePointer);
5100             break;
5101 
5102         default:
5103             status = kStatus_USB_Error;
5104             break;
5105     }
5106 
5107     if (status != kStatus_USB_Success)
5108     {
5109         /* release pipe */
5110         USB_HostEhciLock();
5111         temp                             = (void *)ehciInstance->ehciPipeList;
5112         ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
5113         ehciInstance->ehciPipeList       = ehciPipePointer;
5114         USB_HostEhciUnlock();
5115         return status;
5116     }
5117 
5118     /* add pipe to run pipe list */
5119     USB_HostEhciLock();
5120     temp                              = (void *)ehciInstance->ehciRunningPipeList;
5121     ehciPipePointer->pipeCommon.next  = (usb_host_pipe_t *)temp;
5122     ehciInstance->ehciRunningPipeList = ehciPipePointer;
5123     USB_HostEhciUnlock();
5124 
5125     *pipeHandle = ehciPipePointer;
5126     return status;
5127 }
5128 
USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle)5129 usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
5130 {
5131     usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
5132     usb_host_ehci_pipe_t *ehciPipePointer  = (usb_host_ehci_pipe_t *)pipeHandle;
5133     usb_host_pipe_t *prevPointer           = NULL;
5134     void *temp;
5135     void *tempCurrent;
5136 
5137     switch (ehciPipePointer->pipeCommon.pipeType)
5138     {
5139         case USB_ENDPOINT_BULK:
5140         case USB_ENDPOINT_CONTROL:
5141             (void)USB_HostEhciCloseControlBulk(ehciInstance, ehciPipePointer);
5142             break;
5143 
5144         case USB_ENDPOINT_INTERRUPT:
5145             (void)USB_HostEhciCloseInterrupt(ehciInstance, ehciPipePointer);
5146             break;
5147 
5148 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
5149      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
5150         case USB_ENDPOINT_ISOCHRONOUS:
5151             (void)USB_HostEhciCloseIso(ehciInstance, ehciPipePointer);
5152             break;
5153 #endif
5154 
5155         default:
5156             /*no action*/
5157             break;
5158     }
5159 
5160     /* delete pipe from run pipe list */
5161     USB_HostEhciLock();
5162     temp        = (void *)ehciInstance->ehciRunningPipeList;
5163     prevPointer = (usb_host_pipe_t *)temp;
5164     tempCurrent = (void *)ehciPipePointer;
5165     if (prevPointer == (usb_host_pipe_t *)tempCurrent)
5166     {
5167         temp                              = (void *)prevPointer->next;
5168         ehciInstance->ehciRunningPipeList = (usb_host_ehci_pipe_t *)(temp);
5169     }
5170     else
5171     {
5172         while (prevPointer != NULL)
5173         {
5174             temp = (void *)ehciPipePointer;
5175             if (prevPointer->next == (usb_host_pipe_t *)temp)
5176             {
5177                 prevPointer->next = ehciPipePointer->pipeCommon.next;
5178                 break;
5179             }
5180             else
5181             {
5182                 prevPointer = prevPointer->next;
5183             }
5184         }
5185     }
5186     USB_HostEhciUnlock();
5187 
5188     /* release pipe */
5189     USB_HostEhciLock();
5190     temp                             = (void *)ehciInstance->ehciPipeList;
5191     ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)temp;
5192     ehciInstance->ehciPipeList       = ehciPipePointer;
5193     USB_HostEhciUnlock();
5194 
5195     return kStatus_USB_Success;
5196 }
5197 
USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)5198 usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
5199                                    usb_host_pipe_handle pipeHandle,
5200                                    usb_host_transfer_t *transfer)
5201 {
5202     usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
5203     usb_host_ehci_pipe_t *ehciPipePointer  = (usb_host_ehci_pipe_t *)pipeHandle;
5204     usb_status_t status                    = kStatus_USB_Success;
5205 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
5206      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
5207     uint32_t speed = 0U;
5208 #endif
5209 
5210 #if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
5211     if (transfer->transferLength > 0)
5212     {
5213         DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);
5214     }
5215     if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL)
5216     {
5217         DCACHE_CleanByRange((uint32_t)&transfer->setupPacket->bmRequestType, sizeof(usb_setup_struct_t));
5218     }
5219 #endif
5220 
5221     switch (ehciPipePointer->pipeCommon.pipeType)
5222     {
5223         case USB_ENDPOINT_BULK:
5224         case USB_ENDPOINT_CONTROL:
5225         case USB_ENDPOINT_INTERRUPT:
5226             status = USB_HostEhciQhQtdListInit(ehciInstance, ehciPipePointer,
5227                                                transfer); /* initialize qtd for control/bulk transfer */
5228             break;
5229 
5230 #if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \
5231      ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)))
5232         case USB_ENDPOINT_ISOCHRONOUS:
5233             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
5234                                                          (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
5235             if (speed == USB_SPEED_HIGH)
5236             {
5237 #if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD))
5238                 status = USB_HostEhciItdArrayInit(ehciInstance, ehciPipePointer,
5239                                                   transfer); /* initialize itd for iso transfer */
5240 #endif
5241             }
5242             else
5243             {
5244 #if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))
5245                 status = USB_HostEhciSitdArrayInit(ehciInstance, ehciPipePointer,
5246                                                    transfer); /* initialize sitd for iso transfer */
5247 #endif
5248             }
5249             break;
5250 #endif
5251 
5252         default:
5253             /*no action*/
5254             break;
5255     }
5256     return status;
5257 }
5258 
USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)5259 usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
5260                                   usb_host_pipe_handle pipeHandle,
5261                                   usb_host_transfer_t *transfer)
5262 {
5263     return USB_HostEhciWritePipe(controllerHandle, pipeHandle, transfer); /* same as write */
5264 }
5265 
USB_HostEhciIoctl(usb_host_controller_handle controllerHandle,uint32_t ioctlEvent,void * ioctlParam)5266 usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
5267 {
5268     usb_status_t status                    = kStatus_USB_Success;
5269     usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle;
5270     usb_host_cancel_param_t *param;
5271     usb_host_ehci_pipe_t *ehciPipePointer;
5272     volatile usb_host_ehci_qh_t *vltQhPointer;
5273 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5274 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
5275     uint8_t *lpmParam;
5276 #endif
5277 #endif
5278     uint32_t deviceAddress                    = 0;
5279     usb_host_controller_control_t controlCode = (usb_host_controller_control_t)ioctlEvent;
5280 
5281     if (controllerHandle == NULL)
5282     {
5283         return kStatus_USB_InvalidHandle;
5284     }
5285 
5286     switch (controlCode)
5287     {
5288         case kUSB_HostCancelTransfer: /* cancel pipe or one transfer */
5289             param  = (usb_host_cancel_param_t *)ioctlParam;
5290             status = USB_HostEhciCancelPipe(ehciInstance, (usb_host_ehci_pipe_t *)param->pipeHandle, param->transfer);
5291             break;
5292 
5293 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5294 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
5295         case kUSB_HostL1Config:
5296             lpmParam                           = (uint8_t *)ioctlParam;
5297             ehciInstance->hirdValue            = (*lpmParam) & 0xFU;
5298             ehciInstance->L1remoteWakeupEnable = (((*lpmParam) & 0x80U) >> 7);
5299             break;
5300 #endif
5301 #endif
5302 
5303         case kUSB_HostBusControl: /* bus control */
5304             status = USB_HostEhciControlBus(ehciInstance, *((uint8_t *)ioctlParam));
5305             break;
5306 
5307         case kUSB_HostGetFrameNumber: /* get frame number */
5308             *((uint32_t *)ioctlParam) = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3);
5309             break;
5310 
5311         case kUSB_HostUpdateControlEndpointAddress:
5312             ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
5313             vltQhPointer    = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
5314             /* update address */
5315             (void)USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle,
5316                                                          (uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
5317             vltQhPointer->staticEndpointStates[0] |= deviceAddress;
5318             USB_HostEhciDelay(ehciInstance->ehciIpBase, 2U);
5319             break;
5320 
5321         case kUSB_HostUpdateControlPacketSize:
5322             ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam;
5323             vltQhPointer    = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh;
5324             USB_HostEhciLock();
5325             if (0U != (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK))
5326             {
5327                 USB_HostEhciStopAsync(ehciInstance);
5328                 /* update max packet size */
5329                 vltQhPointer->staticEndpointStates[0] =
5330                     (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
5331                      ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
5332                 USB_HostEhciStartAsync(ehciInstance);
5333             }
5334             else
5335             {
5336                 /* update max packet size */
5337                 vltQhPointer->staticEndpointStates[0] =
5338                     (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) |
5339                      ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT));
5340             }
5341             USB_HostEhciUnlock();
5342             break;
5343 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
5344         case kUSB_HostTestModeInit: /* test mode control */
5345             USB_HostEhciTestModeInit((usb_host_device_instance_t *)ioctlParam);
5346             break;
5347 #endif
5348         default:
5349             status = kStatus_USB_NotSupported;
5350             break;
5351     }
5352     return status;
5353 }
5354 
USB_HostEhciTaskFunction(void * hostHandle)5355 void USB_HostEhciTaskFunction(void *hostHandle)
5356 {
5357     usb_host_ehci_instance_t *ehciInstance;
5358     uint32_t bitSet;
5359     usb_device_handle deviceHandle;
5360 
5361     if (hostHandle == NULL)
5362     {
5363         return;
5364     }
5365     ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
5366 
5367     if (OSA_EventWait(ehciInstance->taskEventHandle, 0xFF, 0, USB_OSA_WAIT_TIMEOUT, &bitSet) ==
5368         KOSA_StatusSuccess) /* wait all event */
5369     {
5370         if (0U != (bitSet & EHCI_TASK_EVENT_PORT_CHANGE)) /* port change */
5371         {
5372             USB_HostEhciPortChange(ehciInstance);
5373         }
5374 
5375         if (0U != (bitSet & EHCI_TASK_EVENT_TIMER0)) /* timer0 */
5376         {
5377             USB_HostEhciTimer0(ehciInstance);
5378         }
5379 
5380 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5381         if (0U != (bitSet & EHCI_TASK_EVENT_TIMER1)) /* timer1 */
5382         {
5383             USB_HostEhciTimer1(ehciInstance);
5384         }
5385 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
5386         if (0U != (bitSet & EHCI_TASK_EVENT_HOST_COMPLETED_LPM)) /* L1 completed */
5387         {
5388             USB_HostEhciCompletedLPM(ehciInstance);
5389         }
5390 #endif
5391 #endif
5392 
5393         if ((ehciInstance->deviceAttached == (uint8_t)kEHCIDeviceAttached))
5394         {
5395             if (0U != (bitSet & EHCI_TASK_EVENT_TRANSACTION_DONE)) /* transaction done */
5396             {
5397                 USB_HostEhciTransactionDone(ehciInstance);
5398             }
5399 
5400             if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_DETACH)) /* device detach */
5401             {
5402                 ehciInstance->ehciIpBase->USBINTR &=
5403                     (~USBHS_USBINTR_PCE_MASK); /* disable attach, enable when the detach process is done */
5404                 ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceDetached;
5405                 (void)USB_HostDetachDevice(ehciInstance->hostHandle, 0, 0);
5406             }
5407         }
5408         else if (ehciInstance->deviceAttached != (uint8_t)kEHCIDeviceAttached)
5409         {
5410             if (0U != (bitSet & EHCI_TASK_EVENT_DEVICE_ATTACH)) /* device is attached */
5411             {
5412                 USB_HostEhciLock();
5413                 USB_HostEhciStartAsync(ehciInstance);
5414                 USB_HostEhciStartPeriodic(ehciInstance);
5415                 USB_HostEhciUnlock();
5416 
5417                 if (USB_HostAttachDevice(ehciInstance->hostHandle, ehciInstance->firstDeviceSpeed, 0, 0, 1,
5418                                          &deviceHandle) == kStatus_USB_Success)
5419                 {
5420                     ehciInstance->deviceAttached = (uint8_t)kEHCIDeviceAttached;
5421                 }
5422             }
5423         }
5424         else
5425         {
5426             /*no action*/
5427         }
5428     }
5429 }
5430 
USB_HostEhciIsrFunction(void * hostHandle)5431 void USB_HostEhciIsrFunction(void *hostHandle)
5432 {
5433     usb_host_ehci_instance_t *ehciInstance;
5434     static uint32_t interruptStatus = 0;
5435 
5436     if (hostHandle == NULL)
5437     {
5438         return;
5439     }
5440 
5441     ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
5442 
5443 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5444 
5445 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
5446     if (0U != (ehciInstance->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK))
5447     {
5448         usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5449         ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK;
5450         (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5451                                           kUSB_HostEventDetectResume); /* call host callback function */
5452 #if (defined(USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
5453         while (0U == (ehciInstance->registerNcBase->USB_OTGn_PHY_CTRL_0 & USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK))
5454         {
5455         }
5456 #endif
5457         if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5458         {
5459             USB_HostEhciStartAsync(ehciInstance);
5460             USB_HostEhciStartPeriodic(ehciInstance);
5461         }
5462         ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5463         if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5464         {
5465             /* ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
5466             ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5467         }
5468 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
5469         else if ((kBus_EhciL1Sleeped == ehciInstance->busSuspendStatus))
5470         {
5471             ehciInstance->busSuspendStatus = kBus_EhciL1StartResume;
5472         }
5473 #endif
5474         else
5475         {
5476             /*no action*/
5477         }
5478     }
5479     else
5480     {
5481         /*no action*/
5482     }
5483 #else
5484 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
5485 #else
5486     if (0U != (ehciInstance->ehciIpBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK))
5487     {
5488         usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5489 
5490         (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5491                                           kUSB_HostEventDetectResume); /* call host callback function */
5492 
5493         while (0U == (USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
5494         {
5495         }
5496         ehciInstance->ehciIpBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK;
5497         ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK;
5498         if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5499         {
5500             USB_HostEhciStartAsync(ehciInstance);
5501             USB_HostEhciStartPeriodic(ehciInstance);
5502         }
5503         ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5504         if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5505         {
5506             ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5507             /*ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */
5508         }
5509         else
5510         {
5511             /*no action*/
5512         }
5513     }
5514     else
5515     {
5516         /*no action*/
5517     }
5518 #endif /* FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT */
5519 #endif /* FSL_FEATURE_SOC_USBNC_COUNT */
5520 #endif /* USB_HOST_CONFIG_LOW_POWER_MODE */
5521 
5522     interruptStatus = ehciInstance->ehciIpBase->USBSTS;
5523     interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
5524     while (0U != interruptStatus) /* there are usb interrupts */
5525     {
5526         ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */
5527 
5528         if (0U != (interruptStatus & USBHS_USBSTS_SRI_MASK)) /* SOF interrupt */
5529         {
5530         }
5531 
5532         if (0U != (interruptStatus & USBHS_USBSTS_SEI_MASK)) /* system error interrupt */
5533         {
5534         }
5535 
5536         if ((0U != (interruptStatus & USBHS_USBSTS_UI_MASK)) ||
5537             (0U != (interruptStatus & USBHS_USBSTS_UEI_MASK))) /* USB interrupt or USB error interrupt */
5538         {
5539             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE);
5540         }
5541 
5542         if (0U != (interruptStatus & USBHS_USBSTS_PCI_MASK)) /* port change detect interrupt */
5543         {
5544 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5545             usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5546             if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK))
5547             {
5548                 if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus)
5549                 {
5550                     if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5551                     {
5552                         USB_HostEhciStartAsync(ehciInstance);
5553                         USB_HostEhciStartPeriodic(ehciInstance);
5554                     }
5555                     (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5556                                                       kUSB_HostEventNotSuspended); /* call host callback function */
5557                     hostPointer->suspendedDevice   = NULL;
5558                     ehciInstance->busSuspendStatus = kBus_EhciIdle;
5559                     ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK);
5560                 }
5561                 else
5562                 {
5563                     /*no action */
5564                 }
5565             }
5566 #if (defined(FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT) && (FSL_FEATURE_USB_ATLANTIC_EHCI_SUPPORT > 0U))
5567             if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus))
5568             {
5569                 usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle;
5570 
5571                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
5572                                                   kUSB_HostEventDetectResume); /* call host callback function */
5573 
5574                 uint32_t delay = 100000;
5575                 while (delay-- && !(USBOTG->PLL_CONTROL_0 & USBC_PLL_CONTROL_0_PLL_READY_MASK))
5576                 {
5577                 }
5578                 if (0U != (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK))
5579                 {
5580                     USB_HostEhciStartAsync(ehciInstance);
5581                     USB_HostEhciStartPeriodic(ehciInstance);
5582                 }
5583                 ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK);
5584                 ehciInstance->busSuspendStatus = kBus_EhciStartResume;
5585             }
5586 #endif
5587 #endif
5588             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE);
5589         }
5590 
5591         if (0U != (interruptStatus & USBHS_USBSTS_TI0_MASK)) /* timer 0 interrupt */
5592         {
5593             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0);
5594         }
5595 
5596 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
5597         if (0U != (interruptStatus & USBHS_USBSTS_TI1_MASK)) /* timer 1 interrupt */
5598         {
5599             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER1);
5600         }
5601 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
5602         if (0U != (interruptStatus & USB_USBSTS_LPM_HST_COMPI_MASK)) /* host completed L1 LPM transaction interrupt */
5603         {
5604             (void)OSA_EventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_HOST_COMPLETED_LPM);
5605         }
5606 #endif
5607 #endif
5608 
5609         interruptStatus = ehciInstance->ehciIpBase->USBSTS;
5610         interruptStatus &= ehciInstance->ehciIpBase->USBINTR;
5611     }
5612 }
5613 
5614 #endif /* USB_HOST_CONFIG_EHCI */
5615