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 /**   Video 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_video.h"
29 #include "ux_host_stack.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_host_class_video_control_request                PORTABLE C      */
37 /*                                                           6.1.12       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function issues a control request to a given video entity      */
45 /*    (unit or terminal).                                                 */
46 /*    The unit or terminal IDs can be parsed once the video device is     */
47 /*    ready, via ux_host_class_video_entities_parse.                      */
48 /*                                                                        */
49 /*    Note: only one VideoStreaming interface is supported for now.       */
50 /*                                                                        */
51 /*  INPUT                                                                 */
52 /*                                                                        */
53 /*    video                                 Pointer to video class        */
54 /*    request                               The request to issue          */
55 /*    interface_index                       The interface index           */
56 /*                                            0: VideoControl interface   */
57 /*                                            1: VideoStreaming 1         */
58 /*                                            N: VideoStreaming N         */
59 /*    entity_id                             The terminal or unit ID       */
60 /*    control_selector                      The control selector          */
61 /*    parameter                             Pointer to parameter block    */
62 /*    parameter_size                        Size of parameter block       */
63 /*                                                                        */
64 /*  OUTPUT                                                                */
65 /*                                                                        */
66 /*    Completion Status                                                   */
67 /*                                                                        */
68 /*  CALLS                                                                 */
69 /*                                                                        */
70 /*  CALLED BY                                                             */
71 /*                                                                        */
72 /*    Application                                                         */
73 /*                                                                        */
74 /*  RELEASE HISTORY                                                       */
75 /*                                                                        */
76 /*    DATE              NAME                      DESCRIPTION             */
77 /*                                                                        */
78 /*  09-30-2020     Chaoqiong Xiao           Initial Version 6.1           */
79 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
80 /*                                            refined macros names,       */
81 /*                                            resulting in version 6.1.10 */
82 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
83 /*                                            fixed parameter/variable    */
84 /*                                            names conflict C++ keyword, */
85 /*                                            resulting in version 6.1.12 */
86 /*                                                                        */
87 /**************************************************************************/
_ux_host_class_video_control_request(UX_HOST_CLASS_VIDEO * video,UINT request,UCHAR interface_index,UINT entity_id,UINT control_selector,UCHAR * parameter,UINT parameter_size)88 UINT _ux_host_class_video_control_request(UX_HOST_CLASS_VIDEO *video,
89                                         UINT request, UCHAR interface_index,
90                                         UINT entity_id, UINT control_selector,
91                                         UCHAR *parameter, UINT parameter_size)
92 {
93 
94 UX_ENDPOINT     *control_endpoint;
95 UX_TRANSFER     *transfer_request;
96 UINT            status;
97 UCHAR           *control_buffer;
98 UCHAR           request_direction;
99 UX_INTERFACE    *interface_ptr;
100 UCHAR           interface_number;
101 
102 
103     /* Ensure the instance is valid.  */
104     if (_ux_host_stack_class_instance_verify(_ux_system_host_class_video_name, (VOID *) video) != UX_SUCCESS)
105         return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
106 
107     /* Protect thread reentry to this instance.  */
108     status =  _ux_host_semaphore_get(&video -> ux_host_class_video_semaphore_control_request, UX_WAIT_FOREVER);
109     if (status != UX_SUCCESS)
110         return(status);
111 
112     /* We need to get the default control endpoint transfer request pointer.  */
113     control_endpoint =  &video -> ux_host_class_video_device -> ux_device_control_endpoint;
114     transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;
115 
116     /* Need to allocate memory for the control buffer.  */
117     control_buffer =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, parameter_size);
118     if (control_buffer == UX_NULL)
119     {
120 
121         /* Unprotect thread reentry to this instance.  */
122         _ux_host_semaphore_put(&video -> ux_host_class_video_semaphore_control_request);
123 
124         /* Return an error.  */
125         return(UX_MEMORY_INSUFFICIENT);
126     }
127 
128     /* Get the request direction from the control request ID.  */
129     request_direction =  (request & 0x80);
130 
131     /* Are we setting a value?  */
132     if (request_direction == 0)
133     {
134 
135         /* Put parameter block in buffer.  */
136         if (parameter_size)
137             _ux_utility_memory_copy(control_buffer, parameter, parameter_size); /* Use case of memcpy is verified. */
138     }
139 
140     /* Protect the control endpoint semaphore here.  It will be unprotected in the
141        transfer request function.  */
142     status =  _ux_host_semaphore_get(&video -> ux_host_class_video_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
143 
144     /* Check for status.  */
145     if (status != UX_SUCCESS)
146     {
147 
148         /* Something went wrong. */
149         _ux_utility_memory_free(control_buffer);
150         _ux_host_semaphore_put(&video -> ux_host_class_video_semaphore_control_request);
151         return(status);
152     }
153 
154     /* Get the interface number.  */
155     if (interface_index == 0)
156         interface_number = (UCHAR)video -> ux_host_class_video_control_interface_number;
157     else
158     {
159 
160         /* Only one streaming interface is supported now.  */
161         interface_ptr = video -> ux_host_class_video_streaming_interface;
162         interface_number = (UCHAR)interface_ptr -> ux_interface_descriptor.bInterfaceNumber;
163     }
164 
165     /* Create a transfer request for the request.  */
166     transfer_request -> ux_transfer_request_data_pointer =      control_buffer;
167     transfer_request -> ux_transfer_request_requested_length =  parameter_size;
168     transfer_request -> ux_transfer_request_function =          request;
169     transfer_request -> ux_transfer_request_type =              request_direction | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
170     transfer_request -> ux_transfer_request_value =             (control_selector << 8);
171     transfer_request -> ux_transfer_request_index =             interface_number | (entity_id << 8);
172 
173     /* Send request to HCD layer.  */
174     status =  _ux_host_stack_transfer_request(transfer_request);
175 
176     /* Check for correct transfer.  */
177     if (status != UX_SUCCESS)
178     {
179 
180         /* Free the previous control buffer.  */
181         _ux_utility_memory_free(control_buffer);
182 
183         /* Unprotect thread reentry to this instance.  */
184         _ux_host_semaphore_put(&video -> ux_host_class_video_semaphore_control_request);
185 
186         /* Return completion status.  */
187         return(status);
188     }
189 
190     /* Are we getting a value?  */
191     if (request_direction)
192     {
193 
194         /* Then store it in the caller's buffer.  */
195         if (parameter_size)
196             _ux_utility_memory_copy(parameter, control_buffer, parameter_size); /* Use case of memcpy is verified. */
197     }
198 
199     /* Free all used resources.  */
200     _ux_utility_memory_free(control_buffer);
201 
202     /* Unprotect thread reentry to this instance.  */
203     _ux_host_semaphore_put(&video -> ux_host_class_video_semaphore_control_request);
204 
205     /* Return completion status.  */
206     return(status);
207 }
208 
209 /**************************************************************************/
210 /*                                                                        */
211 /*  FUNCTION                                               RELEASE        */
212 /*                                                                        */
213 /*    _uxe_host_class_video_control_request               PORTABLE C      */
214 /*                                                           6.3.0        */
215 /*  AUTHOR                                                                */
216 /*                                                                        */
217 /*    Yajun Xia, Microsoft Corporation                                    */
218 /*                                                                        */
219 /*  DESCRIPTION                                                           */
220 /*                                                                        */
221 /*    This function checks errors in video control request function call. */
222 /*                                                                        */
223 /*  INPUT                                                                 */
224 /*                                                                        */
225 /*    video                                 Pointer to video class        */
226 /*    request                               The request to issue          */
227 /*    interface_index                       The interface index           */
228 /*                                            0: VideoControl interface   */
229 /*                                            1: VideoStreaming 1         */
230 /*                                            N: VideoStreaming N         */
231 /*    entity_id                             The terminal or unit ID       */
232 /*    control_selector                      The control selector          */
233 /*    parameter                             Pointer to parameter block    */
234 /*    parameter_size                        Size of parameter block       */
235 /*                                                                        */
236 /*  OUTPUT                                                                */
237 /*                                                                        */
238 /*    Completion Status                                                   */
239 /*                                                                        */
240 /*  CALLS                                                                 */
241 /*                                                                        */
242 /*    _ux_host_class_video_control_request  Video control request         */
243 /*                                                                        */
244 /*  CALLED BY                                                             */
245 /*                                                                        */
246 /*    Application                                                         */
247 /*    Video Class                                                         */
248 /*                                                                        */
249 /*  RELEASE HISTORY                                                       */
250 /*                                                                        */
251 /*    DATE              NAME                      DESCRIPTION             */
252 /*                                                                        */
253 /*  10-31-2023        Yajun xia             Initial Version 6.3.0         */
254 /*                                                                        */
255 /**************************************************************************/
_uxe_host_class_video_control_request(UX_HOST_CLASS_VIDEO * video,UINT request,UCHAR interface_index,UINT entity_id,UINT control_selector,UCHAR * parameter,UINT parameter_size)256 UINT _uxe_host_class_video_control_request(UX_HOST_CLASS_VIDEO *video,
257                                         UINT request, UCHAR interface_index,
258                                         UINT entity_id, UINT control_selector,
259                                         UCHAR *parameter, UINT parameter_size)
260 {
261 
262     /* Sanity checks.  */
263     if (video == UX_NULL)
264         return(UX_INVALID_PARAMETER);
265 
266     /* Call the video control request function.  */
267     return(_ux_host_class_video_control_request(video, request, interface_index,
268                                                 entity_id, control_selector,
269                                                 parameter, parameter_size));
270 }
271