1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** USBX Component                                                        */
17 /**                                                                       */
18 /**   EHCI Controller Driver                                              */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /* Include necessary system files.  */
25 
26 #define UX_SOURCE_CODE
27 
28 #include "ux_api.h"
29 #include "ux_hcd_ehci.h"
30 #include "ux_host_stack.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_hcd_ehci_done_queue_process                     PORTABLE C      */
38 /*                                                           6.1.11       */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Chaoqiong Xiao, Microsoft Corporation                               */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function process the isochronous, periodic and asynchronous    */
46 /*    lists in search for transfers that occurred in the past             */
47 /*    (micro-)frame.                                                      */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    hcd_ehci                              Pointer to EHCI controller    */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    None                                                                */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    _ux_hcd_ehci_asynch_td_process        Process asynch TD             */
60 /*    _ux_hcd_ehci_hsisochronous_tds_process                              */
61 /*                                          Process high speed            */
62 /*                                          isochronous TDs               */
63 /*    _ux_hcd_ehci_fsisochronous_tds_process                              */
64 /*                                          Process full speed (split)    */
65 /*                                          isochronous TDs               */
66 /*    _ux_utility_virtual_address           Get virtual address           */
67 /*                                                                        */
68 /*  CALLED BY                                                             */
69 /*                                                                        */
70 /*    EHCI Controller Driver                                              */
71 /*                                                                        */
72 /*  RELEASE HISTORY                                                       */
73 /*                                                                        */
74 /*    DATE              NAME                      DESCRIPTION             */
75 /*                                                                        */
76 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
77 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
78 /*                                            resulting in version 6.1    */
79 /*  11-09-2020     Chaoqiong Xiao           Modified comment(s),          */
80 /*                                            fixed compile warning,      */
81 /*                                            resulting in version 6.1.2  */
82 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
83 /*                                            fixed standalone compile,   */
84 /*                                            resulting in version 6.1.11 */
85 /*                                                                        */
86 /**************************************************************************/
_ux_hcd_ehci_done_queue_process(UX_HCD_EHCI * hcd_ehci)87 VOID  _ux_hcd_ehci_done_queue_process(UX_HCD_EHCI *hcd_ehci)
88 {
89 
90 UX_EHCI_TD                      *td;
91 UX_EHCI_PERIODIC_LINK_POINTER   ed;
92 UX_EHCI_ED                      *start_ed;
93 
94 
95 #if UX_MAX_ISO_TD
96 UX_EHCI_PERIODIC_LINK_POINTER   lp;
97 
98     /* We scan the active isochronous list first.  */
99     _ux_host_mutex_on(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
100     lp.itd_ptr = hcd_ehci -> ux_hcd_ehci_hsiso_scan_list;
101     while(lp.itd_ptr != UX_NULL)
102     {
103 
104         /* Process the iTD, return next active TD.  */
105         lp.itd_ptr = _ux_hcd_ehci_hsisochronous_tds_process(hcd_ehci, lp.itd_ptr);
106     }
107     _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
108 
109 #if defined(UX_HCD_EHCI_SPLIT_TRANSFER_ENABLE)
110 
111     /* We scan the split isochronous list then.  */
112     _ux_host_mutex_on(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
113     lp.sitd_ptr = hcd_ehci -> ux_hcd_ehci_fsiso_scan_list;
114     while(lp.sitd_ptr != UX_NULL)
115     {
116 
117         /* Process the iTD, return next active TD.  */
118         lp.sitd_ptr = _ux_hcd_ehci_fsisochronous_tds_process(hcd_ehci, lp.sitd_ptr);
119     }
120     _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
121 
122 #endif
123 #endif
124 
125     /* We scan the linked interrupt list then.  */
126     _ux_host_mutex_on(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
127     ed.ed_ptr = hcd_ehci -> ux_hcd_ehci_interrupt_ed_list;
128     while(ed.ed_ptr != UX_NULL)
129     {
130 
131         /* Retrieve the fist TD attached to this ED.  */
132         td =  ed.ed_ptr -> ux_ehci_ed_first_td;
133 
134         /* Process TD until there is no next available.  */
135         while (td != UX_NULL)
136             td =  _ux_hcd_ehci_asynch_td_process(ed.ed_ptr, td);
137 
138         /* Next ED.  */
139         ed.ed_ptr = ed.ed_ptr -> ux_ehci_ed_next_ed;
140     }
141     _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
142 
143     /* Now we can parse the asynchronous list. The head ED is always empty and
144        used as an anchor only.  */
145     start_ed =  hcd_ehci -> ux_hcd_ehci_asynch_head_list;
146 
147     /* Point to the next ED in the asynchronous tree.  */
148     ed.ed_ptr = start_ed -> ux_ehci_ed_queue_head;
149     ed.value &= UX_EHCI_LINK_ADDRESS_MASK;
150 
151     /* Obtain the virtual address from the element.  */
152     ed.void_ptr = _ux_utility_virtual_address(ed.void_ptr);
153 
154     /* Now traverse this list until we have found a non anchor endpoint that
155        has transfers done.  */
156     while (ed.ed_ptr != start_ed)
157     {
158 
159         /* Retrieve the fist TD attached to this ED.  */
160         td =  ed.ed_ptr -> ux_ehci_ed_first_td;
161         while (td != UX_NULL)
162         {
163 
164             td =  _ux_hcd_ehci_asynch_td_process(ed.ed_ptr, td);
165         }
166 
167         /* Point to the next ED in the asynchronous tree.  */
168         ed.ed_ptr = ed.ed_ptr -> ux_ehci_ed_queue_head;
169         ed.value &= UX_EHCI_LINK_ADDRESS_MASK;
170 
171         /* Obtain the virtual address from the element.  */
172         ed.void_ptr = _ux_utility_virtual_address(ed.void_ptr);
173     }
174 }
175 
176