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 /** Audio Class */
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_class_audio.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_audio_control_request PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function issue audio specific control request. */
45 /* */
46 /* INPUT */
47 /* */
48 /* audio Pointer to audio class */
49 /* streaming_control 0 for control requests */
50 /* 1 for streaming requests */
51 /* request_type bmRequestType */
52 /* request bRequest */
53 /* request_value wValue can be: */
54 /* (CS << 8) | CN or */
55 /* (ICN << 8) | OCN or */
56 /* (MU_MIXER_CONTROL << 8) | MCN */
57 /* or other specific value. */
58 /* spec_id Entity/Language ID (if used) */
59 /* parameter Pointer to request parameters */
60 /* parameter_size Request parameters length */
61 /* actual_size Actual processed size */
62 /* */
63 /* OUTPUT */
64 /* */
65 /* Completion Status */
66 /* */
67 /* CALLS */
68 /* */
69 /* _ux_host_stack_class_instance_verify Verify instance is valid */
70 /* _ux_host_stack_transfer_request Process transfer request */
71 /* _ux_host_semaphore_get Get semaphore */
72 /* _ux_host_mutex_on Get mutex */
73 /* _ux_host_mutex_off Release mutex */
74 /* */
75 /* CALLED BY */
76 /* */
77 /* Application */
78 /* Audio Class */
79 /* */
80 /* RELEASE HISTORY */
81 /* */
82 /* DATE NAME DESCRIPTION */
83 /* */
84 /* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
85 /* */
86 /**************************************************************************/
_ux_host_class_audio_control_request(UX_HOST_CLASS_AUDIO * audio,UINT streaming_control,UINT request_type,UINT request,UINT request_value,UINT spec_id,UCHAR * parameter,ULONG parameter_size,ULONG * actual_size)87 UINT _ux_host_class_audio_control_request(UX_HOST_CLASS_AUDIO *audio,
88 UINT streaming_control,
89 UINT request_type, UINT request,
90 UINT request_value,
91 UINT spec_id,
92 UCHAR *parameter, ULONG parameter_size, ULONG *actual_size)
93 {
94
95 UX_ENDPOINT *control_endpoint;
96 UX_TRANSFER *transfer_request;
97 ULONG request_index = 0;
98 UINT status;
99
100
101 /* Ensure the instance is valid. */
102 if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS)
103 {
104
105 /* Error trap. */
106 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN);
107
108 /* If trace is enabled, insert this event into the trace buffer. */
109 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0)
110
111 return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
112 }
113
114 /* Check request settings. */
115 switch(request_type & UX_REQUEST_TARGET)
116 {
117 case UX_REQUEST_TARGET_INTERFACE:
118 request_index = streaming_control ?
119 audio -> ux_host_class_audio_streaming_interface -> ux_interface_descriptor.bInterfaceNumber :
120 audio -> ux_host_class_audio_control_interface_number;
121 break;
122 case UX_REQUEST_TARGET_ENDPOINT:
123 request_index = audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.bEndpointAddress;
124 break;
125 default:
126 return(UX_INVALID_PARAMETER);
127 }
128
129 /* Protect thread reentry to this instance. */
130 _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex);
131
132 /* We need to get the default control endpoint transfer request pointer. */
133 control_endpoint = &audio -> ux_host_class_audio_device -> ux_device_control_endpoint;
134 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
135
136 /* Protect the control endpoint semaphore here. It will be unprotected in the
137 transfer request function. */
138 status = _ux_host_semaphore_get(&audio -> ux_host_class_audio_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
139
140 /* Check for status. */
141 if (status != UX_SUCCESS)
142 {
143 /* Something went wrong. */
144 _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
145 return(status);
146 }
147
148 /* Create a transfer request for the specific setting. */
149 transfer_request -> ux_transfer_request_data_pointer = parameter;
150 transfer_request -> ux_transfer_request_requested_length = parameter_size;
151 transfer_request -> ux_transfer_request_function = request;
152 transfer_request -> ux_transfer_request_type = request_type;
153 transfer_request -> ux_transfer_request_value = request_value;
154 transfer_request -> ux_transfer_request_index = request_index | (spec_id << 8);
155
156 /* Send request to HCD layer. */
157 status = _ux_host_stack_transfer_request(transfer_request);
158
159 /* Save actual size. */
160 if (actual_size)
161 *actual_size = transfer_request -> ux_transfer_request_actual_length;
162
163 /* Unprotect thread reentry to this instance. */
164 _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
165
166 /* Return completion status. */
167 return(status);
168 }
169
170
171 /**************************************************************************/
172 /* */
173 /* FUNCTION RELEASE */
174 /* */
175 /* _uxe_host_class_audio_control_request PORTABLE C */
176 /* 6.3.0 */
177 /* AUTHOR */
178 /* */
179 /* Chaoqiong Xiao, Microsoft Corporation */
180 /* */
181 /* DESCRIPTION */
182 /* */
183 /* This function checks errors in audio control request function call. */
184 /* */
185 /* INPUT */
186 /* */
187 /* audio Pointer to audio class */
188 /* streaming_control 0 for control requests */
189 /* 1 for streaming requests */
190 /* request_type bmRequestType */
191 /* request bRequest */
192 /* request_value wValue can be: */
193 /* (CS << 8) | CN or */
194 /* (ICN << 8) | OCN or */
195 /* (MU_MIXER_CONTROL << 8) | MCN */
196 /* or other specific value. */
197 /* spec_id Entity/Language ID (if used) */
198 /* parameter Pointer to request parameters */
199 /* parameter_size Request parameters length */
200 /* actual_size Actual processed size */
201 /* */
202 /* OUTPUT */
203 /* */
204 /* Status */
205 /* */
206 /* CALLS */
207 /* */
208 /* _ux_host_class_audio_control_request Get audio control request */
209 /* */
210 /* CALLED BY */
211 /* */
212 /* Application */
213 /* Audio Class */
214 /* */
215 /* RELEASE HISTORY */
216 /* */
217 /* DATE NAME DESCRIPTION */
218 /* */
219 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
220 /* */
221 /**************************************************************************/
_uxe_host_class_audio_control_request(UX_HOST_CLASS_AUDIO * audio,UINT streaming_control,UINT request_type,UINT request,UINT request_value,UINT spec_id,UCHAR * parameter,ULONG parameter_size,ULONG * actual_size)222 UINT _uxe_host_class_audio_control_request(UX_HOST_CLASS_AUDIO *audio,
223 UINT streaming_control,
224 UINT request_type, UINT request,
225 UINT request_value,
226 UINT spec_id,
227 UCHAR *parameter, ULONG parameter_size, ULONG *actual_size)
228 {
229
230 /* Sanity check. */
231 if ((audio == UX_NULL))
232 return(UX_INVALID_PARAMETER);
233
234 /* Invoke audio control request function. */
235 return(_ux_host_class_audio_control_request(audio,
236 streaming_control,
237 request_type, request, request_value,
238 spec_id, parameter, parameter_size, actual_size));
239 }
240