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_request_isochronous_transfer PORTABLE C */
38 /* 6.1.12 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function performs an isochronous transfer request (list). */
46 /* */
47 /* Note: the request max length is endpoint max packet size, multiple */
48 /* endpoint max number of transactions. */
49 /* */
50 /* INPUT */
51 /* */
52 /* hcd_ehci Pointer to EHCI controller */
53 /* transfer_request Pointer to transfer request. */
54 /* If next transfer request is */
55 /* valid the whole request list */
56 /* is added, until next transfer */
57 /* request being NULL. If next */
58 /* next transfer request is not */
59 /* valid (being NULL) single */
60 /* transfer request is added. */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* Completion Status */
65 /* */
66 /* CALLS */
67 /* */
68 /* _ux_host_mutex_on Get mutex */
69 /* _ux_host_mutex_off Put mutex */
70 /* _ux_host_semaphore_put Put semaphore */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* EHCI Controller Driver */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
81 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
82 /* resulting in version 6.1 */
83 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
84 /* refined macros names, */
85 /* resulting in version 6.1.10 */
86 /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
87 /* fixed standalone compile, */
88 /* resulting in version 6.1.11 */
89 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
90 /* improved iso start up, */
91 /* resulting in version 6.1.12 */
92 /* */
93 /**************************************************************************/
_ux_hcd_ehci_request_isochronous_transfer(UX_HCD_EHCI * hcd_ehci,UX_TRANSFER * transfer_request)94 UINT _ux_hcd_ehci_request_isochronous_transfer(UX_HCD_EHCI *hcd_ehci, UX_TRANSFER *transfer_request)
95 {
96 #if UX_MAX_ISO_TD == 0
97
98 UX_PARAMETER_NOT_USED(hcd_ehci);
99 UX_PARAMETER_NOT_USED(transfer_request);
100
101 /* If trace is enabled, insert this event into the trace buffer. */
102 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
103
104 /* Not supported yet - return error. */
105 return(UX_FUNCTION_NOT_SUPPORTED);
106 #else
107
108 UX_ENDPOINT *endpoint;
109 UX_EHCI_PERIODIC_LINK_POINTER lp;
110 UX_EHCI_HSISO_ED *ied;
111 UX_TRANSFER **head;
112 UX_TRANSFER **tail;
113 UX_TRANSFER **first_new;
114 UX_TRANSFER *request_list;
115 UCHAR start = UX_FALSE;
116
117
118 /* Get the pointer to the endpoint. */
119 endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
120
121 /* Now get the physical iTD/siTD attached to this endpoint. */
122 lp.ed_ptr = endpoint -> ux_endpoint_ed;
123
124 /* Lock the periodic list to update. */
125 _ux_host_mutex_on(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
126
127 /* Append the request to iTD/siTD request list tail. */
128 #if defined(UX_HCD_EHCI_SPLIT_TRANSFER_ENABLE)
129 if (endpoint -> ux_endpoint_device -> ux_device_speed != UX_HIGH_SPEED_DEVICE)
130 head = &lp.sitd_ptr -> ux_ehci_fsiso_td_transfer_head;
131 else
132 #endif
133 {
134
135 /* Get pointer of ED. */
136 ied = lp.itd_ptr -> ux_ehci_hsiso_td_ed;
137
138 /* Get pointer locations. */
139 head = &ied -> ux_ehci_hsiso_ed_transfer_head;
140 tail = &ied -> ux_ehci_hsiso_ed_transfer_tail;
141 first_new = &ied -> ux_ehci_hsiso_ed_transfer_first_new;
142
143 /* If there is no transfer, start. */
144 if (ied -> ux_ehci_hsiso_ed_frstart == 0xFF)
145 {
146 ied -> ux_ehci_hsiso_ed_frstart = 0xFE;
147 ied -> ux_ehci_hsiso_ed_fr_sw = 0;
148 ied -> ux_ehci_hsiso_ed_fr_hc = 0;
149 start = UX_TRUE;
150 }
151 }
152
153 request_list = (*head);
154 if (request_list == UX_NULL)
155 {
156
157 /* Link to head. */
158 (*head) = transfer_request;
159 (*tail) = transfer_request;
160 (*first_new) = transfer_request;
161 }
162 else
163 {
164
165 /* Link to tail of the list. */
166 (*tail) -> ux_transfer_request_next_transfer_request = transfer_request;
167
168 /* In case there is nothing to load, set new ones. */
169 if (*first_new == UX_NULL)
170 *first_new = transfer_request;
171 }
172
173 /* Move tail until it's real last one. */
174 while((*tail) -> ux_transfer_request_next_transfer_request != UX_NULL)
175 (*tail) = ((*tail) -> ux_transfer_request_next_transfer_request);
176
177 /* Release the periodic table. */
178 _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex);
179
180 /* Simulate iTD/siTD done to start - HCD signal. */
181 if (start)
182 {
183 hcd_ehci -> ux_hcd_ehci_hcd_owner -> ux_hcd_thread_signal ++;
184 _ux_host_semaphore_put(&_ux_system_host -> ux_system_host_hcd_semaphore);
185 }
186
187 /* Return completion status. */
188 return(UX_SUCCESS);
189 #endif
190 }
191
192