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_deactivate      PORTABLE C      */
36 /*                                                           6.1.12       */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Chaoqiong Xiao, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function deactivate current configuration for a device.        */
44 /*    When this configuration is deactivated, all the device interfaces   */
45 /*    are deactivated on the device.                                      */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*                                                                        */
50 /*  OUTPUT                                                                */
51 /*                                                                        */
52 /*    Completion Status                                                   */
53 /*                                                                        */
54 /*  CALLS                                                                 */
55 /*                                                                        */
56 /*    _ux_utility_semaphore_get             Get semaphore                 */
57 /*    _ux_utility_semaphore_put             Put semaphore                 */
58 /*    (ux_host_class_entry_function)        Class entry function          */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    Application                                                         */
63 /*    USBX Components                                                     */
64 /*                                                                        */
65 /*  RELEASE HISTORY                                                       */
66 /*                                                                        */
67 /*    DATE              NAME                      DESCRIPTION             */
68 /*                                                                        */
69 /*  02-02-2021     Chaoqiong Xiao           Initial Version 6.1.4         */
70 /*  06-02-2021     Chaoqiong Xiao           Modified comment(s),          */
71 /*                                            fixed trace enabled error,  */
72 /*                                            resulting in version 6.1.7  */
73 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
74 /*                                            added standalone support,   */
75 /*                                            resulting in version 6.1.10 */
76 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
77 /*                                            internal clean up,          */
78 /*                                            resulting in version 6.1.11 */
79 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
80 /*                                            fixed parameter/variable    */
81 /*                                            names conflict C++ keyword, */
82 /*                                            resulting in version 6.1.12 */
83 /*                                                                        */
84 /**************************************************************************/
_ux_host_stack_device_configuration_deactivate(UX_DEVICE * device)85 UINT  _ux_host_stack_device_configuration_deactivate(UX_DEVICE *device)
86 {
87 
88 #if defined(UX_HOST_STANDALONE)
89 UX_INTERRUPT_SAVE_AREA
90 #endif
91 UX_HOST_CLASS_COMMAND       command;
92 UX_CONFIGURATION            *configuration;
93 UX_INTERFACE                *interface_ptr;
94 UINT                        status;
95 
96 
97     /* Do a sanity check on the device handle.  */
98     if (device -> ux_device_handle != (ULONG) (ALIGN_TYPE) device)
99     {
100 
101         /* Error trap. */
102         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DEVICE_HANDLE_UNKNOWN);
103 
104         /* If trace is enabled, insert this event into the trace buffer.  */
105         UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DEVICE_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
106 
107         return(UX_DEVICE_HANDLE_UNKNOWN);
108     }
109 
110     /* If trace is enabled, insert this event into the trace buffer.  */
111     UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_DEACTIVATE, device, device -> ux_device_current_configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
112 
113 #if defined(UX_HOST_STANDALONE)
114 
115     /* Check device lock.  */
116     UX_DISABLE
117     if (device -> ux_device_flags & UX_DEVICE_FLAG_LOCK)
118     {
119         UX_RESTORE
120         return(UX_BUSY);
121     }
122     device -> ux_device_flags |= UX_DEVICE_FLAG_LOCK;
123     UX_RESTORE
124 #else
125 
126     /* Protect the control endpoint semaphore here.  It will be unprotected in the
127        transfer request function.  */
128     status =  _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
129 
130     /* Check for status.  */
131     if (status != UX_SUCCESS)
132     {
133 
134         /* Error trap. */
135         _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_SEMAPHORE_ERROR);
136 
137         /* If trace is enabled, insert this event into the trace buffer.  */
138         UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_SEMAPHORE_ERROR, device -> ux_device_current_configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
139 
140         return(UX_SEMAPHORE_ERROR);
141     }
142 #endif
143 
144     /* Check for the state of the device, if not configured, we are done.  */
145     if (device -> ux_device_state != UX_DEVICE_CONFIGURED)
146     {
147 #if defined(UX_HOST_STANDALONE)
148         device -> ux_device_flags &= ~UX_DEVICE_FLAG_LOCK;
149 #else
150         _ux_host_semaphore_put(&device -> ux_device_protection_semaphore);
151 #endif
152         return(UX_SUCCESS);
153     }
154 
155     /* Deactivate classes by command.  */
156     command.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_DEACTIVATE;
157 
158     /* Search for the active configuration.  */
159     configuration =  device -> ux_device_current_configuration;
160 
161     /* If device configured configuration must be activated.  */
162 
163     /* We have the correct configuration, search the interface(s).  */
164     interface_ptr =  configuration -> ux_configuration_first_interface;
165 
166     /* Loop to perform the search.  */
167     while (interface_ptr != UX_NULL)
168     {
169 
170         /* Check if an instance of the interface is present.  */
171         if (interface_ptr -> ux_interface_class_instance != UX_NULL)
172         {
173 
174             /* We need to stop the class instance for the device.  */
175             command.ux_host_class_command_instance =  interface_ptr -> ux_interface_class_instance;
176 
177             /* Call the class.  */
178             interface_ptr -> ux_interface_class -> ux_host_class_entry_function(&command);
179         }
180 
181         /* Move to next interface.  */
182         interface_ptr =  interface_ptr -> ux_interface_next_interface;
183     }
184 
185     /* The device can now be un-configured.  */
186     status =  _ux_host_stack_device_configuration_reset(device);
187 
188 #if defined(UX_HOST_STANDALONE)
189     device -> ux_device_flags &= ~UX_DEVICE_FLAG_LOCK;
190 #endif
191 
192     /* Return completion status.  */
193     return(status);
194 }
195 
196 
197 /**************************************************************************/
198 /*                                                                        */
199 /*  FUNCTION                                               RELEASE        */
200 /*                                                                        */
201 /*    _uxe_host_stack_device_configuration_deactivate     PORTABLE C      */
202 /*                                                           6.3.0        */
203 /*  AUTHOR                                                                */
204 /*                                                                        */
205 /*    Chaoqiong Xiao, Microsoft Corporation                               */
206 /*                                                                        */
207 /*  DESCRIPTION                                                           */
208 /*                                                                        */
209 /*    This function checks errors in host stack configuration deactivate  */
210 /*    function call.                                                      */
211 /*                                                                        */
212 /*  INPUT                                                                 */
213 /*                                                                        */
214 /*    device                                Pointer to device             */
215 /*                                                                        */
216 /*  OUTPUT                                                                */
217 /*                                                                        */
218 /*    None                                                                */
219 /*                                                                        */
220 /*  CALLS                                                                 */
221 /*                                                                        */
222 /*    _ux_host_stack_device_configuration_deactivate                      */
223 /*                                          Host stack config deactivate  */
224 /*                                                                        */
225 /*  CALLED BY                                                             */
226 /*                                                                        */
227 /*    Application                                                         */
228 /*                                                                        */
229 /*  RELEASE HISTORY                                                       */
230 /*                                                                        */
231 /*    DATE              NAME                      DESCRIPTION             */
232 /*                                                                        */
233 /*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
234 /*                                                                        */
235 /**************************************************************************/
_uxe_host_stack_device_configuration_deactivate(UX_DEVICE * device)236 UINT  _uxe_host_stack_device_configuration_deactivate(UX_DEVICE *device)
237 {
238 
239     /* Sanity check.  */
240     if (device == UX_NULL)
241         return(UX_INVALID_PARAMETER);
242 
243     /* Invoke configuration deactivate function.  */
244     return(_ux_host_stack_device_configuration_deactivate(device));
245 }
246