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