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 /** Prolific 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_prolific.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_prolific_setup PORTABLE C */
37 /* 6.1.11 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function obtains the entire prolific configuration descriptors.*/
45 /* This is needed because the prolific class needs to know if commands */
46 /* are routed through the comm interface or the data class. */
47 /* */
48 /* INPUT */
49 /* */
50 /* prolific Pointer to prolific class */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* Completion Status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _ux_host_stack_transfer_request Process transfer request */
59 /* _ux_utility_memory_allocate Allocate memory block */
60 /* _ux_utility_memory_free Release memory block */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* _ux_host_class_prolific_activate */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
71 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
74 /* internal clean up, */
75 /* resulting in version 6.1.11 */
76 /* */
77 /**************************************************************************/
_ux_host_class_prolific_setup(UX_HOST_CLASS_PROLIFIC * prolific)78 UINT _ux_host_class_prolific_setup(UX_HOST_CLASS_PROLIFIC *prolific)
79 {
80
81 UCHAR *setup_buffer;
82 UX_ENDPOINT *control_endpoint;
83 UX_TRANSFER *transfer_request;
84 UINT status;
85
86 /* We need to get the default control endpoint transfer request pointer. */
87 control_endpoint = &prolific -> ux_host_class_prolific_device -> ux_device_control_endpoint;
88 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
89
90 /* Need to allocate memory for the buffer. */
91 setup_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_PROLIFIC_SETUP_BUFFER_SIZE);
92 if (setup_buffer == UX_NULL)
93 return(UX_MEMORY_INSUFFICIENT);
94
95 /* Set the device type. Can be either 0, 1 or HX. */
96 if (prolific -> ux_host_class_prolific_device -> ux_device_descriptor.bDeviceClass == 0x02)
97
98 /* Device is of type 0. */
99 prolific -> ux_host_class_prolific_device_type = UX_HOST_CLASS_PROLIFIC_DEVICE_TYPE_0;
100
101 else
102 {
103
104 /* Check packet size. If 64, we are dealing with HX type device. */
105 if (prolific -> ux_host_class_prolific_device -> ux_device_descriptor.bMaxPacketSize0 == 64)
106
107 /* Device is of type HX. */
108 prolific -> ux_host_class_prolific_device_type = UX_HOST_CLASS_PROLIFIC_DEVICE_TYPE_HX;
109
110 else
111
112 /* Default case : type 1. */
113 prolific -> ux_host_class_prolific_device_type = UX_HOST_CLASS_PROLIFIC_DEVICE_TYPE_1;
114
115 }
116
117 /* Create a transfer request for the prolific setup request # 1. */
118 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
119 transfer_request -> ux_transfer_request_requested_length = 1;
120 transfer_request -> ux_transfer_request_function = 1;
121 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
122 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_EEPROM_READ;
123 transfer_request -> ux_transfer_request_index = 0;
124
125 /* Send request to HCD layer. */
126 status = _ux_host_stack_transfer_request(transfer_request);
127
128 /* Check status, if error, do not proceed. */
129 if (status != UX_SUCCESS)
130 {
131
132 /* Free all used resources. */
133 _ux_utility_memory_free(setup_buffer);
134
135 /* Return completion status. */
136 return(status);
137
138 }
139
140 /* Create a transfer request for the prolific setup request # 2. */
141 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
142 transfer_request -> ux_transfer_request_requested_length = 0;
143 transfer_request -> ux_transfer_request_function = 1;
144 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
145 transfer_request -> ux_transfer_request_value = 0x0404;
146 transfer_request -> ux_transfer_request_index = 0;
147
148 /* Send request to HCD layer. */
149 status = _ux_host_stack_transfer_request(transfer_request);
150
151 /* Check status, if error, do not proceed. */
152 if (status != UX_SUCCESS)
153 {
154
155 /* Free all used resources. */
156 _ux_utility_memory_free(setup_buffer);
157
158 /* Return completion status. */
159 return(status);
160
161 }
162
163 /* Create a transfer request for the prolific setup request # 3. */
164 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
165 transfer_request -> ux_transfer_request_requested_length = 1;
166 transfer_request -> ux_transfer_request_function = 1;
167 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
168 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_EEPROM_READ;
169 transfer_request -> ux_transfer_request_index = 0;
170
171 /* Send request to HCD layer. */
172 status = _ux_host_stack_transfer_request(transfer_request);
173
174 /* Check status, if error, do not proceed. */
175 if (status != UX_SUCCESS)
176 {
177
178 /* Free all used resources. */
179 _ux_utility_memory_free(setup_buffer);
180
181 /* Return completion status. */
182 return(status);
183
184 }
185
186 /* Create a transfer request for the prolific setup request # 4. */
187 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
188 transfer_request -> ux_transfer_request_requested_length = 1;
189 transfer_request -> ux_transfer_request_function = 1;
190 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
191 transfer_request -> ux_transfer_request_value = 0x8383;
192 transfer_request -> ux_transfer_request_index = 0;
193
194 /* Send request to HCD layer. */
195 status = _ux_host_stack_transfer_request(transfer_request);
196
197 /* Check status, if error, do not proceed. */
198 if (status != UX_SUCCESS)
199 {
200
201 /* Free all used resources. */
202 _ux_utility_memory_free(setup_buffer);
203
204 /* Return completion status. */
205 return(status);
206
207 }
208
209 /* Create a transfer request for the prolific setup request # 5. */
210 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
211 transfer_request -> ux_transfer_request_requested_length = 1;
212 transfer_request -> ux_transfer_request_function = 1;
213 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
214 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_EEPROM_READ;
215 transfer_request -> ux_transfer_request_index = 0;
216
217 /* Send request to HCD layer. */
218 status = _ux_host_stack_transfer_request(transfer_request);
219
220 /* Check status, if error, do not proceed. */
221 if (status != UX_SUCCESS)
222 {
223
224 /* Free all used resources. */
225 _ux_utility_memory_free(setup_buffer);
226
227 /* Return completion status. */
228 return(status);
229
230 }
231
232 /* Create a transfer request for the prolific setup request # 6. */
233 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
234 transfer_request -> ux_transfer_request_requested_length = 0;
235 transfer_request -> ux_transfer_request_function = 1;
236 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
237 transfer_request -> ux_transfer_request_value = 0x0404;
238 transfer_request -> ux_transfer_request_index = 1;
239
240 /* Send request to HCD layer. */
241 status = _ux_host_stack_transfer_request(transfer_request);
242
243 /* Check status, if error, do not proceed. */
244 if (status != UX_SUCCESS)
245 {
246
247 /* Free all used resources. */
248 _ux_utility_memory_free(setup_buffer);
249
250 /* Return completion status. */
251 return(status);
252
253 }
254
255 /* Create a transfer request for the prolific setup request # 7. */
256 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
257 transfer_request -> ux_transfer_request_requested_length = 1;
258 transfer_request -> ux_transfer_request_function = 1;
259 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
260 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_EEPROM_READ;
261 transfer_request -> ux_transfer_request_index = 0;
262
263 /* Send request to HCD layer. */
264 status = _ux_host_stack_transfer_request(transfer_request);
265
266 /* Check status, if error, do not proceed. */
267 if (status != UX_SUCCESS)
268 {
269
270 /* Free all used resources. */
271 _ux_utility_memory_free(setup_buffer);
272
273 /* Return completion status. */
274 return(status);
275
276 }
277
278 /* Create a transfer request for the prolific setup request # 8. */
279 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
280 transfer_request -> ux_transfer_request_requested_length = 1;
281 transfer_request -> ux_transfer_request_function = 1;
282 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
283 transfer_request -> ux_transfer_request_value = 0x8383;
284 transfer_request -> ux_transfer_request_index = 0;
285
286 /* Send request to HCD layer. */
287 status = _ux_host_stack_transfer_request(transfer_request);
288
289 /* Check status, if error, do not proceed. */
290 if (status != UX_SUCCESS)
291 {
292
293 /* Free all used resources. */
294 _ux_utility_memory_free(setup_buffer);
295
296 /* Return completion status. */
297 return(status);
298
299 }
300
301 /* Create a transfer request for the prolific setup request # 9. */
302 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
303 transfer_request -> ux_transfer_request_requested_length = 0;
304 transfer_request -> ux_transfer_request_function = 1;
305 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
306 transfer_request -> ux_transfer_request_value = 0;
307 transfer_request -> ux_transfer_request_index = 1;
308
309 /* Send request to HCD layer. */
310 status = _ux_host_stack_transfer_request(transfer_request);
311
312 /* Check status, if error, do not proceed. */
313 if (status != UX_SUCCESS)
314 {
315
316 /* Free all used resources. */
317 _ux_utility_memory_free(setup_buffer);
318
319 /* Return completion status. */
320 return(status);
321
322 }
323
324 /* Create a transfer request for the prolific setup request # 9. */
325 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
326 transfer_request -> ux_transfer_request_requested_length = 0;
327 transfer_request -> ux_transfer_request_function = 1;
328 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
329 transfer_request -> ux_transfer_request_value = 1;
330 transfer_request -> ux_transfer_request_index = 0;
331
332 /* Send request to HCD layer. */
333 status = _ux_host_stack_transfer_request(transfer_request);
334
335 /* Check status, if error, do not proceed. */
336 if (status != UX_SUCCESS)
337 {
338
339 /* Free all used resources. */
340 _ux_utility_memory_free(setup_buffer);
341
342 /* Return completion status. */
343 return(status);
344
345 }
346
347 /* Create a transfer request for the prolific setup request # 10. */
348 if (prolific -> ux_host_class_prolific_device_type == UX_HOST_CLASS_PROLIFIC_DEVICE_TYPE_HX)
349
350 /* Chip is HX. */
351 transfer_request -> ux_transfer_request_index = 0x44;
352
353 else
354
355 /* Chip is not HX. */
356 transfer_request -> ux_transfer_request_index = 0x24;
357
358 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
359 transfer_request -> ux_transfer_request_requested_length = 0;
360 transfer_request -> ux_transfer_request_function = 1;
361 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
362 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_REG_CONFIGURE;
363
364 /* Send request to HCD layer. */
365 _ux_host_stack_transfer_request(transfer_request);
366
367
368 /* Reset upstream data pipes part 1. */
369 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
370 transfer_request -> ux_transfer_request_requested_length = 0;
371 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PROLIFIC_VENDOR_WRITE_REQUEST;
372 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
373 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_PIPE1_RESET;
374 transfer_request -> ux_transfer_request_index = 0;
375
376 /* Send request to HCD layer. */
377 status = _ux_host_stack_transfer_request(transfer_request);
378
379 /* Check status, if error, do not proceed. */
380 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
381 {
382
383 /* Free all used resources. */
384 _ux_utility_memory_free(setup_buffer);
385
386 /* Return completion status. */
387 return(UX_TRANSFER_ERROR);
388
389 }
390
391 /* Reset upstream data pipes part 2. */
392 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
393 transfer_request -> ux_transfer_request_requested_length = 0;
394 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_PROLIFIC_VENDOR_WRITE_REQUEST;
395 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
396 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_PROLIFIC_COMMAND_PIPE2_RESET;
397 transfer_request -> ux_transfer_request_index = 0;
398
399 /* Send request to HCD layer. */
400 status = _ux_host_stack_transfer_request(transfer_request);
401
402 /* Check status, if error, do not proceed. */
403 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
404 {
405
406 /* Free all used resources. */
407 _ux_utility_memory_free(setup_buffer);
408
409 /* Return completion status. */
410 return(UX_TRANSFER_ERROR);
411
412 }
413
414 /* Free all used resources. */
415 _ux_utility_memory_free(setup_buffer);
416
417 /* Return completion status. */
418 return(status);
419 }
420
421