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