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 /** Generic Serial Host module 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_gser.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_gser_command PORTABLE C */
37 /* 6.3.0 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function will send a command to the ACM device. The command */
45 /* can be one of the following : */
46 /* SET_CONTROL */
47 /* SET_LINE */
48 /* SEND_BREAK */
49 /* */
50 /* */
51 /* INPUT */
52 /* */
53 /* acm Pointer to acm class */
54 /* command command value */
55 /* value value to be sent in the */
56 /* command request */
57 /* data_buffer buffer to be sent */
58 /* data_length length of the buffer to send */
59 /* */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* Completion Status */
64 /* */
65 /* CALLS */
66 /* */
67 /* _ux_host_stack_transfer_request Process transfer request */
68 /* _ux_host_semaphore_get Get semaphore */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* Application */
73 /* */
74 /* RELEASE HISTORY */
75 /* */
76 /* DATE NAME DESCRIPTION */
77 /* */
78 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
79 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
80 /* resulting in version 6.1 */
81 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
82 /* refined macros names, */
83 /* resulting in version 6.1.10 */
84 /* 10-31-2023 Yajun xia Modified comment(s), */
85 /* resulting in version 6.3.0 */
86 /* */
87 /**************************************************************************/
_ux_host_class_gser_command(UX_HOST_CLASS_GSER * gser,ULONG interface_index,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length)88 UINT _ux_host_class_gser_command(UX_HOST_CLASS_GSER *gser, ULONG interface_index, ULONG command,
89 ULONG value, UCHAR *data_buffer, ULONG data_length)
90 {
91
92 UX_ENDPOINT *control_endpoint;
93 UX_TRANSFER *transfer_request;
94 UINT status;
95 ULONG request_direction;
96
97
98 /* We need to get the default control endpoint transfer request pointer. */
99 control_endpoint = &gser -> ux_host_class_gser_device -> ux_device_control_endpoint;
100 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
101
102 /* Check the direction of the command. */
103 switch (command)
104 {
105
106 case UX_HOST_CLASS_GSER_REQ_SEND_ENCAPSULATED_COMMAND :
107 case UX_HOST_CLASS_GSER_REQ_SET_COMM_FEATURE :
108 case UX_HOST_CLASS_GSER_REQ_CLEAR_COMM_FEATURE :
109 case UX_HOST_CLASS_GSER_REQ_SET_AUX_LINE_STATE :
110 case UX_HOST_CLASS_GSER_REQ_SET_HOOK_STATE :
111 case UX_HOST_CLASS_GSER_REQ_PULSE_SETUP :
112 case UX_HOST_CLASS_GSER_REQ_SEND_PULSE :
113 case UX_HOST_CLASS_GSER_REQ_SET_PUSLE_TIME :
114 case UX_HOST_CLASS_GSER_REQ_RING_AUX_JACK :
115 case UX_HOST_CLASS_GSER_REQ_SET_LINE_CODING :
116 case UX_HOST_CLASS_GSER_REQ_SET_LINE_STATE :
117 case UX_HOST_CLASS_GSER_REQ_SEND_BREAK :
118 case UX_HOST_CLASS_GSER_REQ_SET_RINGER_PARMS :
119 case UX_HOST_CLASS_GSER_REQ_SET_OPERATION_PARMS :
120 case UX_HOST_CLASS_GSER_REQ_SET_LINE_PARMS :
121
122 /* Direction is out */
123 request_direction = UX_REQUEST_OUT;
124 break;
125
126
127 case UX_HOST_CLASS_GSER_REQ_GET_ENCAPSULATED_COMMAND :
128 case UX_HOST_CLASS_GSER_REQ_GET_COMM_FEATURE :
129 case UX_HOST_CLASS_GSER_REQ_GET_LINE_CODING :
130 case UX_HOST_CLASS_GSER_REQ_GET_RINGER_PARMS :
131 case UX_HOST_CLASS_GSER_REQ_GET_OPERATION_PARMS :
132 case UX_HOST_CLASS_GSER_REQ_GET_LINE_PARMS :
133
134 /* Direction is in */
135 request_direction = UX_REQUEST_IN;
136 break;
137
138
139 default :
140
141 return(UX_ERROR);
142
143 }
144
145 /* Protect the control endpoint semaphore here. It will be unprotected in the
146 transfer request function. */
147 status = _ux_host_semaphore_get(&gser -> ux_host_class_gser_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
148
149 /* Check for status. */
150 if (status != UX_SUCCESS)
151
152 /* Something went wrong. */
153 return(status);
154
155 /* Create a transfer_request for the request. */
156 transfer_request -> ux_transfer_request_data_pointer = data_buffer;
157 transfer_request -> ux_transfer_request_requested_length = data_length;
158 transfer_request -> ux_transfer_request_function = command;
159 transfer_request -> ux_transfer_request_type = request_direction | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
160 transfer_request -> ux_transfer_request_value = value;
161 transfer_request -> ux_transfer_request_index = gser -> ux_host_class_gser_interface_array[interface_index].ux_host_class_gser_interface->ux_interface_descriptor.bInterfaceNumber;
162
163 /* Send request to HCD layer. */
164 status = _ux_host_stack_transfer_request(transfer_request);
165
166 /* Return completion status. */
167 return(status);
168 }
169
170
171 /**************************************************************************/
172 /* */
173 /* FUNCTION RELEASE */
174 /* */
175 /* _uxe_host_class_gser_command PORTABLE C */
176 /* 6.3.0 */
177 /* AUTHOR */
178 /* */
179 /* Chaoqiong Xiao, Microsoft Corporation */
180 /* */
181 /* DESCRIPTION */
182 /* */
183 /* This function checks errors in GSER command function call. */
184 /* */
185 /* INPUT */
186 /* */
187 /* gser Pointer to GSER class */
188 /* command command value */
189 /* value value to be sent in the */
190 /* command request */
191 /* data_buffer buffer to be sent */
192 /* data_length length of the buffer to send */
193 /* */
194 /* OUTPUT */
195 /* */
196 /* Status */
197 /* */
198 /* CALLS */
199 /* */
200 /* _ux_host_class_gser_command Send GSER request */
201 /* */
202 /* CALLED BY */
203 /* */
204 /* Application */
205 /* */
206 /* RELEASE HISTORY */
207 /* */
208 /* DATE NAME DESCRIPTION */
209 /* */
210 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
211 /* */
212 /**************************************************************************/
_uxe_host_class_gser_command(UX_HOST_CLASS_GSER * gser,ULONG interface_index,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length)213 UINT _uxe_host_class_gser_command(UX_HOST_CLASS_GSER *gser, ULONG interface_index, ULONG command,
214 ULONG value, UCHAR *data_buffer, ULONG data_length)
215 {
216
217 /* Sanity check. */
218 if (gser == UX_NULL)
219 return(UX_INVALID_PARAMETER);
220
221 /* Invoke GSER command function. */
222 return(_ux_host_class_gser_command(gser, interface_index,
223 command, value, data_buffer, data_length));
224 }
225