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