1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016,2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "usb_host_config.h"
10 #if (defined(USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U))
11 #include "usb_host.h"
12 #include "usb_host_hci.h"
13 #include "fsl_device_registers.h"
14 #include "usb_host_ohci.h"
15 #include "usb_host_devices.h"
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /* reset recovery time (ms) */
22 #define USB_HOST_OHCI_PORT_RESET_RECOVERY_DELAY (11U)
23 
24 /*******************************************************************************
25  * Prototypes
26  ******************************************************************************/
27 static usb_status_t USB_HostOhciLinkGtdControlTr(usb_host_ohci_state_struct_t *usbHostState,
28                                                  usb_host_ohci_pipe_struct_t *pipe,
29                                                  usb_host_transfer_t *tr);
30 #if ((defined USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD))
31 static usb_status_t USB_HostOhciLinkItdTr(usb_host_ohci_state_struct_t *usbHostState,
32                                           usb_host_ohci_pipe_struct_t *pipe,
33                                           usb_host_transfer_t *tr);
34 static usb_status_t USB_HostOhciFreeItd(usb_host_ohci_state_struct_t *usbHostState,
35                                         usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd);
36 #endif
37 static usb_status_t USB_HostOhciLinkGtdTr(usb_host_ohci_state_struct_t *usbHostState,
38                                           usb_host_ohci_pipe_struct_t *pipe,
39                                           usb_host_transfer_t *tr);
40 static usb_status_t USB_HostOhciFreeGtd(usb_host_ohci_state_struct_t *usbHostState,
41                                         usb_host_ohci_general_transfer_descritpor_struct_t *gtd);
42 static void USB_HostOhciTdDoneHandle(usb_host_ohci_state_struct_t *usbHostState,
43                                      usb_host_ohci_pipe_struct_t *pipe,
44                                      usb_host_transfer_t *currentTr,
45                                      usb_host_ohci_general_transfer_descritpor_struct_t *gtd,
46                                      usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd);
47 
48 /*******************************************************************************
49  * Variables
50  ******************************************************************************/
51 /* The hcca for interrupt tansaction, 256-byte alignment*/
52 USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static usb_host_ohci_hcca_struct_t
53     s_UsbHostOhciHcca[USB_HOST_CONFIG_OHCI];
54 USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(32) static usb_host_ohci_td_struct_t
55     s_UsbHostOhciTd[USB_HOST_CONFIG_OHCI];
56 static usb_host_ohci_state_struct_t s_UsbHostOhciState[USB_HOST_CONFIG_OHCI];
57 
58 /*******************************************************************************
59  * Code
60  ******************************************************************************/
USB_HostOhciDisableIsr(usb_host_ohci_state_struct_t * usbHostState)61 static void USB_HostOhciDisableIsr(usb_host_ohci_state_struct_t *usbHostState)
62 {
63     OSA_SR_ALLOC();
64 
65     /* Enter critical */
66     OSA_ENTER_CRITICAL();
67     if (0U == usbHostState->isrLevel)
68     {
69         NVIC_DisableIRQ((IRQn_Type)usbHostState->isrNumber);
70     }
71     usbHostState->isrLevel++;
72     OSA_EXIT_CRITICAL();
73 }
74 
USB_HostOhciEnableIsr(usb_host_ohci_state_struct_t * usbHostState)75 static void USB_HostOhciEnableIsr(usb_host_ohci_state_struct_t *usbHostState)
76 {
77     OSA_SR_ALLOC();
78 
79     /* Enter critical */
80     OSA_ENTER_CRITICAL();
81     usbHostState->isrLevel--;
82     if (0U == usbHostState->isrLevel)
83     {
84         NVIC_EnableIRQ((IRQn_Type)usbHostState->isrNumber);
85     }
86     OSA_EXIT_CRITICAL();
87 }
88 
USB_HostOhciDelay(usb_host_ohci_state_struct_t * usbHostState,uint32_t ms)89 static void USB_HostOhciDelay(usb_host_ohci_state_struct_t *usbHostState, uint32_t ms)
90 {
91     /* note: the max delay time cannot exceed half of max value (0x4000) */
92     uint32_t sofStart;
93     uint32_t SofEnd;
94     uint32_t distance;
95 
96     sofStart =
97         ((uint32_t)s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber & USB_HOST_OHCI_FMNUMBER_FN_MASK);
98 
99     do
100     {
101         SofEnd   = (uint32_t)((uint32_t)s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber &
102                             USB_HOST_OHCI_FMNUMBER_FN_MASK);
103         distance = (uint32_t)(SofEnd - sofStart + USB_HOST_OHCI_FMNUMBER_FN_MASK + 1U) & USB_HOST_OHCI_FMNUMBER_FN_MASK;
104     } while ((distance) < (ms)); /* compute the distance between sofStart and SofEnd */
105 }
106 
USB_HostOhciControlBus(usb_host_ohci_state_struct_t * usbHostState,uint8_t busControl)107 static usb_status_t USB_HostOhciControlBus(usb_host_ohci_state_struct_t *usbHostState, uint8_t busControl)
108 {
109 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
110     uint32_t portStatus;
111 #endif
112     usb_status_t status                = kStatus_USB_Success;
113     usb_host_bus_control_t controlCode = (usb_host_bus_control_t)busControl;
114     switch (controlCode)
115     {
116         case kUSB_HostBusReset:
117             break;
118 
119         case kUSB_HostBusRestart:
120             break;
121 
122         case kUSB_HostBusEnableAttach:
123             usbHostState->controlIsBusy = 0U;
124             break;
125 
126         case kUSB_HostBusDisableAttach:
127             break;
128 
129 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
130         case kUSB_HostBusSuspend:
131             if (0U != (usbHostState->usbRegBase->HcRhPortStatus[0] & USB_HOST_OHCI_RHPORTSTATUS_CCS_MASK))
132             {
133                 usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
134                 portStatus                       = usbHostState->usbRegBase->HcRhPortStatus[0];
135 
136                 portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
137                 portStatus |= USB_HOST_OHCI_RHPORTSTATUS_PSS_MASK;
138                 usbHostState->usbRegBase->HcRhPortStatus[0] = portStatus;
139 
140                 portStatus = usbHostState->usbRegBase->HcControl;
141                 portStatus &= ~USB_HOST_OHCI_CONTROL_HCFS_MASK;
142                 portStatus |= USB_HOST_OHCI_CONTROL_HCFS(USB_HOST_OHCI_CONTROL_HCFS_SUSPEND) |
143                               USB_HOST_OHCI_CONTROL_RWC_MASK | USB_HOST_OHCI_CONTROL_RWE_MASK;
144                 usbHostState->usbRegBase->HcControl = portStatus;
145 
146                 usbHostState->matchTick        = hostPointer->hwTick;
147                 usbHostState->busSuspendStatus = kBus_OhciStartSuspend;
148 
149                 while ((hostPointer->hwTick - usbHostState->matchTick) <= 3U)
150                 {
151                 }
152 
153                 usbHostState->usbRegBase->HcRhStatus |= USB_HOST_OHCI_RHSTATUS_DRWE_MASK;
154                 /* call host callback function, function is initialized in USB_HostInit */
155                 (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
156                                                   kUSB_HostEventSuspended); /* call host callback function */
157                 usbHostState->busSuspendStatus = kBus_OhciSuspended;
158             }
159             else
160             {
161                 status = kStatus_USB_Error;
162             }
163             break;
164 
165         case kUSB_HostBusResume:
166             if (0u != (usbHostState->usbRegBase->HcRhPortStatus[0] & USB_HOST_OHCI_RHPORTSTATUS_CCS_MASK))
167             {
168                 portStatus = usbHostState->usbRegBase->HcRhPortStatus[0];
169                 portStatus &= ~(USB_HOST_OHCI_RHPORTSTATUS_WIC);
170                 portStatus |= USB_HOST_OHCI_RHPORTSTATUS_POCI_MASK;
171                 usbHostState->usbRegBase->HcRhPortStatus[0] = portStatus;
172                 usbHostState->busSuspendStatus              = kBus_OhciStartResume;
173             }
174             else
175             {
176                 usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
177 
178                 portStatus = usbHostState->usbRegBase->HcControl;
179                 portStatus &= ~(USB_HOST_OHCI_CONTROL_HCFS_MASK | USB_HOST_OHCI_CONTROL_RWE_MASK |
180                                 USB_HOST_OHCI_CONTROL_RWC_MASK);
181                 portStatus |= USB_HOST_OHCI_CONTROL_HCFS(USB_HOST_OHCI_CONTROL_HCFS_OPERATIONAL);
182                 usbHostState->usbRegBase->HcControl = portStatus;
183                 portStatus                          = usbHostState->usbRegBase->HcRhPortStatus[0];
184                 portStatus &= ~(USB_HOST_OHCI_RHPORTSTATUS_WIC);
185                 portStatus |= USB_HOST_OHCI_RHPORTSTATUS_PES_MASK;
186                 usbHostState->usbRegBase->HcRhPortStatus[0] = portStatus;
187                 hostPointer->suspendedDevice                = NULL;
188                 usbHostState->busSuspendStatus              = kBus_OhciIdle;
189                 status                                      = kStatus_USB_Error;
190             }
191             break;
192 #endif
193         default:
194             status = kStatus_USB_Error;
195             break;
196     }
197     return status;
198 }
199 
USB_HostOhciBusTime(uint8_t speed,uint8_t pipeType,uint8_t direction,uint32_t dataLength)200 static uint32_t USB_HostOhciBusTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength)
201 {
202     uint32_t result = (3167U + ((1000U * dataLength) * 7U * 8U / 6U)) / 1000U;
203 
204     if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */
205     {
206         if (speed == USB_SPEED_FULL)
207         {
208             if (direction == USB_IN)
209             {
210                 result = 7268000U + 83540U * result + USB_HOST_OHCI_TIME_DELAY;
211             }
212             else
213             {
214                 result = 6265000U + 83540U * result + USB_HOST_OHCI_TIME_DELAY;
215             }
216         }
217         else
218         {
219             /*no action*/
220         }
221     }
222     else /* interrupt */
223     {
224         if (speed == USB_SPEED_FULL)
225         {
226             result = 9107000U + 83540U * result + USB_HOST_OHCI_TIME_DELAY;
227         }
228         else if (speed == USB_SPEED_LOW)
229         {
230             if (direction == USB_IN)
231             {
232                 result = 64060000U + 2000U * USB_HOST_OHCI_HUB_LS_SETUP_TIME_DELAY + 676670U * result +
233                          USB_HOST_OHCI_TIME_DELAY;
234             }
235             else
236             {
237                 result = 64107000U + 2000U * USB_HOST_OHCI_HUB_LS_SETUP_TIME_DELAY + 667000U * result +
238                          USB_HOST_OHCI_TIME_DELAY;
239             }
240         }
241         else
242         {
243             /*no action*/
244         }
245     }
246 
247     result /= 1000000U;
248     if (result == 0U)
249     {
250         result = 1U;
251     }
252 
253     return result;
254 }
255 
USB_HostOhciGetPipe(usb_host_ohci_pipe_struct_t ** pipeQueue,usb_host_ohci_pipe_struct_t ** pipe)256 static usb_status_t USB_HostOhciGetPipe(usb_host_ohci_pipe_struct_t **pipeQueue, usb_host_ohci_pipe_struct_t **pipe)
257 {
258     usb_status_t error = kStatus_USB_Busy;
259     void *temp;
260     OSA_SR_ALLOC();
261 
262     /* get a pipe instance */
263     /* Enter critical */
264     OSA_ENTER_CRITICAL();
265     if (NULL != (*pipeQueue))
266     {
267         *pipe      = *pipeQueue;
268         temp       = (void *)((*pipe)->pipeCommon.next);
269         *pipeQueue = (usb_host_ohci_pipe_struct_t *)temp;
270         error      = kStatus_USB_Success;
271     }
272     /* Exit critical */
273     OSA_EXIT_CRITICAL();
274     return error;
275 }
276 
USB_HostOhciRemovePipe(usb_host_ohci_pipe_struct_t ** pipeQueue,usb_host_ohci_pipe_struct_t * pipe)277 static usb_status_t USB_HostOhciRemovePipe(usb_host_ohci_pipe_struct_t **pipeQueue, usb_host_ohci_pipe_struct_t *pipe)
278 {
279     usb_host_ohci_pipe_struct_t *p = *pipeQueue;
280     usb_host_ohci_pipe_struct_t *pre;
281     void *temp;
282     OSA_SR_ALLOC();
283 
284     /* get a pipe instance */
285     /* Enter critical */
286     OSA_ENTER_CRITICAL();
287     pre = NULL;
288     while (NULL != p)
289     {
290         if (p != pipe)
291         {
292             pre  = p;
293             temp = (void *)p->pipeCommon.next;
294             p    = (usb_host_ohci_pipe_struct_t *)temp;
295         }
296         else
297         {
298             if (NULL == pre)
299             {
300                 temp       = (void *)p->pipeCommon.next;
301                 *pipeQueue = (usb_host_ohci_pipe_struct_t *)temp;
302             }
303             else
304             {
305                 pre->pipeCommon.next = p->pipeCommon.next;
306             }
307             break;
308         }
309     }
310     OSA_EXIT_CRITICAL();
311     return kStatus_USB_Success;
312 }
313 
USB_HostOhciInsertPipe(usb_host_ohci_pipe_struct_t ** pipeQueue,usb_host_ohci_pipe_struct_t * pipe)314 static usb_status_t USB_HostOhciInsertPipe(usb_host_ohci_pipe_struct_t **pipeQueue, usb_host_ohci_pipe_struct_t *pipe)
315 {
316     usb_host_ohci_pipe_struct_t *p = *pipeQueue;
317     void *temp;
318     OSA_SR_ALLOC();
319 
320     /* get a pipe instance */
321     /* Enter critical */
322     OSA_ENTER_CRITICAL();
323     while (NULL != p)
324     {
325         if (p != pipe)
326         {
327             temp = (void *)p->pipeCommon.next;
328             p    = (usb_host_ohci_pipe_struct_t *)temp;
329         }
330         else
331         {
332             break;
333         }
334     }
335     if (NULL == p)
336     {
337         temp                  = (*pipeQueue);
338         pipe->pipeCommon.next = (usb_host_pipe_t *)temp;
339         *pipeQueue            = pipe;
340     }
341     OSA_EXIT_CRITICAL();
342     return kStatus_USB_Success;
343 }
344 
USB_HostOhciGetGtd(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_general_transfer_descritpor_struct_t ** gtd,uint32_t count)345 static usb_status_t USB_HostOhciGetGtd(usb_host_ohci_state_struct_t *usbHostState,
346                                        usb_host_ohci_general_transfer_descritpor_struct_t **gtd,
347                                        uint32_t count)
348 {
349     usb_host_ohci_general_transfer_descritpor_struct_t *p = NULL;
350     uint32_t *tmp;
351     void *temp;
352     OSA_SR_ALLOC();
353 
354     /* get a td */
355     /* Enter critical */
356     OSA_ENTER_CRITICAL();
357     if (count > usbHostState->gtdCount)
358     {
359         OSA_EXIT_CRITICAL();
360         return kStatus_USB_Busy;
361     }
362     *gtd = NULL;
363     while ((0U != count) && (NULL != usbHostState->gtdList))
364     {
365         if (NULL == (*gtd))
366         {
367             *gtd = usbHostState->gtdList;
368         }
369         else
370         {
371             p->NextTD = (uint32_t)usbHostState->gtdList;
372         }
373         p = usbHostState->gtdList;
374 
375         usbHostState->gtdList = (usb_host_ohci_general_transfer_descritpor_struct_t *)usbHostState->gtdList->nextGtd;
376         temp                  = (void *)(p);
377         tmp                   = (uint32_t *)(temp);
378         usbHostState->gtdCount--;
379         for (uint8_t i = 0; i < (sizeof(usb_host_ohci_general_transfer_descritpor_struct_t) / sizeof(uint32_t)); i++)
380         {
381             tmp[i] = 0U;
382         }
383         count--;
384     }
385     if (NULL == p)
386     {
387         OSA_EXIT_CRITICAL();
388         return kStatus_USB_Busy;
389     }
390     p->NextTD = 0U;
391     /* Exit critical */
392     OSA_EXIT_CRITICAL();
393     return kStatus_USB_Success;
394 }
395 
USB_HostOhciFreeGtd(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_general_transfer_descritpor_struct_t * gtd)396 static usb_status_t USB_HostOhciFreeGtd(usb_host_ohci_state_struct_t *usbHostState,
397                                         usb_host_ohci_general_transfer_descritpor_struct_t *gtd)
398 {
399     usb_host_ohci_general_transfer_descritpor_struct_t *p;
400     OSA_SR_ALLOC();
401 
402     if (NULL == gtd)
403     {
404         return kStatus_USB_Error;
405     }
406 
407     /* free a td */
408     /* Enter critical */
409     OSA_ENTER_CRITICAL();
410     p = usbHostState->gtdList;
411     while (NULL != p)
412     {
413         if (p == gtd)
414         {
415             OSA_EXIT_CRITICAL();
416             return kStatus_USB_Success;
417         }
418         p = (usb_host_ohci_general_transfer_descritpor_struct_t *)p->nextGtd;
419     }
420     gtd->nextGtd          = usbHostState->gtdList;
421     usbHostState->gtdList = gtd;
422     usbHostState->gtdCount++;
423     /* Exit critical */
424     OSA_EXIT_CRITICAL();
425     return kStatus_USB_Success;
426 }
427 
428 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
USB_HostOhciGetItd(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_isochronous_transfer_descritpor_struct_t ** itd,uint32_t count)429 static usb_status_t USB_HostOhciGetItd(usb_host_ohci_state_struct_t *usbHostState,
430                                        usb_host_ohci_isochronous_transfer_descritpor_struct_t **itd,
431                                        uint32_t count)
432 {
433     usb_host_ohci_isochronous_transfer_descritpor_struct_t *p = NULL;
434     uint32_t *tmp;
435     void *temp;
436     OSA_SR_ALLOC();
437 
438     /* free a td */
439     /* Enter critical */
440     OSA_ENTER_CRITICAL();
441     if (count > usbHostState->itdCount)
442     {
443         OSA_EXIT_CRITICAL();
444         return kStatus_USB_Busy;
445     }
446     *itd = NULL;
447     while ((0U != count) && (NULL != usbHostState->itdList))
448     {
449         if (NULL == (*itd))
450         {
451             *itd = usbHostState->itdList;
452         }
453         else
454         {
455             p->NextTD = (uint32_t)usbHostState->itdList;
456         }
457         p                     = usbHostState->itdList;
458         usbHostState->itdList = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)usbHostState->itdList->NextTD;
459         temp                  = (void *)(p);
460         tmp                   = (uint32_t *)(temp);
461         usbHostState->itdCount--;
462         for (uint32_t i = 0; i < (sizeof(usb_host_ohci_isochronous_transfer_descritpor_struct_t) / sizeof(uint32_t));
463              i++)
464         {
465             tmp[i] = 0U;
466         }
467         count--;
468     }
469     if (NULL == p)
470     {
471         OSA_EXIT_CRITICAL();
472         return kStatus_USB_Busy;
473     }
474     p->NextTD = 0U;
475     /* Exit critical */
476     OSA_EXIT_CRITICAL();
477     return kStatus_USB_Success;
478 }
479 
USB_HostOhciFreeItd(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_isochronous_transfer_descritpor_struct_t * itd)480 static usb_status_t USB_HostOhciFreeItd(usb_host_ohci_state_struct_t *usbHostState,
481                                         usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd)
482 {
483     usb_host_ohci_isochronous_transfer_descritpor_struct_t *p;
484     usb_host_ohci_isochronous_transfer_descritpor_struct_t *pre;
485     OSA_SR_ALLOC();
486 
487     if (NULL == itd)
488     {
489         return kStatus_USB_Error;
490     }
491     /* free a td */
492     /* Enter critical */
493     pre = NULL;
494     OSA_ENTER_CRITICAL();
495     p = usbHostState->itdList;
496     while (NULL != p)
497     {
498         if (p == itd)
499         {
500             OSA_EXIT_CRITICAL();
501             return kStatus_USB_Success;
502         }
503         pre = p;
504         p   = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)p->NextTD;
505     }
506     if (NULL == pre)
507     {
508         usbHostState->itdList = itd;
509     }
510     else
511     {
512         pre->NextTD = (uint32_t)itd;
513     }
514     itd->NextTD = 0U;
515     usbHostState->itdCount++;
516     /* Exit critical */
517     OSA_EXIT_CRITICAL();
518     return kStatus_USB_Success;
519 }
520 #endif
USB_HostOhciLinkTdToDoneList(usb_host_ohci_state_struct_t * usbHostState)521 static void USB_HostOhciLinkTdToDoneList(usb_host_ohci_state_struct_t *usbHostState)
522 {
523     usb_host_ohci_general_transfer_descritpor_struct_t *tdList;
524     usb_host_ohci_general_transfer_descritpor_struct_t *tdListPos;
525     tdList = (usb_host_ohci_general_transfer_descritpor_struct_t
526                   *)(s_UsbHostOhciHcca[usbHostState->controllerId].HccaDoneHead & USB_HOST_OHCI_HD_MASK);
527 
528     while (NULL != tdList)
529     {
530         tdListPos = (usb_host_ohci_general_transfer_descritpor_struct_t *)(tdList->NextTD & USB_HOST_OHCI_HD_MASK);
531         {
532             if (NULL != usbHostState->tdDoneListTail)
533             {
534                 usbHostState->tdDoneListTail->NextTD = (uint32_t)tdList;
535             }
536             else
537             {
538                 usbHostState->tdDoneListHead = tdList;
539             }
540             usbHostState->tdDoneListTail = tdList;
541         }
542         tdList = tdListPos;
543     }
544     if (NULL != usbHostState->tdDoneListTail)
545     {
546         usbHostState->tdDoneListTail->NextTD = 0U;
547     }
548     usbHostState->writeBackCount++;
549     s_UsbHostOhciHcca[usbHostState->controllerId].HccaDoneHead = 0U;
550 }
551 
USB_HostOhciPortChange(usb_host_ohci_state_struct_t * usbHostState)552 static usb_status_t USB_HostOhciPortChange(usb_host_ohci_state_struct_t *usbHostState)
553 {
554     uint32_t portStatus;
555     uint32_t i;
556     uint32_t portCount = (usbHostState->usbRegBase->HcRhDescriptorA & USB_HOST_OHCI_RHDESCRIPTORA_NDP_MASK);
557 
558     for (i = 0U; i < portCount; i++)
559     {
560         portStatus = usbHostState->usbRegBase->HcRhPortStatus[i];
561         if (0U != (portStatus & USB_HOST_OHCI_RHPORTSTATUS_CSC_MASK))
562         {
563 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
564             if (kBus_OhciIdle != usbHostState->busSuspendStatus)
565             {
566                 usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
567                 portStatus                       = usbHostState->usbRegBase->HcRhPortStatus[i];
568                 portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
569                 usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus | USB_HOST_OHCI_RHPORTSTATUS_PSSC_MASK;
570                 while (0U != (usbHostState->usbRegBase->HcRhPortStatus[i] & USB_HOST_OHCI_RHPORTSTATUS_PSS_MASK))
571                 {
572                 }
573                 portStatus = usbHostState->usbRegBase->HcControl;
574                 portStatus &= ~(USB_HOST_OHCI_CONTROL_HCFS_MASK | USB_HOST_OHCI_CONTROL_RWE_MASK |
575                                 USB_HOST_OHCI_CONTROL_RWC_MASK);
576                 portStatus |= USB_HOST_OHCI_CONTROL_HCFS(USB_HOST_OHCI_CONTROL_HCFS_OPERATIONAL);
577                 usbHostState->usbRegBase->HcControl = portStatus;
578                 portStatus                          = usbHostState->usbRegBase->HcRhPortStatus[i];
579                 portStatus &= ~(USB_HOST_OHCI_RHPORTSTATUS_WIC);
580                 portStatus |= USB_HOST_OHCI_RHPORTSTATUS_PES_MASK;
581                 usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus;
582                 hostPointer->suspendedDevice                = NULL;
583                 usbHostState->busSuspendStatus              = kBus_OhciIdle;
584             }
585 #endif
586             uint32_t sofStart = (uint32_t)s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber &
587                                 USB_HOST_OHCI_FMNUMBER_FN_MASK;
588             uint32_t sof;
589             while (1U == 1U)
590             {
591                 portStatus = usbHostState->usbRegBase->HcRhPortStatus[i];
592                 if (0U != (portStatus & USB_HOST_OHCI_RHPORTSTATUS_CSC_MASK))
593                 {
594                     portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
595                     usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus | USB_HOST_OHCI_RHPORTSTATUS_CSC_MASK;
596                 }
597                 sof = (uint32_t)((uint32_t)s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber &
598                                  USB_HOST_OHCI_FMNUMBER_FN_MASK);
599                 if ((((sof + USB_HOST_OHCI_FMNUMBER_FN_MASK + 1U) - sofStart) & USB_HOST_OHCI_FMNUMBER_FN_MASK) > 1U)
600                 {
601                     break;
602                 }
603             }
604         }
605 
606         portStatus = usbHostState->usbRegBase->HcRhPortStatus[i];
607 
608         if (0U != (portStatus & USB_HOST_OHCI_RHPORTSTATUS_CCS_MASK))
609         {
610             uint32_t index;
611             if (((uint8_t)kUSB_DeviceOhciPortDetached) != usbHostState->portState[i].portStatus)
612             {
613 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
614                 if ((kBus_OhciSuspended == usbHostState->busSuspendStatus) ||
615                     (kBus_OhciStartResume == usbHostState->busSuspendStatus))
616                 {
617                     if (0U != (portStatus & USB_HOST_OHCI_RHPORTSTATUS_PSSC_MASK))
618                     {
619                         usb_host_instance_t *hostPointer = (usb_host_instance_t *)usbHostState->hostHandle;
620                         usbHostState->busSuspendStatus   = kBus_OhciStartResume;
621                         /* call host callback function, function is initialized in USB_HostInit */
622                         (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
623                                                           kUSB_HostEventDetectResume); /* call host callback function */
624                         portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
625                         usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus | USB_HOST_OHCI_RHPORTSTATUS_PSSC_MASK;
626                         while (0U !=
627                                (usbHostState->usbRegBase->HcRhPortStatus[i] & USB_HOST_OHCI_RHPORTSTATUS_PSS_MASK))
628                         {
629                         }
630                         portStatus = usbHostState->usbRegBase->HcControl;
631                         portStatus &= ~(USB_HOST_OHCI_CONTROL_HCFS_MASK | USB_HOST_OHCI_CONTROL_RWE_MASK |
632                                         USB_HOST_OHCI_CONTROL_RWC_MASK);
633                         portStatus |= USB_HOST_OHCI_CONTROL_HCFS(USB_HOST_OHCI_CONTROL_HCFS_OPERATIONAL);
634                         usbHostState->usbRegBase->HcControl = portStatus;
635                         portStatus                          = usbHostState->usbRegBase->HcRhPortStatus[i];
636                         portStatus &= ~(USB_HOST_OHCI_RHPORTSTATUS_WIC);
637                         portStatus |= USB_HOST_OHCI_RHPORTSTATUS_PES_MASK;
638                         usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus;
639                         /* call host callback function, function is initialized in USB_HostInit */
640                         (void)hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL,
641                                                           kUSB_HostEventResumed); /* call host callback function */
642                         hostPointer->suspendedDevice   = NULL;
643                         usbHostState->busSuspendStatus = kBus_OhciIdle;
644                     }
645                 }
646 #endif
647                 break;
648             }
649 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
650             usbHostState->busSuspendStatus = kBus_OhciIdle;
651 #endif
652             for (index = 0U; index < USB_HOST_OHCI_PORT_CONNECT_DEBOUNCE_DELAY; index++)
653             {
654                 (void)USB_HostOhciDelay(usbHostState, 1);
655                 if (0U == ((usbHostState->usbRegBase->HcRhPortStatus[i] & USB_HOST_OHCI_RHPORTSTATUS_CCS_MASK)))
656                 {
657                     break;
658                 }
659             }
660 
661             portStatus = usbHostState->usbRegBase->HcRhPortStatus[i];
662 
663             /* CCS is cleared ?*/
664             if ((0U == ((portStatus & USB_HOST_OHCI_RHPORTSTATUS_CCS_MASK))) ||
665                 (index < USB_HOST_OHCI_PORT_CONNECT_DEBOUNCE_DELAY))
666             {
667                 usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceOhciPortDetached;
668                 continue;
669             }
670 
671             portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
672             usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus | USB_HOST_OHCI_RHPORTSTATUS_PRS_MASK;
673 
674             while (0U != (usbHostState->usbRegBase->HcRhPortStatus[i] & USB_HOST_OHCI_RHPORTSTATUS_PRS_MASK))
675             {
676                 __NOP();
677             }
678 
679             usbHostState->portState[i].portSpeed =
680                 (0U != (usbHostState->usbRegBase->HcRhPortStatus[i] & USB_HOST_OHCI_RHPORTSTATUS_LSDA_MASK)) ?
681                     USB_SPEED_LOW :
682                     USB_SPEED_FULL;
683             /* do bus recovery delay */
684             (void)USB_HostOhciDelay(usbHostState, USB_HOST_OHCI_PORT_RESET_RECOVERY_DELAY);
685             usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceOhciPortPhyAttached;
686             (void)OSA_EventSet(usbHostState->ohciEvent, USB_HOST_OHCI_EVENT_ATTACH);
687         }
688         else
689         {
690             if ((uint8_t)kUSB_DeviceOhciPortDetached == usbHostState->portState[i].portStatus)
691             {
692                 continue;
693             }
694 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
695             usbHostState->busSuspendStatus = kBus_OhciIdle;
696 #endif
697             usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceOhciPortPhyDetached;
698             (void)OSA_EventSet(usbHostState->ohciEvent, USB_HOST_OHCI_EVENT_DETACH);
699         }
700     }
701     return kStatus_USB_Success;
702 }
703 
USB_HostOhciFindStartFrame(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)704 static usb_status_t USB_HostOhciFindStartFrame(usb_host_ohci_state_struct_t *usbHostState,
705                                                usb_host_ohci_pipe_struct_t *pipe)
706 {
707     usb_host_ohci_pipe_struct_t *p;
708     uint32_t startFrame;
709     uint32_t frame;
710     uint32_t total = 0U;
711     void *temp;
712 
713     pipe->startFrame = 0U;
714 
715     if (NULL == usbHostState->pipeListInUsing)
716     {
717         return kStatus_USB_Success;
718     }
719 
720     for (startFrame = 0U; startFrame < pipe->pipeCommon.interval; startFrame++)
721     {
722         for (frame = startFrame; frame < USB_HOST_OHCI_HCCA_SIZE; frame++)
723         {
724             total = 0U;
725             temp  = (void *)usbHostState->pipeListInUsing;
726             while (NULL != temp)
727             {
728                 p    = (usb_host_ohci_pipe_struct_t *)temp;
729                 temp = (void *)p->pipeCommon.next;
730                 if ((frame >= p->startFrame) && (0U == ((frame - p->startFrame) % p->pipeCommon.interval)))
731                 {
732                     total += p->busTime;
733                 }
734             }
735             if ((float)total > USB_HOST_OHCI_PERIODIC_BANDWIDTH)
736             {
737                 break;
738             }
739         }
740         if (frame >= USB_HOST_OHCI_HCCA_SIZE)
741         {
742             pipe->startFrame = (uint16_t)startFrame;
743             return kStatus_USB_Success;
744         }
745     }
746     return kStatus_USB_BandwidthFail;
747 }
748 
USB_HostOhciAddToPeriodicList(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)749 static usb_status_t USB_HostOhciAddToPeriodicList(usb_host_ohci_state_struct_t *usbHostState,
750                                                   usb_host_ohci_pipe_struct_t *pipe)
751 {
752     uint32_t i;
753     uint32_t dummy = (uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_PERIODIC_ED_DUMMY];
754     usb_host_ohci_endpoint_descritpor_struct_t *ed;
755     usb_host_ohci_endpoint_descritpor_struct_t *pre;
756 
757     for (i = pipe->startFrame; i < USB_HOST_OHCI_HCCA_SIZE; i += pipe->pipeCommon.interval)
758     {
759         ed = (usb_host_ohci_endpoint_descritpor_struct_t *)s_UsbHostOhciHcca[usbHostState->controllerId]
760                  .HccaInterrruptTable[i];
761         pre = ed;
762 
763         while (NULL != pre)
764         {
765             if (pre == pipe->ed)
766             {
767                 break;
768             }
769             pre = (usb_host_ohci_endpoint_descritpor_struct_t *)pre->NextED;
770         }
771 
772         if (NULL != pre)
773         {
774             continue;
775         }
776 
777         pre = NULL;
778         while (dummy != (uint32_t)ed)
779         {
780             if (ed->pipe->pipeCommon.interval <= pipe->pipeCommon.interval)
781             {
782                 if ((USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType) && (dummy != (uint32_t)ed))
783                 {
784                 }
785                 else
786                 {
787                     break;
788                 }
789             }
790             pre = ed;
791             ed  = (usb_host_ohci_endpoint_descritpor_struct_t *)ed->NextED;
792         }
793         pipe->ed->NextED = (uint32_t)ed;
794         if (NULL != pre)
795         {
796             pre->NextED = (uint32_t)pipe->ed;
797         }
798         else
799         {
800             s_UsbHostOhciHcca[usbHostState->controllerId].HccaInterrruptTable[i] = (uint32_t)pipe->ed;
801         }
802     }
803     return kStatus_USB_Success;
804 }
805 
USB_HostOhciOpenControlBulkPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)806 static usb_status_t USB_HostOhciOpenControlBulkPipe(usb_host_ohci_state_struct_t *usbHostState,
807                                                     usb_host_ohci_pipe_struct_t *pipe)
808 {
809     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
810     usb_status_t error;
811 
812     error = USB_HostOhciGetGtd(usbHostState, &gtd, 1);
813     if (kStatus_USB_Success != error)
814     {
815         return error;
816     }
817 
818     gtd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
819     gtd->stateUnion.stateBitField.R  = 1U;
820 
821     pipe->ed->TailP = (uint32_t)gtd;
822     pipe->ed->HeadP = (uint32_t)gtd;
823     if (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType)
824     {
825         pipe->ed->NextED = s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_CONTROL_ED_DUMMY].NextED;
826         s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_CONTROL_ED_DUMMY].NextED = (uint32_t)pipe->ed;
827         usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_CLE_MASK;
828     }
829     else
830     {
831         pipe->ed->NextED = s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_BULK_ED_DUMMY].NextED;
832         s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_BULK_ED_DUMMY].NextED = (uint32_t)pipe->ed;
833         usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_BLE_MASK;
834     }
835 
836     return kStatus_USB_Success;
837 }
838 
839 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
USB_HostOhciOpenIsoPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)840 static usb_status_t USB_HostOhciOpenIsoPipe(usb_host_ohci_state_struct_t *usbHostState,
841                                             usb_host_ohci_pipe_struct_t *pipe)
842 {
843 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
844     usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd;
845 #endif
846     usb_status_t error;
847     OSA_SR_ALLOC();
848 
849     pipe->busTime = (uint16_t)USB_HostOhciBusTime(
850         ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed, pipe->pipeCommon.pipeType,
851         pipe->pipeCommon.direction,
852         ((uint32_t)pipe->pipeCommon.maxPacketSize) * ((uint32_t)pipe->pipeCommon.numberPerUframe));
853 
854     OSA_ENTER_CRITICAL();
855     error = USB_HostOhciFindStartFrame(usbHostState, pipe);
856     if (kStatus_USB_Success != error)
857     {
858         OSA_EXIT_CRITICAL();
859         return error;
860     }
861 
862 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
863     error = USB_HostOhciGetItd(usbHostState, &itd, 1);
864     if (kStatus_USB_Success != error)
865     {
866         OSA_EXIT_CRITICAL();
867         return error;
868     }
869     itd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
870 
871     pipe->ed->TailP = (uint32_t)itd;
872     pipe->ed->HeadP = (uint32_t)itd;
873 #else
874     pipe->ed->TailP = (uint32_t)0;
875     pipe->ed->HeadP = (uint32_t)0;
876 #endif
877 
878     usbHostState->usbRegBase->HcControl &= ~(USB_HOST_OHCI_CONTROL_PLE_MASK | USB_HOST_OHCI_CONTROL_IE_MASK);
879 
880     (void)USB_HostOhciAddToPeriodicList(usbHostState, pipe);
881 
882     usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_PLE_MASK | USB_HOST_OHCI_CONTROL_IE_MASK;
883 
884     OSA_EXIT_CRITICAL();
885     return kStatus_USB_Success;
886 }
887 #endif
888 
USB_HostOhciOpenInterruptPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)889 static usb_status_t USB_HostOhciOpenInterruptPipe(usb_host_ohci_state_struct_t *usbHostState,
890                                                   usb_host_ohci_pipe_struct_t *pipe)
891 {
892     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
893     usb_status_t error;
894     OSA_SR_ALLOC();
895 
896     pipe->busTime = (uint16_t)USB_HostOhciBusTime(
897         ((usb_host_device_instance_t *)pipe->pipeCommon.deviceHandle)->speed, pipe->pipeCommon.pipeType,
898         pipe->pipeCommon.direction,
899         ((uint32_t)pipe->pipeCommon.maxPacketSize) * ((uint32_t)pipe->pipeCommon.numberPerUframe));
900 
901     OSA_ENTER_CRITICAL();
902     error = USB_HostOhciFindStartFrame(usbHostState, pipe);
903     if (kStatus_USB_Success != error)
904     {
905         OSA_EXIT_CRITICAL();
906         return error;
907     }
908 
909     error = USB_HostOhciGetGtd(usbHostState, &gtd, 1);
910     if (kStatus_USB_Success != error)
911     {
912         OSA_EXIT_CRITICAL();
913         return error;
914     }
915     gtd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
916     gtd->stateUnion.stateBitField.R  = 1U;
917 
918     pipe->ed->TailP = (uint32_t)gtd;
919     pipe->ed->HeadP = (uint32_t)gtd;
920 
921     (void)USB_HostOhciAddToPeriodicList(usbHostState, pipe);
922     OSA_EXIT_CRITICAL();
923 
924     usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_PLE_MASK;
925 
926     return kStatus_USB_Success;
927 }
928 
USB_HostOhciTdDoneHandle(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * currentTr,usb_host_ohci_general_transfer_descritpor_struct_t * gtd,usb_host_ohci_isochronous_transfer_descritpor_struct_t * itd)929 static void USB_HostOhciTdDoneHandle(usb_host_ohci_state_struct_t *usbHostState,
930                                      usb_host_ohci_pipe_struct_t *pipe,
931                                      usb_host_transfer_t *currentTr,
932                                      usb_host_ohci_general_transfer_descritpor_struct_t *gtd,
933                                      usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd)
934 {
935     usb_host_transfer_t *trPos;
936     usb_host_transfer_t *trPre;
937     usb_host_ohci_pipe_struct_t *p;
938 
939     uint32_t startFrame;
940     uint32_t currentFrame;
941     uint32_t *temp;
942     void *tempVoid;
943 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
944     uint32_t conditionCode;
945 #endif
946 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
947     uint8_t reRunLabel = 0;
948 #endif
949 
950     pipe->isDone = 0U;
951     if (NULL == currentTr)
952     {
953 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
954         if (NULL != itd)
955         {
956             itd->stateUnion.state            = 0U;
957             itd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
958             itd->NextTD                      = 0U;
959             itd->BE                          = 0U;
960             itd->BP0                         = 0U;
961             (void)USB_HostOhciFreeItd(usbHostState, itd);
962         }
963         else
964 #endif
965         {
966             gtd->stateUnion.state            = 0U;
967             gtd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
968             gtd->stateUnion.stateBitField.R  = 1U;
969             gtd->CBP                         = 0U;
970             gtd->NextTD                      = 0U;
971             gtd->BE                          = 0U;
972         }
973         return;
974     }
975 
976     if (USB_HOST_OHCI_CC_NO_ERROR != gtd->stateUnion.stateBitField.CC)
977     {
978         if (kStatus_USB_Success == (usb_status_t)currentTr->union2.frame)
979         {
980 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
981             uint32_t speed = USB_SPEED_FULL;
982             if (pipe->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)
983             {
984                 (void)USB_HostHelperGetPeripheralInformation(pipe->pipeCommon.deviceHandle,
985                                                              (uint32_t)kUSB_HostGetDeviceSpeed, &speed);
986                 if ((gtd->stateUnion.stateBitField.CC == USB_HOST_OHCI_CC_DEVICE_NOT_RESPONDING) &&
987                     (speed == USB_SPEED_LOW))
988                 {
989                     pipe->deviceNotRespondingCount++;
990                     if (pipe->deviceNotRespondingCount <
991                         USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND_CONSEQUENT_COUNT)
992                     {
993                         pipe->endpointInterval = (uint16_t)(pipe->pipeCommon.interval + 1U);
994                         /* re-run the GTD */
995                         reRunLabel = 1U;
996                     }
997                     else
998                     {
999                         pipe->deviceNotRespondingCount = 0U;
1000                         pipe->endpointInterval         = 0U;
1001                         currentTr->union2.frame        = (uint32_t)kStatus_USB_TransferFailed;
1002                     }
1003                 }
1004             }
1005             else
1006             {
1007                 currentTr->union2.frame = (uint32_t)kStatus_USB_TransferFailed;
1008             }
1009 #else
1010             currentTr->union2.frame = (uint32_t)kStatus_USB_TransferFailed;
1011 #endif
1012         }
1013 
1014         if (USB_HOST_OHCI_CC_STALL == gtd->stateUnion.stateBitField.CC)
1015         {
1016             currentTr->union2.frame = (uint32_t)kStatus_USB_TransferStall;
1017         }
1018         pipe->ed->HeadP &= ~USB_HOST_OHCI_ED_HEADP_HALT_MASK;
1019     }
1020 
1021 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
1022     if (NULL != itd)
1023     {
1024         usb_host_ohci_isochronous_transfer_descritpor_struct_t *itdP;
1025         usb_host_ohci_isochronous_transfer_descritpor_struct_t *itdQ = NULL;
1026         itdP = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)currentTr->union1.unitHead;
1027 
1028         while (NULL != itdP)
1029         {
1030             if (itd == itdP)
1031             {
1032                 if (NULL != itdQ)
1033                 {
1034                     itdQ->nextItd = itdP->nextItd;
1035                 }
1036                 else
1037                 {
1038                     currentTr->union1.unitHead = (uint32_t)itdP->nextItd;
1039                 }
1040                 break;
1041             }
1042             itdQ = itdP;
1043             itdP = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)itdP->nextItd;
1044         }
1045         currentTr->transferSofar = 0U;
1046         for (uint32_t i = 0; i <= itd->stateUnion.stateBitField.FC; i++)
1047         {
1048             currentTr->transferSofar += ((uint32_t)itd->OffsetPSW[i] & (USB_HOST_OHCI_ITD_TRANSFER_SIZE_MASK));
1049             conditionCode = (((uint32_t)itd->OffsetPSW[i] & (USB_HOST_OHCI_ITD_CONDITION_CODE_MASK)) >>
1050                              USB_HOST_OHCI_ITD_CONDITION_CODE_SHIFT);
1051             if (0U != conditionCode)
1052             {
1053                 if (conditionCode != USB_HOST_OHCI_CC_DATA_UNDERRUN)
1054                 {
1055                     if (kStatus_USB_Success == (usb_status_t)currentTr->union2.frame)
1056                     {
1057                         if (conditionCode == USB_HOST_OHCI_CC_DATA_OVERRUN)
1058                         {
1059                             currentTr->union2.frame = (uint32_t)kStatus_USB_DataOverRun;
1060                         }
1061                         else
1062                         {
1063                             currentTr->union2.frame = (uint32_t)kStatus_USB_Error;
1064                         }
1065                     }
1066                 }
1067             }
1068         }
1069         if (currentTr->direction == USB_OUT)
1070         {
1071             currentTr->transferSofar = currentTr->transferLength - currentTr->transferSofar;
1072         }
1073         (void)USB_HostOhciFreeItd(usbHostState, itd);
1074     }
1075     else
1076 #endif
1077     {
1078         usb_host_ohci_general_transfer_descritpor_struct_t *gtdP;
1079         usb_host_ohci_general_transfer_descritpor_struct_t *gtdQ = NULL;
1080 
1081         gtdP = (usb_host_ohci_general_transfer_descritpor_struct_t *)currentTr->union1.unitHead;
1082         while (NULL != gtdP)
1083         {
1084             if (gtd == gtdP)
1085             {
1086                 if (NULL != gtdQ)
1087                 {
1088                     gtdQ->nextGtd = gtdP->nextGtd;
1089                 }
1090                 else
1091                 {
1092                     uint32_t tail              = pipe->ed->TailP & USB_HOST_OHCI_ED_TAILP_MASK;
1093                     uint32_t head              = pipe->ed->HeadP & USB_HOST_OHCI_ED_HEADP_MASK;
1094                     currentTr->union1.unitHead = (uint32_t)gtdP->nextGtd;
1095                     if (head != tail)
1096                     {
1097                         pipe->ed->HeadP &= ~USB_HOST_OHCI_ED_HEADP_MASK;
1098                         pipe->ed->HeadP |= (uint32_t)gtdP->NextTD;
1099                     }
1100                 }
1101                 break;
1102             }
1103             gtdQ = gtdP;
1104             gtdP = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtdP->nextGtd;
1105         }
1106 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
1107         if (0U == reRunLabel)
1108 #endif
1109         {
1110             if ((0U != gtd->CBP) && (USB_HOST_OHCI_GTD_DP_SETUP != gtd->stateUnion.stateBitField.DP))
1111             {
1112                 currentTr->transferLength -= ((0U != (((gtd->BE) ^ (gtd->CBP)) & 0xFFFFF000U)) ? 0x00001000U : 0U) +
1113                                              ((gtd->BE) & 0x00000FFFU) - ((gtd->CBP) & 0x00000FFFU) + 1U;
1114             }
1115             currentTr->transferSofar = currentTr->transferLength;
1116         }
1117         (void)USB_HostOhciFreeGtd(usbHostState, gtd);
1118     }
1119 
1120     temp = (uint32_t *)(currentTr->union1.unitHead);
1121     if (NULL == (void *)(temp))
1122     {
1123         if ((0U == pipe->isCanceling) && ((uint32_t)kStatus_USB_Success == currentTr->union2.frame))
1124         {
1125             if (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType)
1126             {
1127                 if (NULL != pipe->ed->trListHead)
1128                 {
1129                     if (kStatus_USB_Success == USB_HostOhciLinkGtdControlTr(usbHostState, pipe, pipe->ed->trListHead))
1130                     {
1131                         /*no action, added for misra4.7*/
1132                     }
1133                     else
1134                     {
1135                         /*no action*/
1136                     }
1137                 }
1138             }
1139         }
1140     }
1141     temp = (uint32_t *)(currentTr->union1.unitHead);
1142     if (NULL == (void *)(temp))
1143     {
1144         uint8_t trIsFound = 0;
1145         trPre             = NULL;
1146         trPos             = pipe->ed->trListHead;
1147 
1148         while (NULL != trPos)
1149         {
1150             if (currentTr == trPos)
1151             {
1152                 if (NULL == trPre)
1153                 {
1154                     pipe->ed->trListHead = trPos->next;
1155                 }
1156                 else
1157                 {
1158                     trPre->next = trPos->next;
1159                 }
1160                 trIsFound = 1;
1161                 break;
1162             }
1163             trPre = trPos;
1164             trPos = trPos->next;
1165         }
1166         if (NULL == pipe->ed->trListHead)
1167         {
1168             pipe->ed->trListTail = NULL;
1169         }
1170 
1171         if (0U != trIsFound)
1172         {
1173             pipe->cutOffTime = USB_HOST_OHCI_TRANSFER_TIMEOUT_GAP;
1174 
1175             if ((kStatus_USB_Success == ((usb_status_t)currentTr->union2.frame)) &&
1176                 (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType) &&
1177                 (USB_REQUEST_STANDARD_CLEAR_FEATURE == currentTr->setupPacket->bRequest) &&
1178                 (USB_REQUEST_TYPE_RECIPIENT_ENDPOINT == currentTr->setupPacket->bmRequestType) &&
1179                 (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT ==
1180                  (USB_SHORT_FROM_LITTLE_ENDIAN(currentTr->setupPacket->wValue) & 0x00FFU)))
1181             {
1182                 p = usbHostState->pipeListInUsing;
1183                 while (p != NULL)
1184                 {
1185                     /* only compute bulk and interrupt pipe */
1186                     if (((p->pipeCommon.endpointAddress |
1187                           (p->pipeCommon.direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) ==
1188                          ((uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(currentTr->setupPacket->wIndex)))) &&
1189                         (p->pipeCommon.deviceHandle == pipe->pipeCommon.deviceHandle))
1190                     {
1191                         break;
1192                     }
1193                     tempVoid = (void *)p->pipeCommon.next;
1194                     p        = (usb_host_ohci_pipe_struct_t *)tempVoid;
1195                 }
1196 
1197                 if ((NULL != p) && ((p->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) ||
1198                                     (p->pipeCommon.pipeType == USB_ENDPOINT_BULK)))
1199                 {
1200                     p->ed->stateUnion.stateBitField.K = 1U;
1201                     startFrame                        = s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber;
1202                     currentFrame                      = startFrame;
1203 
1204                     while (currentFrame == startFrame)
1205                     {
1206                         currentFrame = s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber;
1207                     }
1208 
1209                     p->ed->HeadP &= ~USB_HOST_OHCI_ED_HEADP_CARRY_MASK;
1210 
1211                     p->ed->stateUnion.stateBitField.K = 0U;
1212                 }
1213             }
1214 
1215 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
1216             if (0U != reRunLabel)
1217             {
1218                 (void)USB_HostOhciWritePipe(usbHostState, pipe, currentTr);
1219             }
1220             else
1221 #endif
1222             {
1223 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
1224                 pipe->deviceNotRespondingCount = 0U;
1225                 pipe->endpointInterval         = 0U;
1226 #endif
1227                 currentTr->callbackFn(currentTr->callbackParam, currentTr,
1228                                       (usb_status_t)currentTr->union2.frame); /* transfer callback */
1229             }
1230             if (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType)
1231             {
1232                 usbHostState->controlIsBusy = 0U;
1233             }
1234             pipe->isBusy = 0U;
1235         }
1236         else
1237         {
1238         }
1239 
1240         if (0U == usbHostState->controlIsBusy)
1241         {
1242             p = usbHostState->pipeListInUsing;
1243 
1244             while (NULL != p)
1245             {
1246                 if (USB_ENDPOINT_CONTROL == p->pipeCommon.pipeType)
1247                 {
1248                     if (NULL != p->ed->trListHead)
1249                     {
1250                         /* initialize gtd for control/bulk/interrupt transfer */
1251                         if (kStatus_USB_Success == USB_HostOhciLinkGtdControlTr(usbHostState, p, p->ed->trListHead))
1252                         {
1253                             usbHostState->controlIsBusy = 1U;
1254                             break;
1255                         }
1256                         else
1257                         {
1258                             /*fixed misra directive 4.7*/
1259                         }
1260                     }
1261                 }
1262                 tempVoid = (void *)p->pipeCommon.next;
1263                 p        = (usb_host_ohci_pipe_struct_t *)tempVoid;
1264             }
1265         }
1266 
1267         if (NULL != pipe->ed->trListHead)
1268         {
1269             switch (pipe->pipeCommon.pipeType)
1270             {
1271                 case USB_ENDPOINT_CONTROL:
1272                     break;
1273                 case USB_ENDPOINT_BULK:
1274                 case USB_ENDPOINT_INTERRUPT:
1275                     /* initialize gtd for control/bulk/interrupt transfer */
1276                     if (kStatus_USB_Success != USB_HostOhciLinkGtdTr(usbHostState, pipe, pipe->ed->trListHead))
1277                     {
1278                         /*for misra 4.7, no meaning */
1279                     }
1280                     else
1281                     {
1282                         /*for misra 4.7*/
1283                     }
1284                     break;
1285 #if ((defined USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD))
1286                 case USB_ENDPOINT_ISOCHRONOUS:
1287                     /* initialize itd for iso transfer */
1288                     /* USB_HostOhciLinkItdTr(usbHostState, pipe, pipe->ed->trListHead); */
1289                     break;
1290 #endif
1291                 default:
1292                     /*no action*/
1293                     break;
1294             }
1295         }
1296     }
1297 }
1298 
USB_HostOhciCancelPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr)1299 static usb_status_t USB_HostOhciCancelPipe(usb_host_ohci_state_struct_t *usbHostState,
1300                                            usb_host_ohci_pipe_struct_t *pipe,
1301                                            usb_host_transfer_t *tr)
1302 {
1303     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
1304     usb_host_ohci_general_transfer_descritpor_struct_t *gtdPre;
1305     usb_host_ohci_general_transfer_descritpor_struct_t *gtdPos;
1306     usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd;
1307     usb_host_ohci_pipe_struct_t *currentPipe;
1308     usb_host_transfer_t *trCurrent;
1309     usb_host_transfer_t *trPos;
1310     usb_host_transfer_t *trPre;
1311     uint32_t startFrame;
1312     uint32_t currentFrame;
1313     void *temp;
1314     pipe->ed->stateUnion.stateBitField.K = 1U;
1315     startFrame                           = s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber;
1316     currentFrame                         = startFrame;
1317 
1318     while (currentFrame == startFrame)
1319     {
1320         currentFrame = s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber;
1321     }
1322 
1323     USB_HostOhciLock();
1324     USB_HostOhciDisableIsr(usbHostState);
1325     pipe->isCanceling = 1U;
1326     pipe->ed->HeadP &= ~USB_HOST_OHCI_ED_HEADP_MASK;
1327     pipe->ed->HeadP |= pipe->ed->TailP;
1328     /* Fetch the td from token done list */
1329     gtd    = (usb_host_ohci_general_transfer_descritpor_struct_t *)((uint32_t)usbHostState->tdDoneListHead);
1330     gtdPre = NULL;
1331     while (NULL != gtd)
1332     {
1333         if (((uint32_t)gtd) < ((uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].gtd[0]))
1334         {
1335             temp        = (void *)gtd;
1336             itd         = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)temp;
1337             trCurrent   = itd->tr;
1338             currentPipe = itd->pipe;
1339         }
1340         else
1341         {
1342             itd         = NULL;
1343             trCurrent   = gtd->tr;
1344             currentPipe = gtd->pipe;
1345         }
1346         if (pipe == currentPipe)
1347         {
1348             if ((NULL == tr) || (tr == trCurrent))
1349             {
1350                 gtdPos = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtd->NextTD;
1351                 USB_HostOhciTdDoneHandle(usbHostState, pipe, trCurrent, gtd, itd);
1352                 if (NULL == gtdPre)
1353                 {
1354                     usbHostState->tdDoneListHead = gtdPos;
1355                 }
1356                 else
1357                 {
1358                     gtdPre->NextTD = (uint32_t)gtdPos;
1359                 }
1360                 gtd = gtdPos;
1361                 continue;
1362             }
1363         }
1364         gtdPre = gtd;
1365         gtd    = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtd->NextTD;
1366     }
1367 
1368     trPre     = NULL;
1369     trCurrent = pipe->ed->trListHead;
1370 
1371     while (NULL != trCurrent)
1372     {
1373         trPos = trCurrent->next;
1374         if ((NULL == tr) || (tr == trCurrent))
1375         {
1376             if (0UL != trCurrent->union1.unitHead)
1377             {
1378                 gtd = (usb_host_ohci_general_transfer_descritpor_struct_t *)trCurrent->union1.unitHead;
1379                 while (NULL != gtd)
1380                 {
1381                     if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
1382                     {
1383                         temp   = (void *)gtd;
1384                         itd    = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)temp;
1385                         temp   = (void *)itd->nextItd;
1386                         gtdPos = (usb_host_ohci_general_transfer_descritpor_struct_t *)temp;
1387                     }
1388                     else
1389                     {
1390                         itd    = NULL;
1391                         gtdPos = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtd->nextGtd;
1392                     }
1393                     USB_HostOhciTdDoneHandle(usbHostState, pipe, trCurrent, gtd, itd);
1394                     gtd = gtdPos;
1395                 }
1396             }
1397             else
1398             {
1399                 pipe->cutOffTime = USB_HOST_OHCI_TRANSFER_TIMEOUT_GAP;
1400 
1401 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
1402                 pipe->deviceNotRespondingCount = 0U;
1403                 pipe->endpointInterval         = 0U;
1404 #endif
1405                 trCurrent->callbackFn(trCurrent->callbackParam, trCurrent,
1406                                       kStatus_USB_TransferCancel); /* transfer callback */
1407 
1408                 pipe->isBusy = 0U;
1409 
1410                 if (NULL == trPre)
1411                 {
1412                     pipe->ed->trListHead = trPos;
1413                 }
1414                 else
1415                 {
1416                     trPre->next = trPos;
1417                 }
1418             }
1419         }
1420         else
1421         {
1422             trPre = trCurrent;
1423         }
1424         trCurrent = trPos;
1425     }
1426     if (NULL == pipe->ed->trListHead)
1427     {
1428         pipe->ed->trListTail = NULL;
1429     }
1430     pipe->isCanceling = 0U;
1431     USB_HostOhciEnableIsr(usbHostState);
1432     USB_HostOhciUnlock();
1433     pipe->ed->stateUnion.stateBitField.K = 0U;
1434 
1435     return kStatus_USB_Success;
1436 }
1437 
USB_HostOhciRemoveFromPeriodicList(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)1438 static usb_status_t USB_HostOhciRemoveFromPeriodicList(usb_host_ohci_state_struct_t *usbHostState,
1439                                                        usb_host_ohci_pipe_struct_t *pipe)
1440 {
1441     uint32_t i;
1442     usb_host_ohci_endpoint_descritpor_struct_t *ed;
1443     usb_host_ohci_endpoint_descritpor_struct_t *pre;
1444 
1445     for (i = pipe->startFrame; i < USB_HOST_OHCI_HCCA_SIZE; i += pipe->pipeCommon.interval)
1446     {
1447         pre = NULL;
1448         ed  = (usb_host_ohci_endpoint_descritpor_struct_t *)s_UsbHostOhciHcca[usbHostState->controllerId]
1449                  .HccaInterrruptTable[i];
1450 
1451         while (NULL != ed)
1452         {
1453             if (ed == pipe->ed)
1454             {
1455                 if (NULL == pre)
1456                 {
1457                     s_UsbHostOhciHcca[usbHostState->controllerId].HccaInterrruptTable[i] = ed->NextED;
1458                 }
1459                 else
1460                 {
1461                     pre->NextED = ed->NextED;
1462                 }
1463                 break;
1464             }
1465             pre = ed;
1466             ed  = (usb_host_ohci_endpoint_descritpor_struct_t *)ed->NextED;
1467         }
1468     }
1469     return kStatus_USB_Success;
1470 }
1471 
USB_HostOhciCloseControlBulkPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)1472 static usb_status_t USB_HostOhciCloseControlBulkPipe(usb_host_ohci_state_struct_t *usbHostState,
1473                                                      usb_host_ohci_pipe_struct_t *pipe)
1474 {
1475     usb_host_ohci_endpoint_descritpor_struct_t *edHead;
1476     usb_host_ohci_endpoint_descritpor_struct_t *preEdHead;
1477 
1478     (void)USB_HostOhciCancelPipe(usbHostState, pipe, NULL);
1479 
1480     pipe->ed->stateUnion.stateBitField.K = 1U;
1481 
1482     if (USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType)
1483     {
1484         edHead = &s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_CONTROL_ED_DUMMY];
1485     }
1486     else
1487     {
1488         edHead = &s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_BULK_ED_DUMMY];
1489     }
1490 
1491     (void)USB_HostOhciFreeGtd(
1492         usbHostState,
1493         (usb_host_ohci_general_transfer_descritpor_struct_t *)(pipe->ed->TailP & USB_HOST_OHCI_ED_HEADP_MASK));
1494 
1495     preEdHead = NULL;
1496     while ((NULL != edHead) && (edHead != pipe->ed))
1497     {
1498         preEdHead = edHead;
1499         edHead    = (usb_host_ohci_endpoint_descritpor_struct_t *)edHead->NextED;
1500     }
1501 
1502     if ((NULL != preEdHead) && (NULL != edHead))
1503     {
1504         preEdHead->NextED = edHead->NextED;
1505     }
1506 
1507     return kStatus_USB_Success;
1508 }
1509 
USB_HostOhciCloseIsoInterruptPipe(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe)1510 static usb_status_t USB_HostOhciCloseIsoInterruptPipe(usb_host_ohci_state_struct_t *usbHostState,
1511                                                       usb_host_ohci_pipe_struct_t *pipe)
1512 {
1513     (void)USB_HostOhciCancelPipe(usbHostState, pipe, NULL);
1514 
1515     pipe->ed->stateUnion.stateBitField.K = 1U;
1516     if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
1517     {
1518 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
1519         (void)USB_HostOhciFreeItd(
1520             usbHostState,
1521             (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)(pipe->ed->TailP & USB_HOST_OHCI_ED_HEADP_MASK));
1522 #endif
1523     }
1524     else
1525     {
1526         (void)USB_HostOhciFreeGtd(
1527             usbHostState,
1528             (usb_host_ohci_general_transfer_descritpor_struct_t *)(pipe->ed->TailP & USB_HOST_OHCI_ED_HEADP_MASK));
1529     }
1530 
1531     (void)USB_HostOhciRemoveFromPeriodicList(usbHostState, pipe);
1532 
1533     return kStatus_USB_Success;
1534 }
1535 
USB_HostOhciFillGtd(usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr,usb_host_ohci_general_transfer_descritpor_struct_t * gtd,uint8_t * buffer,uint32_t length,uint8_t dirPid,uint8_t dataToggle,uint8_t ioc)1536 static void USB_HostOhciFillGtd(usb_host_ohci_pipe_struct_t *pipe,
1537                                 usb_host_transfer_t *tr,
1538                                 usb_host_ohci_general_transfer_descritpor_struct_t *gtd,
1539                                 uint8_t *buffer,
1540                                 uint32_t length,
1541                                 uint8_t dirPid,
1542                                 uint8_t dataToggle,
1543                                 uint8_t ioc)
1544 {
1545     gtd->CBP                         = (uint32_t)buffer;
1546     gtd->BE                          = (0U != length) ? (gtd->CBP + length - 1U) : 0U;
1547     gtd->pipe                        = pipe;
1548     gtd->tr                          = tr;
1549     gtd->stateUnion.stateBitField.R  = 1U;
1550     gtd->stateUnion.stateBitField.DP = dirPid;
1551     gtd->stateUnion.stateBitField.DI = (0U != ioc) ? 0U : USB_HOST_OHCI_GTD_DI_NO_INTERRUPT;
1552     gtd->stateUnion.stateBitField.T  = dataToggle;
1553     gtd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
1554     gtd->length                      = length;
1555 }
1556 
USB_HostOhciLinkGtdControlTr(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr)1557 static usb_status_t USB_HostOhciLinkGtdControlTr(usb_host_ohci_state_struct_t *usbHostState,
1558                                                  usb_host_ohci_pipe_struct_t *pipe,
1559                                                  usb_host_transfer_t *tr)
1560 {
1561     usb_host_ohci_general_transfer_descritpor_struct_t *head;
1562     usb_host_ohci_general_transfer_descritpor_struct_t *p = NULL;
1563     void *temp;
1564     uint8_t dirPid   = USB_HOST_OHCI_GTD_DP_SETUP;
1565     uint8_t statePid = 0U;
1566     usb_host_ohci_transfer_status_t transferStaus;
1567     usb_status_t status;
1568     OSA_SR_ALLOC();
1569 
1570     OSA_ENTER_CRITICAL();
1571     if ((0U != pipe->isBusy) && (kStatus_UsbHostOhci_Idle == (usb_host_ohci_transfer_status_t)tr->setupStatus))
1572     {
1573         OSA_EXIT_CRITICAL();
1574         return kStatus_USB_Success;
1575     }
1576     pipe->isBusy = 1;
1577     pipe->isDone = 0U;
1578     OSA_EXIT_CRITICAL();
1579 
1580     transferStaus = (usb_host_ohci_transfer_status_t)tr->setupStatus;
1581     switch (transferStaus)
1582     {
1583         case kStatus_UsbHostOhci_Idle:
1584             status = USB_HostOhciGetGtd(usbHostState, &p, 1);
1585             if (kStatus_USB_Success != status)
1586             {
1587                 OSA_ENTER_CRITICAL();
1588                 pipe->isBusy = 0;
1589                 OSA_EXIT_CRITICAL();
1590                 return status;
1591             }
1592             head                = (usb_host_ohci_general_transfer_descritpor_struct_t *)pipe->ed->TailP;
1593             head->NextTD        = (uint32_t)p;
1594             p                   = head;
1595             tr->union1.unitHead = (uint32_t)p;
1596             USB_HostOhciFillGtd(pipe, tr, p, (uint8_t *)tr->setupPacket, 8U, USB_HOST_OHCI_GTD_DP_SETUP, 0x02U, 0U);
1597             if (0U != tr->transferLength)
1598             {
1599                 tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_Setup;
1600             }
1601             else
1602             {
1603                 tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_Data;
1604             }
1605             status = kStatus_USB_Success;
1606             break;
1607         case kStatus_UsbHostOhci_Setup:
1608             status = USB_HostOhciGetGtd(usbHostState, &p, 1);
1609             if (kStatus_USB_Success != status)
1610             {
1611                 OSA_ENTER_CRITICAL();
1612                 pipe->isBusy = 0;
1613                 OSA_EXIT_CRITICAL();
1614                 return status;
1615             }
1616 
1617             head                = (usb_host_ohci_general_transfer_descritpor_struct_t *)pipe->ed->TailP;
1618             head->NextTD        = (uint32_t)p;
1619             p                   = head;
1620             tr->union1.unitHead = (uint32_t)p;
1621             dirPid              = (tr->direction == USB_OUT) ? USB_HOST_OHCI_GTD_DP_OUT : USB_HOST_OHCI_GTD_DP_IN;
1622             USB_HostOhciFillGtd(pipe, tr, p, (uint8_t *)tr->transferBuffer, tr->transferLength, dirPid, 0x03U, 1U);
1623             tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_Data;
1624             status          = kStatus_USB_Success;
1625             break;
1626         case kStatus_UsbHostOhci_Data:
1627             status = USB_HostOhciGetGtd(usbHostState, &p, 1);
1628             if (kStatus_USB_Success != status)
1629             {
1630                 OSA_ENTER_CRITICAL();
1631                 pipe->isBusy = 0;
1632                 OSA_EXIT_CRITICAL();
1633                 return status;
1634             }
1635             head                = (usb_host_ohci_general_transfer_descritpor_struct_t *)pipe->ed->TailP;
1636             head->NextTD        = (uint32_t)p;
1637             p                   = head;
1638             tr->union1.unitHead = (uint32_t)p;
1639             if (tr->setupPacket->wLength > 0u)
1640             {
1641                 statePid = (tr->direction == USB_OUT) ? USB_HOST_OHCI_GTD_DP_IN : USB_HOST_OHCI_GTD_DP_OUT;
1642             }
1643             else
1644             {
1645                 statePid = USB_HOST_OHCI_GTD_DP_IN;
1646             }
1647             USB_HostOhciFillGtd(pipe, tr, p, NULL, 0U, statePid, 0x03, 1U);
1648             tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_State;
1649             status          = kStatus_USB_Success;
1650             break;
1651         case kStatus_UsbHostOhci_State:
1652             tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_Idle;
1653             status          = kStatus_USB_Success;
1654             break;
1655         default:
1656             OSA_ENTER_CRITICAL();
1657             pipe->isBusy = 0;
1658             OSA_EXIT_CRITICAL();
1659             tr->setupStatus = (uint8_t)kStatus_UsbHostOhci_Idle;
1660             status          = kStatus_USB_Success;
1661             break;
1662     }
1663 
1664     if (0U == pipe->isBusy)
1665     {
1666         return kStatus_USB_Error;
1667     }
1668 
1669     if (NULL != p)
1670     {
1671         p->stateUnion.stateBitField.DI = 0U;
1672         p->nextGtd                     = NULL;
1673         p                              = (usb_host_ohci_general_transfer_descritpor_struct_t *)p->NextTD;
1674         p->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
1675         p->stateUnion.stateBitField.R  = 1U;
1676         p->pipe                        = pipe;
1677         temp                           = (void *)pipe;
1678         tr->transferPipe               = (usb_host_pipe_t *)temp;
1679         pipe->ed->TailP                = (uint32_t)p;
1680 
1681         usbHostState->usbRegBase->HcCommandStatus |= USB_HOST_OHCI_COMMAND_STATUS_CLF_MASK;
1682     }
1683     return status;
1684 }
1685 
USB_HostOhciLinkGtdTr(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr)1686 static usb_status_t USB_HostOhciLinkGtdTr(usb_host_ohci_state_struct_t *usbHostState,
1687                                           usb_host_ohci_pipe_struct_t *pipe,
1688                                           usb_host_transfer_t *tr)
1689 {
1690     usb_host_ohci_general_transfer_descritpor_struct_t *head;
1691     usb_host_ohci_general_transfer_descritpor_struct_t *p;
1692     uint32_t remainingLength = tr->transferLength;
1693     uint32_t tdCount         = 0U;
1694     uint32_t tdLength        = 0U;
1695     uint32_t bufferAddress   = (uint32_t)tr->transferBuffer;
1696     void *temp;
1697     usb_status_t status;
1698     uint8_t dirPid;
1699 
1700     OSA_SR_ALLOC();
1701 
1702     OSA_ENTER_CRITICAL();
1703     if (0U != pipe->isBusy)
1704     {
1705         OSA_EXIT_CRITICAL();
1706         return kStatus_USB_Success;
1707     }
1708     pipe->isBusy = 1U;
1709     pipe->isDone = 0U;
1710     OSA_EXIT_CRITICAL();
1711 
1712     while (0U != remainingLength)
1713     {
1714         tdLength = USB_HOST_OHCI_GTD_MAX_LENGTH - (bufferAddress & USB_HOST_OHCI_GTD_BUFFER_ALIGN_MASK);
1715         if (tdLength < remainingLength)
1716         {
1717             tdLength -= tdLength % pipe->pipeCommon.maxPacketSize;
1718         }
1719         else
1720         {
1721             tdLength = remainingLength;
1722         }
1723         remainingLength -= tdLength;
1724         bufferAddress += tdLength;
1725         tdCount++;
1726     }
1727 
1728     if (0U == tdCount)
1729     {
1730         tdCount = 1U;
1731     }
1732 
1733     status = USB_HostOhciGetGtd(usbHostState, &p, tdCount);
1734     if (kStatus_USB_Success != status)
1735     {
1736         OSA_ENTER_CRITICAL();
1737         pipe->isBusy = 0;
1738         OSA_EXIT_CRITICAL();
1739         return status;
1740     }
1741 
1742     head                = (usb_host_ohci_general_transfer_descritpor_struct_t *)pipe->ed->TailP;
1743     head->NextTD        = (uint32_t)p;
1744     p                   = head;
1745     tr->union1.unitHead = (uint32_t)p;
1746     dirPid              = (tr->direction == USB_OUT) ? USB_HOST_OHCI_GTD_DP_OUT : USB_HOST_OHCI_GTD_DP_IN;
1747 
1748     remainingLength = tr->transferLength;
1749     bufferAddress   = (uint32_t)tr->transferBuffer;
1750 
1751     while (0U != remainingLength)
1752     {
1753         tdLength = USB_HOST_OHCI_GTD_MAX_LENGTH - (bufferAddress & USB_HOST_OHCI_GTD_BUFFER_ALIGN_MASK);
1754         if (tdLength < remainingLength)
1755         {
1756             tdLength -= tdLength % pipe->pipeCommon.maxPacketSize;
1757         }
1758         else
1759         {
1760             tdLength = remainingLength;
1761         }
1762         remainingLength -= tdLength;
1763         if (0U != remainingLength)
1764         {
1765             USB_HostOhciFillGtd(pipe, tr, p, (uint8_t *)bufferAddress, tdLength, dirPid, 0x00U, 0U);
1766             p->nextGtd = (usb_host_ohci_general_transfer_descritpor_struct_t *)p->NextTD;
1767             p          = (usb_host_ohci_general_transfer_descritpor_struct_t *)p->NextTD;
1768         }
1769         else
1770         {
1771             USB_HostOhciFillGtd(pipe, tr, p, (uint8_t *)bufferAddress, tdLength, dirPid, 0x00U, 1U);
1772         }
1773         bufferAddress += tdLength;
1774     }
1775 
1776     if (0U == tr->transferLength)
1777     {
1778         USB_HostOhciFillGtd(pipe, tr, p, NULL, 0U, dirPid, 0x00U, 1U);
1779     }
1780     p->stateUnion.stateBitField.DI = 0U;
1781     p->nextGtd                     = NULL;
1782     p                              = (usb_host_ohci_general_transfer_descritpor_struct_t *)p->NextTD;
1783     p->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
1784     p->stateUnion.stateBitField.R  = 1U;
1785     p->pipe                        = pipe;
1786     temp                           = (void *)pipe;
1787     tr->transferPipe               = (usb_host_pipe_t *)temp;
1788     pipe->ed->TailP                = (uint32_t)p;
1789 
1790     if (USB_ENDPOINT_BULK == pipe->pipeCommon.pipeType)
1791     {
1792         usbHostState->usbRegBase->HcCommandStatus |= USB_HOST_OHCI_COMMAND_STATUS_BLF_MASK;
1793     }
1794     else
1795     {
1796     }
1797     return status;
1798 }
1799 
1800 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
USB_HostOhciFillItd(usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr,usb_host_ohci_isochronous_transfer_descritpor_struct_t * itd,uint8_t * buffer,uint32_t length,uint32_t startFrame)1801 static void USB_HostOhciFillItd(usb_host_ohci_pipe_struct_t *pipe,
1802                                 usb_host_transfer_t *tr,
1803                                 usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd,
1804                                 uint8_t *buffer,
1805                                 uint32_t length,
1806                                 uint32_t startFrame)
1807 {
1808     itd->BP0                         = ((uint32_t)buffer) & USB_HOST_OHCI_ITD_BP0_MASK;
1809     itd->BE                          = (0U != length) ? (((uint32_t)buffer) + length - 1U) : 0U;
1810     itd->stateUnion.stateBitField.SF = startFrame & USB_HOST_OHCI_FMNUMBER_FN_MASK;
1811     itd->stateUnion.stateBitField.DI = 0U;
1812     itd->stateUnion.stateBitField.FC = (length - 1U) / pipe->pipeCommon.maxPacketSize;
1813     itd->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
1814     itd->pipe                        = pipe;
1815     itd->tr                          = tr;
1816     for (uint32_t i = 0; i < 8U; i++)
1817     {
1818         itd->OffsetPSW[i] = (uint16_t)((((uint32_t)buffer + (i * pipe->pipeCommon.maxPacketSize)) & 0xFFFU) |
1819                                        ((uint32_t)USB_HOST_OHCI_CC_NOT_ACCESSED << 12U));
1820         if ((((uint32_t)buffer + (i * pipe->pipeCommon.maxPacketSize)) & USB_HOST_OHCI_ITD_BP0_MASK) != itd->BP0)
1821         {
1822             itd->OffsetPSW[i] |= (uint16_t)1UL << 11U;
1823         }
1824     }
1825     itd->length = length;
1826 }
1827 
USB_HostOhciLinkItdTr(usb_host_ohci_state_struct_t * usbHostState,usb_host_ohci_pipe_struct_t * pipe,usb_host_transfer_t * tr)1828 static usb_status_t USB_HostOhciLinkItdTr(usb_host_ohci_state_struct_t *usbHostState,
1829                                           usb_host_ohci_pipe_struct_t *pipe,
1830                                           usb_host_transfer_t *tr)
1831 {
1832     usb_host_ohci_isochronous_transfer_descritpor_struct_t *head;
1833     usb_host_ohci_isochronous_transfer_descritpor_struct_t *p;
1834     uint32_t remainingLength = tr->transferLength;
1835     uint32_t tdCount         = 0U;
1836     uint32_t tdLength        = 0U;
1837     uint32_t bufferAddress   = (uint32_t)tr->transferBuffer;
1838     uint32_t startFrame;
1839     uint32_t currentFrame;
1840     void *temp;
1841     usb_status_t status;
1842     uint8_t tansaction = 1U;
1843 
1844     if (0U == remainingLength)
1845     {
1846         return kStatus_USB_Success;
1847     }
1848 
1849     pipe->isDone = 0U;
1850 
1851     tdCount = ((remainingLength - 1U) / (pipe->pipeCommon.maxPacketSize)) + 1U;
1852     if (1U == pipe->pipeCommon.interval)
1853     {
1854         tdCount = ((tdCount - 1U) >> 3U) + 1U;
1855 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
1856 #else
1857         tdCount++;
1858 #endif
1859         tansaction = 8U;
1860     }
1861     status = USB_HostOhciGetItd(usbHostState, &p, tdCount);
1862     if (kStatus_USB_Success != status)
1863     {
1864         return status;
1865     }
1866 
1867 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
1868     head         = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)pipe->ed->TailP;
1869     head->NextTD = (uint32_t)p;
1870     p            = head;
1871 #else
1872     head = p;
1873 #endif
1874     tr->union1.unitHead = (uint32_t)p;
1875 
1876     currentFrame = s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber;
1877     startFrame   = currentFrame;
1878 
1879     while (0U != remainingLength)
1880     {
1881         tdLength = ((uint32_t)pipe->pipeCommon.maxPacketSize) * ((uint32_t)tansaction);
1882         if (tdLength > remainingLength)
1883         {
1884             tdLength = remainingLength;
1885         }
1886         USB_HostOhciFillItd(pipe, tr, p, (uint8_t *)bufferAddress, tdLength, startFrame);
1887         remainingLength -= tdLength;
1888         if (0U != remainingLength)
1889         {
1890             p->nextItd = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)p->NextTD;
1891             p          = p->nextItd;
1892             startFrame += ((uint32_t)tansaction) * ((uint32_t)pipe->pipeCommon.interval);
1893         }
1894         bufferAddress += tdLength;
1895     }
1896     p->nextItd                     = NULL;
1897     p                              = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)p->NextTD;
1898     p->stateUnion.stateBitField.CC = USB_HOST_OHCI_CC_NOT_ACCESSED;
1899     p->pipe                        = pipe;
1900     temp                           = (void *)pipe;
1901     tr->transferPipe               = (usb_host_pipe_t *)temp;
1902     pipe->ed->HeadP &= ~USB_HOST_OHCI_ED_HEADP_MASK;
1903     pipe->ed->HeadP |= (uint32_t)head;
1904     pipe->ed->TailP = (uint32_t)p;
1905 
1906     return status;
1907 }
1908 
1909 #endif
1910 
USB_HostOhciTokenDone(usb_host_ohci_state_struct_t * usbHostState)1911 static usb_status_t USB_HostOhciTokenDone(usb_host_ohci_state_struct_t *usbHostState)
1912 {
1913     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
1914     usb_host_ohci_general_transfer_descritpor_struct_t *gtdPos;
1915     usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd;
1916     usb_host_ohci_pipe_struct_t *pipe;
1917     usb_host_transfer_t *trCurrent;
1918     void *temp;
1919 
1920     /* Enter critical */
1921     USB_HostOhciLock();
1922     USB_HostOhciDisableIsr(usbHostState);
1923 
1924     gtd = (usb_host_ohci_general_transfer_descritpor_struct_t *)((uint32_t)usbHostState->tdDoneListHead);
1925     while (NULL != gtd)
1926     {
1927         if (((uint32_t)gtd) < ((uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].gtd[0]))
1928         {
1929             temp      = (void *)gtd;
1930             itd       = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)temp;
1931             trCurrent = itd->tr;
1932             pipe      = itd->pipe;
1933         }
1934         else
1935         {
1936             itd       = NULL;
1937             trCurrent = gtd->tr;
1938             pipe      = gtd->pipe;
1939         }
1940 
1941         gtdPos = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtd->NextTD;
1942         USB_HostOhciTdDoneHandle(usbHostState, pipe, trCurrent, gtd, itd);
1943         if (usbHostState->tdDoneListTail == gtd)
1944         {
1945             break;
1946         }
1947         gtd = gtdPos;
1948     }
1949     usbHostState->tdDoneListHead = NULL;
1950     usbHostState->tdDoneListTail = NULL;
1951     /* Exit critical */
1952     USB_HostOhciEnableIsr(usbHostState);
1953     USB_HostOhciUnlock();
1954     return kStatus_USB_Success;
1955 }
1956 
USB_HostOhciSof(usb_host_ohci_state_struct_t * usbHostState)1957 static usb_status_t USB_HostOhciSof(usb_host_ohci_state_struct_t *usbHostState)
1958 {
1959     usb_host_ohci_pipe_struct_t *pipe;
1960 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
1961 #else
1962     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
1963     usb_host_ohci_general_transfer_descritpor_struct_t *gtdP;
1964     usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd;
1965     uint32_t head;
1966     uint32_t tail;
1967 #endif
1968     void *temp;
1969     /* Enter critical */
1970     USB_HostOhciLock();
1971     USB_HostOhciDisableIsr(usbHostState);
1972     pipe = usbHostState->pipeListInUsing;
1973     while (NULL != pipe)
1974     {
1975         if ((USB_ENDPOINT_CONTROL == pipe->pipeCommon.pipeType) || (USB_ENDPOINT_BULK == pipe->pipeCommon.pipeType))
1976         {
1977             if (NULL != pipe->ed->trListHead)
1978             {
1979                 pipe->cutOffTime--;
1980                 if (0U == pipe->cutOffTime)
1981                 {
1982                     (void)USB_HostOhciCancelPipe(usbHostState, pipe, pipe->ed->trListHead);
1983                 }
1984             }
1985         }
1986         else
1987         {
1988 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
1989             if (USB_ENDPOINT_INTERRUPT == pipe->pipeCommon.pipeType)
1990             {
1991                 if (pipe->endpointInterval != 0U)
1992                 {
1993                     pipe->endpointInterval--;
1994                     if (pipe->endpointInterval == 0U)
1995                     {
1996                         pipe->deviceNotRespondingCount = 0U;
1997                     }
1998                 }
1999             }
2000 #endif
2001         }
2002 
2003 #if (defined(FSL_FEATURE_USBFSH_VERSION) && (FSL_FEATURE_USBFSH_VERSION >= 200U))
2004 #else
2005         tail = pipe->ed->TailP & USB_HOST_OHCI_ED_TAILP_MASK;
2006         head = pipe->ed->HeadP & USB_HOST_OHCI_ED_HEADP_MASK;
2007         if ((0U != pipe->isBusy) && (head == tail))
2008         {
2009             if ((0U != pipe->isDone) && (pipe->currentTr == pipe->ed->trListHead))
2010             {
2011                 if (pipe->startWriteBackCount != usbHostState->writeBackCount)
2012                 {
2013                     pipe->isDone = 0U;
2014                     gtd = (usb_host_ohci_general_transfer_descritpor_struct_t *)pipe->ed->trListHead->union1.unitHead;
2015                     while (NULL != gtd)
2016                     {
2017                         gtdP = (usb_host_ohci_general_transfer_descritpor_struct_t *)gtd->nextGtd;
2018                         if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
2019                         {
2020                             temp = (void *)gtd;
2021                             itd = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)temp;
2022                         }
2023                         else
2024                         {
2025                             itd = NULL;
2026                         }
2027                         /* usb_echo("Timeout pipe\r\n"); */
2028                         USB_HostOhciTdDoneHandle(usbHostState, pipe, pipe->ed->trListHead, gtd, itd);
2029                         gtd = gtdP;
2030                     }
2031                 }
2032             }
2033             else
2034             {
2035                 pipe->isDone = 1;
2036                 pipe->currentTr = pipe->ed->trListHead;
2037                 pipe->startWriteBackCount = usbHostState->writeBackCount;
2038             }
2039         }
2040         else
2041         {
2042             pipe->isDone = 0U;
2043         }
2044 #endif
2045         temp = (void *)pipe->pipeCommon.next;
2046         pipe = (usb_host_ohci_pipe_struct_t *)temp;
2047     }
2048     /* Exit critical */
2049     USB_HostOhciEnableIsr(usbHostState);
2050     USB_HostOhciUnlock();
2051 
2052     return kStatus_USB_Success;
2053 }
2054 
UBS_HostOhciControllerReset(usb_host_ohci_state_struct_t * usbHostState)2055 static usb_status_t UBS_HostOhciControllerReset(usb_host_ohci_state_struct_t *usbHostState)
2056 {
2057     usbHostState->usbRegBase->HcCommandStatus = USB_HOST_OHCI_COMMAND_STATUS_HCR_MASK;
2058     while (0U != (usbHostState->usbRegBase->HcCommandStatus & USB_HOST_OHCI_COMMAND_STATUS_HCR_MASK))
2059     {
2060         __NOP();
2061     }
2062     return kStatus_USB_Success;
2063 }
2064 
UBS_HostOhciControllerInit(usb_host_ohci_state_struct_t * usbHostState)2065 static usb_status_t UBS_HostOhciControllerInit(usb_host_ohci_state_struct_t *usbHostState)
2066 {
2067     usb_host_ohci_pipe_struct_t *pipe;
2068 #if (defined(USB_HOST_CONFIG_OHCI_MAX_GTD) && (USB_HOST_CONFIG_OHCI_MAX_GTD > 0U))
2069     usb_host_ohci_general_transfer_descritpor_struct_t *gtd;
2070 #endif
2071 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
2072     usb_host_ohci_isochronous_transfer_descritpor_struct_t *itd;
2073 #endif
2074     uint32_t i;
2075     void *temp;
2076     OSA_SR_ALLOC();
2077 
2078     /* Enter critical */
2079     OSA_ENTER_CRITICAL();
2080 
2081     for (i = 0; i < (sizeof(s_UsbHostOhciTd[usbHostState->controllerId].ed) /
2082                      sizeof(usb_host_ohci_endpoint_descritpor_struct_t));
2083          i++)
2084     {
2085         s_UsbHostOhciTd[usbHostState->controllerId].ed[i].stateUnion.stateBitField.K = 1U;
2086     }
2087 
2088     for (i = 0; i < sizeof(usb_host_ohci_hcca_struct_t); i++)
2089     {
2090         *((uint8_t *)(&s_UsbHostOhciHcca[usbHostState->controllerId]) + i) = 0x00U;
2091     }
2092 
2093     usbHostState->pipeListInUsing = NULL;
2094     usbHostState->pipeList        = &usbHostState->pipePool[0];
2095     pipe                          = usbHostState->pipeList;
2096     pipe->ed                      = &s_UsbHostOhciTd[usbHostState->controllerId].ed[3];
2097     for (i = 1; i < USB_HOST_CONFIG_OHCI_MAX_ED; i++)
2098     {
2099         temp                  = (void *)(&usbHostState->pipePool[i]);
2100         pipe->pipeCommon.next = (usb_host_pipe_t *)temp;
2101         temp                  = (void *)pipe->pipeCommon.next;
2102         pipe                  = (usb_host_ohci_pipe_struct_t *)temp;
2103         pipe->ed              = &s_UsbHostOhciTd[usbHostState->controllerId].ed[3U + i];
2104     }
2105     pipe->pipeCommon.next = NULL;
2106 
2107 #if (defined(USB_HOST_CONFIG_OHCI_MAX_GTD) && (USB_HOST_CONFIG_OHCI_MAX_GTD > 0U))
2108     usbHostState->gtdList = &s_UsbHostOhciTd[usbHostState->controllerId].gtd[0];
2109     gtd                   = usbHostState->gtdList;
2110     for (i = 1U; i < USB_HOST_CONFIG_OHCI_MAX_GTD; i++)
2111     {
2112         gtd->nextGtd = &s_UsbHostOhciTd[usbHostState->controllerId].gtd[i];
2113         gtd          = gtd->nextGtd;
2114     }
2115     gtd->nextGtd           = NULL;
2116     usbHostState->gtdCount = USB_HOST_CONFIG_OHCI_MAX_GTD;
2117 #endif
2118 
2119 #if (defined(USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
2120     usbHostState->itdList = &s_UsbHostOhciTd[usbHostState->controllerId].itd[0];
2121     itd                   = usbHostState->itdList;
2122     for (i = 1U; i < USB_HOST_CONFIG_OHCI_MAX_ITD; i++)
2123     {
2124         itd->NextTD = (uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].itd[i];
2125         itd         = (usb_host_ohci_isochronous_transfer_descritpor_struct_t *)itd->NextTD;
2126     }
2127     itd->NextTD            = 0U;
2128     usbHostState->itdCount = USB_HOST_CONFIG_OHCI_MAX_ITD;
2129 #endif
2130     usbHostState->tdDoneListTail = NULL;
2131     usbHostState->tdDoneListHead = NULL;
2132     usbHostState->writeBackCount = 0U;
2133 
2134     /* Exit critical */
2135     OSA_EXIT_CRITICAL();
2136 
2137     usbHostState->usbRegBase->HcControl = 0U;
2138     usbHostState->usbRegBase->HcControl &= ~USB_HOST_OHCI_CONTROL_HCFS_MASK;
2139     usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_HCFS(USB_HOST_OHCI_CONTROL_HCFS_OPERATIONAL);
2140     usbHostState->usbRegBase->HcFmInterval =
2141         (USB_HOST_OHCI_FMINTERVAL_FSMPS((6UL * (USB_HOST_OHCI_SOF_INTERVAL - 210UL)) / 7UL)) |
2142         (USB_HOST_OHCI_FMINTERVAL_FI(USB_HOST_OHCI_SOF_INTERVAL));
2143     usbHostState->usbRegBase->HcPeriodicStart = USB_HOST_OHCI_PERIODIC_START_PS(
2144         (uint32_t)((float)USB_HOST_OHCI_SOF_INTERVAL * (float)USB_HOST_OHCI_PERIODIC_BANDWIDTH_PERCENT));
2145     s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_CONTROL_ED_DUMMY].NextED = 0U;
2146     usbHostState->usbRegBase->HcControlHeadED =
2147         (uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_CONTROL_ED_DUMMY];
2148     s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_BULK_ED_DUMMY].NextED = 0U;
2149     usbHostState->usbRegBase->HcBulkHeadED =
2150         (uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_BULK_ED_DUMMY];
2151     s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_PERIODIC_ED_DUMMY].NextED = 0U;
2152     for (i = 0; i < USB_HOST_OHCI_HCCA_SIZE; i++)
2153     {
2154         s_UsbHostOhciHcca[usbHostState->controllerId].HccaInterrruptTable[i] =
2155             (uint32_t)&s_UsbHostOhciTd[usbHostState->controllerId].ed[USB_HOST_OHCI_PERIODIC_ED_DUMMY];
2156     }
2157     usbHostState->usbRegBase->HcHCCA = (uint32_t)&s_UsbHostOhciHcca[usbHostState->controllerId];
2158     usbHostState->usbRegBase->HcControl |= USB_HOST_OHCI_CONTROL_CBSR(USB_HOST_OHCI_CONTROL_CBSR_C1_B1);
2159     if (0U != (usbHostState->usbRegBase->HcRhDescriptorA & USB_HOST_OHCI_RHDESCRIPTORA_NPS_MASK))
2160     {
2161     }
2162     else
2163     {
2164 /* Use global power to turn on the port power for all ports */
2165 #if 0
2166         if (usbHostState->usbRegBase->HcRhDescriptorA & USB_HOST_OHCI_RHDESCRIPTORA_PSM_MASK)
2167         {
2168             usbHostState->usbRegBase->HcRhDescriptorB |= USB_HOST_OHCI_RHDESCRIPTORB_PPCM(0xFFFEUL);
2169             for (i = 0; i < (usbHostState->usbRegBase->HcRhDescriptorA & USB_HOST_OHCI_RHDESCRIPTORA_NDP_MASK); i++)
2170             {
2171                 uint32_t portStatus = usbHostState->usbRegBase->HcRhPortStatus[i];
2172                 portStatus &= ~USB_HOST_OHCI_RHPORTSTATUS_WIC;
2173                 portStatus |= USB_HOST_OHCI_RHPORTSTATUS_PPS_MASK;
2174                 usbHostState->usbRegBase->HcRhPortStatus[i] = portStatus;
2175             }
2176             usbHostState->usbRegBase->HcRhStatus = USB_HOST_OHCI_RHSTATUS_LPSC_MASK;
2177         }
2178         else
2179         {
2180             usbHostState->usbRegBase->HcRhStatus = USB_HOST_OHCI_RHSTATUS_LPSC_MASK;
2181         }
2182 #else
2183         usbHostState->usbRegBase->HcRhDescriptorB &= ~USB_HOST_OHCI_RHDESCRIPTORB_PPCM(0xFFFEUL);
2184         usbHostState->usbRegBase->HcRhStatus = USB_HOST_OHCI_RHSTATUS_LPSC_MASK;
2185 #endif
2186     }
2187     usbHostState->usbRegBase->HcInterruptDisable |= USB_HOST_OHCI_INTERRUPT_DISABLE_MASK;
2188     usbHostState->usbRegBase->HcInterruptEnable |=
2189         USB_HOST_OHCI_INTERRUPT_ENABLE_MIE_MASK | USB_HOST_OHCI_INTERRUPT_ENABLE_WDH_MASK |
2190         USB_HOST_OHCI_INTERRUPT_ENABLE_RHSC_MASK | USB_HOST_OHCI_INTERRUPT_ENABLE_SF_MASK;
2191 
2192     return kStatus_USB_Success;
2193 }
2194 
2195 /*!
2196  * @brief create the USB host ohci instance.
2197  *
2198  * This function initializes the USB host ohci controller driver.
2199  *
2200  * @param controllerId        The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
2201  * @param hostHandle         The host level handle.
2202  * @param controllerHandle  Return the controller instance handle.
2203  *
2204  * @retval kStatus_USB_Success              The host is initialized successfully.
2205  * @retval kStatus_USB_AllocFail             allocate memory fail.
2206  * @retval kStatus_USB_Error                 host mutex create fail, OHCI mutex or OHCI event create fail.
2207  *                                                         Or, OHCI IP initialize fail.
2208  */
USB_HostOhciCreate(uint8_t controllerId,usb_host_handle hostHandle,usb_host_controller_handle * controllerHandle)2209 usb_status_t USB_HostOhciCreate(uint8_t controllerId,
2210                                 usb_host_handle hostHandle,
2211                                 usb_host_controller_handle *controllerHandle)
2212 {
2213     usb_host_ohci_state_struct_t *usbHostState;
2214     usb_status_t status       = kStatus_USB_Success;
2215     uint32_t usb_base_addrs[] = USBFSH_BASE_ADDRS;
2216     IRQn_Type usb_irq[]       = USBFSH_IRQS;
2217 
2218     if (((controllerId - (uint8_t)kUSB_ControllerOhci0) >= (uint8_t)USB_HOST_CONFIG_OHCI) ||
2219         ((controllerId - (uint8_t)kUSB_ControllerOhci0) >= (sizeof(usb_base_addrs) / sizeof(uint32_t))))
2220     {
2221         return kStatus_USB_ControllerNotFound;
2222     }
2223     usbHostState = &s_UsbHostOhciState[controllerId - (uint8_t)kUSB_ControllerOhci0];
2224     /* Allocate the USB Host Pipe Descriptors */
2225     usbHostState->hostHandle   = hostHandle;
2226     usbHostState->controllerId = controllerId - (uint8_t)kUSB_ControllerOhci0;
2227 
2228     usbHostState->usbRegBase = (usb_host_ohci_hcor_struct_t *)usb_base_addrs[usbHostState->controllerId];
2229     usbHostState->isrNumber  = (uint8_t)usb_irq[usbHostState->controllerId];
2230     usbHostState->ohciEvent  = (osa_event_handle_t)&usbHostState->taskEventHandleBuffer[0];
2231     if (KOSA_StatusSuccess != OSA_EventCreate(usbHostState->ohciEvent, 1U))
2232     {
2233         usbHostState->ohciEvent = NULL;
2234 #ifdef HOST_ECHO
2235         usb_echo(" event create failed in USB_HostOhciCreate\n");
2236 #endif
2237         return kStatus_USB_AllocFail;
2238     } /* Endif */
2239     usbHostState->mutex = (osa_mutex_handle_t)(&usbHostState->mutexBuffer[0]);
2240     if (KOSA_StatusSuccess != OSA_MutexCreate(usbHostState->mutex))
2241     {
2242         usbHostState->mutex = NULL;
2243         (void)USB_HostOhciDestory(usbHostState);
2244 #ifdef HOST_ECHO
2245         usb_echo("USB_HostOhciCreate: create host mutex fail\r\n");
2246 #endif
2247         return kStatus_USB_AllocFail;
2248     }
2249 
2250     /* enable Host clock, OTG clock and AHB clock */
2251     usbHostState->usbRegBase->PortMode &= ~USB_HOST_OHCI_PORTMODE_DEV_ENABLE_MASK;
2252     usbHostState->portNumber =
2253         (uint8_t)(usbHostState->usbRegBase->HcRhDescriptorA & USB_HOST_OHCI_RHDESCRIPTORA_NDP_MASK);
2254     if (0U == usbHostState->portNumber)
2255     {
2256 #ifdef HOST_ECHO
2257         usb_echo(" Port number is invalid in USB_HostOhciCreate\n");
2258 #endif
2259         (void)USB_HostOhciDestory(usbHostState);
2260         return kStatus_USB_Error;
2261     }
2262 
2263     usbHostState->portState = (usb_host_ohci_port_state_struct_t *)OSA_MemoryAllocate(
2264         (uint32_t)sizeof(usb_host_ohci_port_state_struct_t) *
2265         ((uint32_t)usbHostState->portNumber)); /* malloc host ohci port state */
2266     if (NULL == usbHostState->portState)
2267     {
2268         (void)USB_HostOhciDestory(usbHostState);
2269 #ifdef HOST_ECHO
2270         usb_echo("USB_HostOhciCreate: mem alloc fail\r\n");
2271 #endif
2272         return kStatus_USB_Error;
2273     }
2274 
2275     (void)UBS_HostOhciControllerReset(usbHostState);
2276 
2277     (void)UBS_HostOhciControllerInit(usbHostState);
2278 
2279     *controllerHandle = (usb_host_handle)usbHostState;
2280     return status;
2281 }
2282 
2283 /*!
2284  * @brief destroy USB host ohci instance.
2285  *
2286  * This function de-initialize the USB host ohci controller driver.
2287  *
2288  * @param handle                                    the controller handle.
2289  *
2290  * @retval kStatus_USB_Success              The host is initialized successfully.
2291  */
USB_HostOhciDestory(usb_host_controller_handle controllerHandle)2292 usb_status_t USB_HostOhciDestory(usb_host_controller_handle controllerHandle)
2293 {
2294     usb_host_ohci_state_struct_t *usbHostState = (usb_host_ohci_state_struct_t *)controllerHandle;
2295 
2296     usbHostState->usbRegBase->HcInterruptDisable |= USB_HOST_OHCI_INTERRUPT_DISABLE_MASK;
2297     usbHostState->usbRegBase->HcRhStatus |= USB_HOST_OHCI_RHSTATUS_LPS_MASK;
2298     usbHostState->usbRegBase->HcControl = 0U;
2299 
2300     if (NULL != usbHostState->portState)
2301     {
2302         (void)OSA_MemoryFree(usbHostState->portState);
2303         usbHostState->portState = NULL;
2304     }
2305 
2306     if (NULL != usbHostState->mutex)
2307     {
2308         (void)OSA_MutexDestroy(usbHostState->mutex);
2309         usbHostState->mutex = NULL;
2310     }
2311 
2312     if (NULL != usbHostState->ohciEvent)
2313     {
2314         (void)OSA_EventDestroy(usbHostState->ohciEvent);
2315         usbHostState->ohciEvent = NULL;
2316     }
2317 
2318     return kStatus_USB_Success;
2319 }
2320 
USB_HostOhciOpenPipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle * pipeHandle,usb_host_pipe_init_t * pipeInit)2321 usb_status_t USB_HostOhciOpenPipe(usb_host_controller_handle controllerHandle,
2322                                   usb_host_pipe_handle *pipeHandle,
2323                                   usb_host_pipe_init_t *pipeInit)
2324 {
2325     usb_host_ohci_pipe_struct_t *pipe = NULL;
2326     usb_status_t status;
2327     usb_host_ohci_state_struct_t *usbHostState = (usb_host_ohci_state_struct_t *)controllerHandle;
2328 
2329     status = USB_HostOhciGetPipe(&usbHostState->pipeList, &pipe);
2330 
2331     if ((kStatus_USB_Success != status) || (NULL == pipe))
2332     {
2333 #ifdef HOST_ECHO
2334         usb_echo("ohci open pipe failed\r\n");
2335 #endif
2336         return kStatus_USB_Busy;
2337     }
2338 
2339     /* initialize pipe informations */
2340     pipe->pipeCommon.deviceHandle         = pipeInit->devInstance;
2341     pipe->pipeCommon.endpointAddress      = pipeInit->endpointAddress;
2342     pipe->pipeCommon.direction            = pipeInit->direction;
2343     pipe->pipeCommon.interval             = pipeInit->interval;
2344     pipe->pipeCommon.maxPacketSize        = pipeInit->maxPacketSize;
2345     pipe->pipeCommon.pipeType             = pipeInit->pipeType;
2346     pipe->pipeCommon.numberPerUframe      = 1U;
2347     pipe->pipeCommon.nakCount             = pipeInit->nakCount;
2348     pipe->pipeCommon.nextdata01           = 0U;
2349     pipe->pipeCommon.currentCount         = 0U;
2350     pipe->pipeCommon.open                 = 1U;
2351     pipe->ed->stateUnion.stateBitField.EN = pipeInit->endpointAddress;
2352     pipe->ed->stateUnion.stateBitField.D  = (USB_OUT == pipeInit->direction) ? 1U : 2U;
2353     pipe->ed->stateUnion.stateBitField.FA = ((usb_host_device_instance_t *)pipeInit->devInstance)->setAddress;
2354     pipe->ed->stateUnion.stateBitField.S =
2355         (USB_SPEED_FULL == ((usb_host_device_instance_t *)pipeInit->devInstance)->speed) ? 0U : 1U;
2356     pipe->ed->stateUnion.stateBitField.F   = 0U;
2357     pipe->ed->stateUnion.stateBitField.MPS = pipeInit->maxPacketSize;
2358     pipe->ed->stateUnion.stateBitField.K   = 0U;
2359     pipe->ed->TailP                        = 0U;
2360     pipe->ed->HeadP                        = 0U;
2361     pipe->ed->pipe                         = pipe;
2362     pipe->ed->NextED                       = 0U;
2363     pipe->ed->trListHead                   = NULL;
2364     pipe->ed->trListTail                   = NULL;
2365     pipe->ed->dealTr                       = NULL;
2366     pipe->cutOffTime                       = USB_HOST_OHCI_TRANSFER_TIMEOUT_GAP;
2367     pipe->isCanceling                      = 0U;
2368 #if (defined(USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND) && (USB_HOST_OHCI_DEVICE_NOT_RESPONDING_WORKAROUND))
2369     pipe->deviceNotRespondingCount = 0U;
2370     pipe->endpointInterval         = 0U;
2371 #endif
2372 
2373     if (USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType)
2374     {
2375         pipe->ed->stateUnion.stateBitField.F = 1U;
2376 
2377 #if 0
2378         pipe->pipeCommon.interval =
2379             (1 << (pipe->pipeCommon.interval - 1)); /* iso interval is the power of 2 */
2380         if (pipe->pipeCommon.interval > USB_HOST_OHCI_HCCA_SIZE)
2381         {
2382             pipe->pipeCommon.interval = USB_HOST_OHCI_HCCA_SIZE;
2383         }
2384 #else
2385         pipe->pipeCommon.interval = 1U;
2386 #endif
2387     }
2388     else if (USB_ENDPOINT_INTERRUPT == pipe->pipeCommon.pipeType)
2389     {
2390         uint32_t interval = 0U;
2391         /* FS/LS interrupt interval should be the power of 2, it is used for ohci bandwidth */
2392         for (uint32_t p = 0U; p < 16U; p++)
2393         {
2394             if (0U != (pipe->pipeCommon.interval & ((uint16_t)(1UL << p))))
2395             {
2396                 if (p > interval)
2397                 {
2398                     interval = p;
2399                 }
2400             }
2401         }
2402         pipe->pipeCommon.interval = (uint16_t)(1UL << interval);
2403         if (pipe->pipeCommon.interval > USB_HOST_OHCI_HCCA_SIZE)
2404         {
2405             pipe->pipeCommon.interval = USB_HOST_OHCI_HCCA_SIZE;
2406         }
2407     }
2408     else
2409     {
2410     }
2411 
2412     /* open pipe */
2413     switch (pipe->pipeCommon.pipeType)
2414     {
2415         case USB_ENDPOINT_CONTROL:
2416             pipe->ed->stateUnion.stateBitField.D = 0;
2417             status                               = USB_HostOhciOpenControlBulkPipe(usbHostState, pipe);
2418             break;
2419         case USB_ENDPOINT_BULK:
2420             status = USB_HostOhciOpenControlBulkPipe(usbHostState, pipe);
2421             break;
2422 
2423 #if ((defined(USB_HOST_CONFIG_OHCI_MAX_ITD)) && (USB_HOST_CONFIG_OHCI_MAX_ITD > 0U))
2424         case USB_ENDPOINT_ISOCHRONOUS:
2425             status = USB_HostOhciOpenIsoPipe(usbHostState, pipe);
2426             break;
2427 #endif
2428         case USB_ENDPOINT_INTERRUPT:
2429             status = USB_HostOhciOpenInterruptPipe(usbHostState, pipe);
2430             break;
2431 
2432         default:
2433             status = kStatus_USB_Error;
2434             break;
2435     }
2436 
2437     if (status != kStatus_USB_Success)
2438     {
2439         pipe->ed->stateUnion.stateBitField.K = 1U;
2440         pipe->pipeCommon.open                = 0U;
2441         /* release the pipe */
2442         (void)USB_HostOhciInsertPipe(&usbHostState->pipeList, pipe);
2443         return status;
2444     }
2445 
2446     (void)USB_HostOhciInsertPipe(&usbHostState->pipeListInUsing, pipe);
2447 
2448     *pipeHandle = pipe;
2449     return status;
2450 }
2451 
USB_HostOhciClosePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle)2452 usb_status_t USB_HostOhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
2453 {
2454     usb_host_ohci_state_struct_t *usbHostState = (usb_host_ohci_state_struct_t *)controllerHandle;
2455     usb_host_ohci_pipe_struct_t *pipe          = (usb_host_ohci_pipe_struct_t *)pipeHandle;
2456 
2457     switch (pipe->pipeCommon.pipeType)
2458     {
2459         case USB_ENDPOINT_BULK:
2460         case USB_ENDPOINT_CONTROL:
2461             (void)USB_HostOhciCloseControlBulkPipe(usbHostState, pipe);
2462             break;
2463 
2464 #if ((defined USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD))
2465         case USB_ENDPOINT_ISOCHRONOUS:
2466 #endif
2467         case USB_ENDPOINT_INTERRUPT:
2468             (void)USB_HostOhciCloseIsoInterruptPipe(usbHostState, pipe);
2469             break;
2470 
2471         default:
2472             /*no action */
2473             break;
2474     }
2475     (void)USB_HostOhciRemovePipe(&usbHostState->pipeListInUsing, pipe);
2476     pipe->pipeCommon.open = 0U;
2477     (void)USB_HostOhciInsertPipe(&usbHostState->pipeList, pipe);
2478 
2479     return kStatus_USB_Success;
2480 }
2481 
USB_HostOhciWritePipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)2482 usb_status_t USB_HostOhciWritePipe(usb_host_controller_handle controllerHandle,
2483                                    usb_host_pipe_handle pipeHandle,
2484                                    usb_host_transfer_t *transfer)
2485 {
2486     usb_host_ohci_state_struct_t *usbHostState = (usb_host_ohci_state_struct_t *)controllerHandle;
2487     usb_host_ohci_pipe_struct_t *pipe          = (usb_host_ohci_pipe_struct_t *)pipeHandle;
2488     usb_status_t status                        = kStatus_USB_Error;
2489     transfer->setupStatus                      = (uint8_t)kStatus_UsbHostOhci_Idle;
2490     transfer->union2.frame                     = 0U;
2491     OSA_SR_ALLOC();
2492 
2493     OSA_ENTER_CRITICAL();
2494     if (NULL != pipe->ed->trListHead)
2495     {
2496         pipe->ed->trListTail->next = transfer;
2497     }
2498     else
2499     {
2500         pipe->ed->trListHead = transfer;
2501     }
2502     pipe->ed->trListTail = transfer;
2503     transfer->next       = NULL;
2504     OSA_EXIT_CRITICAL();
2505 
2506     switch (pipe->pipeCommon.pipeType)
2507     {
2508         case USB_ENDPOINT_CONTROL:
2509             if (0U != usbHostState->controlIsBusy)
2510             {
2511                 status = kStatus_USB_Success;
2512             }
2513             else
2514             {
2515                 status = USB_HostOhciLinkGtdControlTr(usbHostState, pipe, transfer);
2516 
2517                 if (kStatus_USB_Success == status)
2518                 {
2519                     usbHostState->controlIsBusy = 1U;
2520                 }
2521             }
2522             break;
2523         case USB_ENDPOINT_BULK:
2524         case USB_ENDPOINT_INTERRUPT:
2525             /* initialize gtd for control/bulk/interrupt transfer */
2526             status = USB_HostOhciLinkGtdTr(usbHostState, pipe, transfer);
2527             break;
2528 #if ((defined USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD))
2529         case USB_ENDPOINT_ISOCHRONOUS:
2530             /* initialize itd for iso transfer */
2531             /* status = USB_HostOhciLinkItdTr(usbHostState, pipe, transfer); */
2532             if (0U != transfer->transferLength)
2533             {
2534                 status = kStatus_USB_Success;
2535                 OSA_ENTER_CRITICAL();
2536                 if (NULL == pipe->ed->dealTr)
2537                 {
2538                     if (NULL != pipe->ed->trListHead)
2539                     {
2540                         pipe->ed->dealTr = pipe->ed->trListHead;
2541                     }
2542                     else
2543                     {
2544                         pipe->ed->dealTr = transfer;
2545                     }
2546                 }
2547                 OSA_EXIT_CRITICAL();
2548             }
2549             else
2550             {
2551                 status = kStatus_USB_InvalidParameter;
2552             }
2553             break;
2554 #endif
2555         default:
2556             /*no action*/
2557             break;
2558     }
2559 
2560     if (kStatus_USB_Success != status)
2561     {
2562         usb_host_transfer_t *trP = pipe->ed->trListHead;
2563         usb_host_transfer_t *trQ = NULL;
2564         OSA_ENTER_CRITICAL();
2565 
2566         while (NULL != trP)
2567         {
2568             if (trP == transfer)
2569             {
2570                 if (NULL == trQ)
2571                 {
2572                     pipe->ed->trListHead = trP->next;
2573                 }
2574                 else
2575                 {
2576                     trQ->next = trP->next;
2577                 }
2578                 if (pipe->ed->trListTail == transfer)
2579                 {
2580                     pipe->ed->trListTail = trQ;
2581                 }
2582             }
2583             trQ = trP;
2584             trP = trP->next;
2585         }
2586         OSA_EXIT_CRITICAL();
2587     }
2588     return status;
2589 }
2590 
USB_HostOhciReadPipe(usb_host_controller_handle controllerHandle,usb_host_pipe_handle pipeHandle,usb_host_transfer_t * transfer)2591 usb_status_t USB_HostOhciReadPipe(usb_host_controller_handle controllerHandle,
2592                                   usb_host_pipe_handle pipeHandle,
2593                                   usb_host_transfer_t *transfer)
2594 {
2595     return USB_HostOhciWritePipe(controllerHandle, pipeHandle, transfer);
2596 }
2597 
USB_HostOhciIoctl(usb_host_controller_handle controllerHandle,uint32_t ioctlEvent,void * ioctlParam)2598 usb_status_t USB_HostOhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
2599 {
2600     usb_host_ohci_state_struct_t *usbHostState = (usb_host_ohci_state_struct_t *)controllerHandle;
2601     usb_host_cancel_param_t *param;
2602     usb_host_ohci_pipe_struct_t *pipe;
2603     uint32_t deviceAddress;
2604     usb_status_t status = kStatus_USB_Success;
2605     usb_host_controller_control_t ioctl;
2606     if (controllerHandle == NULL)
2607     {
2608         return kStatus_USB_InvalidHandle;
2609     }
2610     deviceAddress = 0U;
2611     ioctl         = (usb_host_controller_control_t)ioctlEvent;
2612     switch (ioctl)
2613     {
2614         case kUSB_HostCancelTransfer:
2615             /* cancel pipe or one transfer */
2616             param = (usb_host_cancel_param_t *)ioctlParam;
2617             status =
2618                 USB_HostOhciCancelPipe(usbHostState, (usb_host_ohci_pipe_struct_t *)param->pipeHandle, param->transfer);
2619             break;
2620 
2621         case kUSB_HostBusControl:
2622             /* bus control */
2623             status = USB_HostOhciControlBus(usbHostState, *((uint8_t *)ioctlParam));
2624             break;
2625 
2626         case kUSB_HostGetFrameNumber:
2627             /* get frame number */
2628             *((uint32_t *)ioctlParam) = (s_UsbHostOhciHcca[usbHostState->controllerId].HccaFrameNumber);
2629             break;
2630 
2631         case kUSB_HostUpdateControlEndpointAddress:
2632             pipe                                 = (usb_host_ohci_pipe_struct_t *)ioctlParam;
2633             pipe->ed->stateUnion.stateBitField.K = 1U;
2634             /* update address */
2635             (void)USB_HostHelperGetPeripheralInformation(pipe->pipeCommon.deviceHandle,
2636                                                          (uint32_t)kUSB_HostGetDeviceAddress, &deviceAddress);
2637             pipe->ed->stateUnion.stateBitField.FA = deviceAddress;
2638             pipe->ed->stateUnion.stateBitField.K  = 0U;
2639             USB_HostOhciDelay(usbHostState, 2U);
2640             break;
2641 
2642         case kUSB_HostUpdateControlPacketSize:
2643             pipe                                   = (usb_host_ohci_pipe_struct_t *)ioctlParam;
2644             pipe->ed->stateUnion.stateBitField.K   = 1U;
2645             pipe->ed->stateUnion.stateBitField.MPS = pipe->pipeCommon.maxPacketSize;
2646             pipe->ed->stateUnion.stateBitField.K   = 0U;
2647             break;
2648 
2649         case kUSB_HostPortAttachDisable:
2650             break;
2651 
2652         case kUSB_HostPortAttachEnable:
2653             break;
2654 
2655         default:
2656             status = kStatus_USB_NotSupported;
2657             break;
2658     }
2659     return status;
2660 }
2661 
USB_HostOhciTaskFunction(void * hostHandle)2662 void USB_HostOhciTaskFunction(void *hostHandle)
2663 {
2664     usb_host_ohci_state_struct_t *usbHostState;
2665     uint32_t bitSet;
2666 
2667     if (NULL == hostHandle)
2668     {
2669         return;
2670     }
2671     usbHostState = (usb_host_ohci_state_struct_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
2672 
2673     /* wait all event */
2674     if (KOSA_StatusSuccess == OSA_EventWait(usbHostState->ohciEvent, 0xFFU, 0, USB_OSA_WAIT_TIMEOUT, &bitSet))
2675     {
2676         if (0U != (bitSet & USB_HOST_OHCI_EVENT_PORT_CHANGE))
2677         {
2678             (void)USB_HostOhciPortChange(usbHostState);
2679         }
2680         if (0U != (bitSet & USB_HOST_OHCI_EVENT_TOKEN_DONE))
2681         {
2682             (void)USB_HostOhciTokenDone(usbHostState);
2683         }
2684         if (0U != (bitSet & USB_HOST_OHCI_EVENT_SOF))
2685         {
2686             (void)USB_HostOhciSof(usbHostState);
2687         }
2688         if (0U != (bitSet & USB_HOST_OHCI_EVENT_ATTACH))
2689         {
2690             for (uint8_t i = 0; i < usbHostState->portNumber; i++)
2691             {
2692                 if ((uint8_t)kUSB_DeviceOhciPortPhyAttached == usbHostState->portState[i].portStatus)
2693                 {
2694                     void *deviceHandle;
2695                     if (kStatus_USB_Success == USB_HostAttachDevice(usbHostState->hostHandle,
2696                                                                     usbHostState->portState[i].portSpeed, 0U, i, 1U,
2697                                                                     &deviceHandle))
2698                     {
2699                         usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceOhciPortAttached;
2700                     }
2701                 }
2702             }
2703         }
2704         if (0U != (bitSet & USB_HOST_OHCI_EVENT_DETACH))
2705         {
2706             for (uint8_t i = 0; i < usbHostState->portNumber; i++)
2707             {
2708                 if ((uint8_t)kUSB_DeviceOhciPortPhyDetached == usbHostState->portState[i].portStatus)
2709                 {
2710                     usbHostState->portState[i].portStatus = (uint8_t)kUSB_DeviceOhciPortDetached;
2711                     (void)USB_HostDetachDevice(usbHostState->hostHandle, 0U, i);
2712                 }
2713             }
2714         }
2715     }
2716 }
2717 
USB_HostOhciIsrFunction(void * hostHandle)2718 void USB_HostOhciIsrFunction(void *hostHandle)
2719 {
2720     usb_host_ohci_state_struct_t *usbHostState;
2721     static uint32_t interruptStatus = 0U;
2722     static uint32_t sofCount        = 0U;
2723 
2724     if (hostHandle == NULL)
2725     {
2726         return;
2727     }
2728 
2729     usbHostState = (usb_host_ohci_state_struct_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
2730 
2731     interruptStatus = usbHostState->usbRegBase->HcInterruptStatus;
2732     interruptStatus &= usbHostState->usbRegBase->HcInterruptEnable;
2733 
2734     if (0U != (interruptStatus & USB_HOST_OHCI_INTERRUPT_STATUS_WDH_MASK)) /* Write back done head */
2735     {
2736         USB_HostOhciLinkTdToDoneList(usbHostState);
2737         (void)OSA_EventSet(usbHostState->ohciEvent, USB_HOST_OHCI_EVENT_TOKEN_DONE);
2738     }
2739 
2740     if (0U != (interruptStatus & USB_HOST_OHCI_INTERRUPT_STATUS_SF_MASK)) /* SOF interrupt */
2741     {
2742 #if ((defined USB_HOST_CONFIG_OHCI_MAX_ITD) && (USB_HOST_CONFIG_OHCI_MAX_ITD))
2743         usb_host_ohci_pipe_struct_t *pipe;
2744         void *temp;
2745         temp = (void *)usbHostState->pipeListInUsing;
2746         while (NULL != temp)
2747         {
2748             pipe = (usb_host_ohci_pipe_struct_t *)temp;
2749             temp = (void *)pipe->pipeCommon.next;
2750             if ((USB_ENDPOINT_ISOCHRONOUS == pipe->pipeCommon.pipeType) && (NULL != pipe->ed->trListHead))
2751             {
2752                 if ((NULL != pipe->ed->dealTr))
2753                 {
2754                     uint32_t tail = pipe->ed->TailP & USB_HOST_OHCI_ED_TAILP_MASK;
2755                     uint32_t head = pipe->ed->HeadP & USB_HOST_OHCI_ED_HEADP_MASK;
2756                     if (head == tail)
2757                     {
2758                         if (kStatus_USB_Success == USB_HostOhciLinkItdTr(usbHostState, pipe, pipe->ed->dealTr))
2759                         {
2760                             pipe->ed->dealTr = pipe->ed->dealTr->next;
2761                         }
2762                         else
2763                         {
2764                             /*no action*/
2765                         }
2766                     }
2767                 }
2768                 pipe->isDone = 0U;
2769             }
2770         }
2771 #endif
2772         sofCount++;
2773         if (sofCount >= USB_HOST_OHCI_TRANSFER_SCAN_INTERVAL)
2774         {
2775             sofCount = 0U;
2776             (void)OSA_EventSet(usbHostState->ohciEvent, USB_HOST_OHCI_EVENT_SOF);
2777         }
2778     }
2779 
2780     if (0U != (interruptStatus & USB_HOST_OHCI_INTERRUPT_STATUS_RHSC_MASK)) /* port change detect interrupt */
2781     {
2782         (void)OSA_EventSet(usbHostState->ohciEvent, USB_HOST_OHCI_EVENT_PORT_CHANGE);
2783     }
2784 
2785     usbHostState->usbRegBase->HcInterruptStatus = interruptStatus; /* clear interrupt */
2786 }
2787 
2788 #endif
2789