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 /** Host Stack */
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_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_stack_device_configuration_activate PORTABLE C */
37 /* 6.1.10 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function selects a specific configuration for a device. */
45 /* When this configuration is set to the device, by default all the */
46 /* device interface and their associated alternate setting 0 is */
47 /* activated on the device. */
48 /* */
49 /* INPUT */
50 /* */
51 /* configuration Pointer to configuration */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* Completion Status */
56 /* */
57 /* CALLS */
58 /* */
59 /* _ux_utility_semaphore_get Get semaphore */
60 /* _ux_utility_semaphore_put Put semaphore */
61 /* _ux_host_stack_configuration_interface_scan Scan and activate */
62 /* interfaces */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* Application */
67 /* USBX Components */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 02-02-2021 Chaoqiong Xiao Initial Version 6.1.4 */
74 /* 06-02-2021 Chaoqiong Xiao Modified comment(s), */
75 /* fixed trace enabled error, */
76 /* resulting in version 6.1.7 */
77 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
78 /* added standalone support, */
79 /* resulting in version 6.1.10 */
80 /* */
81 /**************************************************************************/
_ux_host_stack_device_configuration_activate(UX_CONFIGURATION * configuration)82 UINT _ux_host_stack_device_configuration_activate(UX_CONFIGURATION *configuration)
83 {
84 #if defined(UX_HOST_STANDALONE)
85 UX_INTERRUPT_SAVE_AREA
86 #endif
87 UX_DEVICE *device;
88 UINT status;
89
90
91 /* Check for validity of the configuration handle. */
92 if (configuration -> ux_configuration_handle != (ULONG) (ALIGN_TYPE) configuration)
93 {
94
95 /* Error trap. */
96 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_CONFIGURATION_HANDLE_UNKNOWN);
97
98 /* If trace is enabled, insert this event into the trace buffer. */
99 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
100
101 return(UX_CONFIGURATION_HANDLE_UNKNOWN);
102 }
103
104 /* Get the device container for this configuration. */
105 device = configuration -> ux_configuration_device;
106
107 /* If trace is enabled, insert this event into the trace buffer. */
108 UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_CONFIGURATION_ACTIVATE, device, configuration, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
109
110 #if defined(UX_HOST_STANDALONE)
111
112 /* Check device lock. */
113 UX_DISABLE
114 if (device -> ux_device_flags & UX_DEVICE_FLAG_LOCK)
115 {
116 UX_RESTORE
117 return(UX_BUSY);
118 }
119 device -> ux_device_flags |= UX_DEVICE_FLAG_LOCK;
120 UX_RESTORE
121 #else
122
123 /* Protect the control endpoint semaphore here. It will be unprotected in the
124 transfer request function. */
125 status = _ux_host_semaphore_get(&device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
126
127 /* Check for status. */
128 if (status != UX_SUCCESS)
129 {
130
131 /* Error trap. */
132 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_SEMAPHORE_ERROR);
133
134 /* If trace is enabled, insert this event into the trace buffer. */
135 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_SEMAPHORE_ERROR, configuration, 0, 0, UX_TRACE_ERRORS, 0, 0)
136
137 return(UX_SEMAPHORE_ERROR);
138 }
139 #endif
140
141 /* Check for the state of the device . If the device is already configured,
142 we need to cancel the existing configuration before enabling this one. */
143 if (device -> ux_device_state == UX_DEVICE_CONFIGURED)
144 {
145
146 /* If this configuration is already activated, we are good,
147 otherwise report error. */
148 status = (device -> ux_device_current_configuration == configuration) ?
149 UX_SUCCESS : UX_ALREADY_ACTIVATED;
150 #if defined(UX_HOST_STANDALONE)
151 device -> ux_device_flags &= ~UX_DEVICE_FLAG_LOCK;
152 #else
153 _ux_host_semaphore_put(&device -> ux_device_protection_semaphore);
154 #endif
155 return(status);
156 }
157
158 /* Scan and activate the interfaces. */
159 status = _ux_host_stack_configuration_interface_scan(configuration);
160
161 #if defined(UX_HOST_STANDALONE)
162
163 if (status == UX_SUCCESS)
164 {
165
166 /* Place device enum state: LOCK -> SET_CONFIGURE. */
167 device -> ux_device_enum_trans =
168 &device -> ux_device_control_endpoint.ux_endpoint_transfer_request;
169 device -> ux_device_enum_state = UX_HOST_STACK_ENUM_TRANS_LOCK_WAIT;
170 device -> ux_device_enum_inst.configuration = configuration;
171 device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_CONFIG_SET;
172
173 /* Set enumeration flag to process enumeration sequence. */
174 device -> ux_device_flags |= UX_DEVICE_FLAG_ENUM;
175
176 /* Wait until enumeration done and device removed. */
177 while(device -> ux_device_enum_state != UX_STATE_IDLE)
178 {
179 _ux_system_host_tasks_run();
180 }
181 }
182 #endif
183
184 /* Return completion status. */
185 return(status);
186 }
187