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