1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Host Stack */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_host_stack.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _ux_host_stack_device_configuration_activate PORTABLE C */
36 /* 6.1.10 */
37 /* AUTHOR */
38 /* */
39 /* Chaoqiong Xiao, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function selects a specific configuration for a device. */
44 /* When this configuration is set to the device, by default all the */
45 /* device interface and their associated alternate setting 0 is */
46 /* activated on the device. */
47 /* */
48 /* INPUT */
49 /* */
50 /* configuration Pointer to configuration */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* Completion Status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _ux_utility_semaphore_get Get semaphore */
59 /* _ux_utility_semaphore_put Put semaphore */
60 /* _ux_host_stack_configuration_interface_scan Scan and activate */
61 /* interfaces */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* Application */
66 /* USBX Components */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */
73 /* 06-02-2021 Chaoqiong Xiao Modified comment(s), */
74 /* fixed trace enabled error, */
75 /* resulting in version 6.1.7 */
76 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
77 /* added standalone support, */
78 /* resulting in version 6.1.10 */
79 /* */
80 /**************************************************************************/
_ux_host_stack_device_configuration_activate(UX_CONFIGURATION * configuration)81 UINT _ux_host_stack_device_configuration_activate(UX_CONFIGURATION *configuration)
82 {
83 #if defined(UX_HOST_STANDALONE)
84 UX_INTERRUPT_SAVE_AREA
85 #endif
86 UX_DEVICE *device;
87 UINT status;
88
89
90 /* Check for validity of the configuration handle. */
91 if (configuration -> ux_configuration_handle != (ULONG) (ALIGN_TYPE) configuration)
92 {
93
94 /* Error trap. */
95 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_CONFIGURATION_HANDLE_UNKNOWN);
96
97 /* If trace is enabled, insert this event into the trace buffer. */
98 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
99
100 return(UX_CONFIGURATION_HANDLE_UNKNOWN);
101 }
102
103 /* Get the device container for this configuration. */
104 device = configuration -> ux_configuration_device;
105
106 /* If trace is enabled, insert this event into the trace buffer. */
107 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_ACTIVATE, device, configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
108
109 #if defined(UX_HOST_STANDALONE)
110
111 /* Check device lock. */
112 UX_DISABLE
113 if (device -> ux_device_flags & UX_DEVICE_FLAG_LOCK)
114 {
115 UX_RESTORE
116 return(UX_BUSY);
117 }
118 device -> ux_device_flags |= UX_DEVICE_FLAG_LOCK;
119 UX_RESTORE
120 #else
121
122 /* Protect the control endpoint semaphore here. It will be unprotected in the
123 transfer request function. */
124 status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
125
126 /* Check for status. */
127 if (status != UX_SUCCESS)
128 {
129
130 /* Error trap. */
131 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_SEMAPHORE_ERROR);
132
133 /* If trace is enabled, insert this event into the trace buffer. */
134 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_SEMAPHORE_ERROR, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
135
136 return(UX_SEMAPHORE_ERROR);
137 }
138 #endif
139
140 /* Check for the state of the device . If the device is already configured,
141 we need to cancel the existing configuration before enabling this one. */
142 if (device -> ux_device_state == UX_DEVICE_CONFIGURED)
143 {
144
145 /* If this configuration is already activated, we are good,
146 otherwise report error. */
147 status = (device -> ux_device_current_configuration == configuration) ?
148 UX_SUCCESS : UX_ALREADY_ACTIVATED;
149 #if defined(UX_HOST_STANDALONE)
150 device -> ux_device_flags &= ~UX_DEVICE_FLAG_LOCK;
151 #else
152 _ux_host_semaphore_put(&device -> ux_device_protection_semaphore);
153 #endif
154 return(status);
155 }
156
157 /* Scan and activate the interfaces. */
158 status = _ux_host_stack_configuration_interface_scan(configuration);
159
160 #if defined(UX_HOST_STANDALONE)
161
162 if (status == UX_SUCCESS)
163 {
164
165 /* Place device enum state: LOCK -> SET_CONFIGURE. */
166 device -> ux_device_enum_trans =
167 &device -> ux_device_control_endpoint.ux_endpoint_transfer_request;
168 device -> ux_device_enum_state = UX_HOST_STACK_ENUM_TRANS_LOCK_WAIT;
169 device -> ux_device_enum_inst.configuration = configuration;
170 device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_CONFIG_SET;
171
172 /* Set enumeration flag to process enumeration sequence. */
173 device -> ux_device_flags |= UX_DEVICE_FLAG_ENUM;
174
175 /* Wait until enumeration done and device removed. */
176 while(device -> ux_device_enum_state != UX_STATE_IDLE)
177 {
178 _ux_system_host_tasks_run();
179 }
180 }
181 #endif
182
183 /* Return completion status. */
184 return(status);
185 }
186
187
188 /**************************************************************************/
189 /* */
190 /* FUNCTION RELEASE */
191 /* */
192 /* _uxe_host_stack_device_configuration_activate PORTABLE C */
193 /* 6.3.0 */
194 /* AUTHOR */
195 /* */
196 /* Chaoqiong Xiao, Microsoft Corporation */
197 /* */
198 /* DESCRIPTION */
199 /* */
200 /* This function checks errors in host stack configuration activate */
201 /* function call. */
202 /* */
203 /* INPUT */
204 /* */
205 /* configuration Pointer to configuration */
206 /* */
207 /* OUTPUT */
208 /* */
209 /* None */
210 /* */
211 /* CALLS */
212 /* */
213 /* _ux_host_stack_device_configuration_activate */
214 /* Host stack config activate */
215 /* */
216 /* CALLED BY */
217 /* */
218 /* Application */
219 /* */
220 /* RELEASE HISTORY */
221 /* */
222 /* DATE NAME DESCRIPTION */
223 /* */
224 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
225 /* */
226 /**************************************************************************/
_uxe_host_stack_device_configuration_activate(UX_CONFIGURATION * configuration)227 UINT _uxe_host_stack_device_configuration_activate(UX_CONFIGURATION *configuration)
228 {
229
230 /* Sanity check. */
231 if (configuration == UX_NULL)
232 return(UX_INVALID_PARAMETER);
233
234 /* Invoke configuration activate function. */
235 return(_ux_host_stack_device_configuration_activate(configuration));
236 }
237