1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13 
14 #include "ux_host_class_cdc_acm.h"
15 #include "ux_host_class_hid.h"
16 #include "ux_host_class_storage.h"
17 #include "ux_host_stack.h"
18 
19 #include "ux_device_class_cdc_acm.h"
20 #include "ux_device_class_hid.h"
21 #include "ux_device_class_storage.h"
22 
23 #include "ux_test_dcd_sim_slave.h"
24 #include "ux_test_hcd_sim_host.h"
25 #include "ux_test_utility_sim.h"
26 
27 UCHAR test_ux_system_host_class_dummy0_name[] = "ux_host_class_dummy0";
28 UCHAR test_ux_system_host_class_dummy1_name[] = "ux_host_class_dummy1";
29 UCHAR test_ux_system_host_class_dummy2_name[] = "ux_host_class_dummy2";
30 UCHAR test_ux_system_host_class_dummy3_name[] = "ux_host_class_dummy3";
31 UCHAR test_ux_system_host_class_dummy4_name[] = "ux_host_class_dummy4";
32 UCHAR test_ux_system_host_class_dummy5_name[] = "ux_host_class_dummy5";
33 UCHAR test_ux_system_host_class_dummy6_name[] = "ux_host_class_dummy6";
34 UCHAR test_ux_system_host_class_dummy7_name[] = "ux_host_class_dummy7";
35 UCHAR test_ux_system_host_class_dummy8_name[] = "ux_host_class_dummy8";
test_ux_host_class_dummy0_entry(UX_HOST_CLASS_COMMAND * command)36 static UINT test_ux_host_class_dummy0_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy1_entry(UX_HOST_CLASS_COMMAND * command)37 static UINT test_ux_host_class_dummy1_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy2_entry(UX_HOST_CLASS_COMMAND * command)38 static UINT test_ux_host_class_dummy2_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy3_entry(UX_HOST_CLASS_COMMAND * command)39 static UINT test_ux_host_class_dummy3_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy4_entry(UX_HOST_CLASS_COMMAND * command)40 static UINT test_ux_host_class_dummy4_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy5_entry(UX_HOST_CLASS_COMMAND * command)41 static UINT test_ux_host_class_dummy5_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy6_entry(UX_HOST_CLASS_COMMAND * command)42 static UINT test_ux_host_class_dummy6_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy7_entry(UX_HOST_CLASS_COMMAND * command)43 static UINT test_ux_host_class_dummy7_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
test_ux_host_class_dummy8_entry(UX_HOST_CLASS_COMMAND * command)44 static UINT test_ux_host_class_dummy8_entry(UX_HOST_CLASS_COMMAND *command){return UX_NO_CLASS_MATCH;}
45 
46 typedef struct TEST_HOST_CLASS_2_REG_STRUCT {
47 
48     UCHAR *class_name;
49     UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *);
50 } TEST_HOST_CLASS_2_REG ;
51 static TEST_HOST_CLASS_2_REG test_host_classes[] = {
52     {test_ux_system_host_class_dummy0_name, test_ux_host_class_dummy0_entry},
53     {_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry},
54     {test_ux_system_host_class_dummy1_name, test_ux_host_class_dummy1_entry},
55     {_ux_system_host_class_hid_name, ux_host_class_hid_entry},
56     {_ux_system_host_class_storage_name, ux_host_class_storage_entry},
57     {test_ux_system_host_class_dummy2_name, test_ux_host_class_dummy2_entry},
58     {test_ux_system_host_class_dummy3_name, test_ux_host_class_dummy3_entry},
59     {test_ux_system_host_class_dummy4_name, test_ux_host_class_dummy4_entry},
60     {test_ux_system_host_class_dummy5_name, test_ux_host_class_dummy5_entry},
61     {test_ux_system_host_class_dummy6_name, test_ux_host_class_dummy6_entry},
62 };
63 
64 typedef struct TEST_HCD_2_REG_STRUCT {
65 
66     UCHAR *hcd_name;
67     UINT (*hcd_init_function)(struct UX_HCD_STRUCT *);
68     ULONG hcd_param1;
69     ULONG hcd_param2;
70 } TEST_HCD_2_REG;
71 static TEST_HCD_2_REG test_hcds[] = {
72     {_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0},
73     {"dummy", _ux_test_hcd_sim_host_initialize, 0, 0},
74     {"dummy", _ux_test_hcd_sim_host_initialize, 0, 0},
75 };
76 
77 typedef struct TEST_DEVICE_CLASS_2_REG_STRUCT {
78 
79     UCHAR *class_name;
80     UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *);
81     ULONG configuration_number;
82     ULONG interface_number;
83 } TEST_DEVICE_CLASS_2_REG ;
84 static TEST_DEVICE_CLASS_2_REG test_device_classes[] = {
85     {_ux_system_slave_class_dpump_name, ux_device_class_cdc_acm_entry, 1, 0},
86     {_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry, 1, 2},
87     {_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry, 2, 0},
88     {_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry, 2, 2},
89 };
90 
91 /* Define constants.  */
92 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
93 #define                             UX_DEMO_STACK_SIZE  1024
94 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
95 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
96 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
97 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
98 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
99 #define                             UX_DEMO_MEMORY_SIZE     (128 * 1024)
100 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
101 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
102 
103 /* Define local/extern function prototypes.  */
104 static VOID                                test_thread_entry(ULONG);
105 static TX_THREAD                           tx_test_thread_host_simulation;
106 static TX_THREAD                           tx_test_thread_slave_simulation;
107 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
108 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
109 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
110 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
111 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
112 
113 static UINT                                test_ux_device_class_entry(UX_SLAVE_CLASS_COMMAND *command);
114 
115 /* Define global data structures.  */
116 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
117 static UX_HOST_CLASS                       *class_driver;
118 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
119 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
120 
121 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
122 static UCHAR                               cdc_acm_slave_change;
123 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
124 
125 static ULONG                               error_counter;
126 
127 static ULONG                               set_cfg_counter;
128 
129 static ULONG                               rsc_mem_free_on_set_cfg;
130 static ULONG                               rsc_sem_on_set_cfg;
131 static ULONG                               rsc_sem_get_on_set_cfg;
132 static ULONG                               rsc_mutex_on_set_cfg;
133 
134 static ULONG                               rsc_enum_sem_usage;
135 static ULONG                               rsc_enum_sem_get_count;
136 static ULONG                               rsc_enum_mutex_usage;
137 static ULONG                               rsc_enum_mem_usage;
138 
139 static UINT                                device_class_entry_return;
140 static UINT                                device_class_entry_cmd_req;
141 
142 /* Define device framework.  */
143 
144 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      93
145 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      103
146 #define             STRING_FRAMEWORK_LENGTH                 47
147 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
148 
149 static unsigned char device_framework_full_speed[] = {
150 
151     /* Device descriptor     18 bytes
152        0x02 bDeviceClass:    CDC class code
153        0x00 bDeviceSubclass: CDC class sub code
154        0x00 bDeviceProtocol: CDC Device protocol
155 
156        idVendor & idProduct - http://www.linux-usb.org/usb.ids
157     */
158     0x12, 0x01, 0x10, 0x01,
159     0xEF, 0x02, 0x01,
160     0x08,
161     0x84, 0x84, 0x00, 0x00,
162     0x00, 0x01,
163     0x01, 0x02, 03,
164     0x01,
165 
166     /* Configuration 1 descriptor 9 bytes */
167     0x09, 0x02, 0x4b, 0x00,
168     0x02, 0x01, 0x00,
169     0x40, 0x00,
170 
171     /* Interface association descriptor. 8 bytes.  */
172     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
173 
174     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
175     0x09, 0x04, 0x00,
176     0x00,
177     0x01,
178     0x02, 0x02, 0x01,
179     0x00,
180 
181     /* Header Functional Descriptor 5 bytes */
182     0x05, 0x24, 0x00,
183     0x10, 0x01,
184 
185     /* ACM Functional Descriptor 4 bytes */
186     0x04, 0x24, 0x02,
187     0x0f,
188 
189     /* Union Functional Descriptor 5 bytes */
190     0x05, 0x24, 0x06,
191     0x00,                          /* Master interface */
192     0x01,                          /* Slave interface  */
193 
194     /* Call Management Functional Descriptor 5 bytes */
195     0x05, 0x24, 0x01,
196     0x03,
197     0x01,                          /* Data interface   */
198 
199     /* Endpoint 0x83 descriptor 7 bytes */
200     0x07, 0x05, 0x83,
201     0x03,
202     0x08, 0x00,
203     0xFF,
204 
205     /* Data Class Interface Descriptor Requirement 9 bytes */
206     0x09, 0x04, 0x01,
207     0x00,
208     0x02,
209     0x0A, 0x00, 0x00,
210     0x00,
211 
212     /* Endpoint 0x81 descriptor 7 bytes */
213     0x07, 0x05, 0x81, /* @ 93 - 14 + 2 = 81 */
214     0x02,
215     0x40, 0x00,
216     0x00,
217 
218     /* Endpoint 0x02 descriptor 7 bytes */
219     0x07, 0x05, 0x02, /* @ 93 - 7 + 2 = 88 */
220     0x02,
221     0x40, 0x00,
222     0x00,
223 
224 };
225 
226 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
227 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
228 
229 static unsigned char device_framework_high_speed[] = {
230 
231     /* Device descriptor
232        0x02 bDeviceClass:    CDC class code
233        0x00 bDeviceSubclass: CDC class sub code
234        0x00 bDeviceProtocol: CDC Device protocol
235 
236        idVendor & idProduct - http://www.linux-usb.org/usb.ids
237     */
238     0x12, 0x01, 0x00, 0x02,
239     0xEF, 0x02, 0x01,
240     0x40,
241     0x84, 0x84, 0x00, 0x00,
242     0x00, 0x01,
243     0x01, 0x02, 03,
244     0x01,
245 
246     /* Device qualifier descriptor */
247     0x0a, 0x06, 0x00, 0x02,
248     0x02, 0x00, 0x00,
249     0x40,
250     0x01,
251     0x00,
252 
253     /* Configuration 1 descriptor */
254     0x09, 0x02, 0x4b, 0x00,
255     0x02, 0x01, 0x00,
256     0x40, 0x00,
257 
258     /* Interface association descriptor. */
259     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
260 
261     /* Communication Class Interface Descriptor Requirement */
262     0x09, 0x04, 0x00,
263     0x00,
264     0x01,
265     0x02, 0x02, 0x01,
266     0x00,
267 
268     /* Header Functional Descriptor */
269     0x05, 0x24, 0x00,
270     0x10, 0x01,
271 
272     /* ACM Functional Descriptor */
273     0x04, 0x24, 0x02,
274     0x0f,
275 
276     /* Union Functional Descriptor */
277     0x05, 0x24, 0x06,
278     0x00,
279     0x01,
280 
281     /* Call Management Functional Descriptor */
282     0x05, 0x24, 0x01,
283     0x00,
284     0x01,
285 
286     /* Endpoint 0x83 descriptor */
287     0x07, 0x05, 0x83,
288     0x03,
289     0x08, 0x00,
290     0xFF,
291 
292     /* Data Class Interface Descriptor Requirement */
293     0x09, 0x04, 0x01,
294     0x00,
295     0x02,
296     0x0A, 0x00, 0x00,
297     0x00,
298 
299     /* Endpoint 0x81 descriptor */
300     0x07, 0x05, 0x81, /* @ 103 - 14 + 2 = 91 */
301     0x02,
302     0x40, 0x00,
303     0x00,
304 
305     /* Endpoint 0x02 descriptor */
306     0x07, 0x05, 0x02, /* @ 103 - 7 + 2 = 98 */
307     0x02,
308     0x40, 0x00,
309     0x00,
310 
311 };
312 
313 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
314 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
315 
316 static unsigned char device_framework_no_interface[] = {
317 
318     /* Device descriptor     18 bytes
319        0x02 bDeviceClass:    CDC class code
320        0x00 bDeviceSubclass: CDC class sub code
321        0x00 bDeviceProtocol: CDC Device protocol
322 
323        idVendor & idProduct - http://www.linux-usb.org/usb.ids
324     */
325     0x12, 0x01, 0x10, 0x01,
326     0xEF, 0x02, 0x01,
327     0x08,
328     0x84, 0x84, 0x00, 0x00,
329     0x00, 0x01,
330     0x01, 0x02, 03,
331     0x01,
332 
333     /* Configuration 1 descriptor 9 bytes */
334     0x09, 0x02, 0x09, 0x00,
335     0x02, 0x01, 0x00,
336     0x40, 0x00,
337 };
338 
339 static unsigned char device_framework_no_endpoint[] = {
340 
341     0x12, 0x01, 0x10, 0x01,
342     0x00, 0x00, 0x00,
343     0x08,
344     0x84, 0x84, 0x00, 0x00,
345     0x00, 0x01,
346     0x01, 0x02, 03,
347     0x01,
348 
349     /* Configuration 1 descriptor 9 bytes */
350     0x09, 0x02, 0x12, 0x00,
351     0x01, 0x01, 0x00,
352     0x40, 0x00,
353 
354     /* Interface Descriptor */
355     0x09, 0x04, 0x00,
356     0x00,
357     0x00,
358     0xFF, 0x01, 0x00,
359     0x00,
360 };
361 
362 static unsigned char device_framework_testing[] = {
363 
364     /* Device descriptor     18 bytes
365        0x02 bDeviceClass:    CDC class code
366        0x00 bDeviceSubclass: CDC class sub code
367        0x00 bDeviceProtocol: CDC Device protocol
368 
369        idVendor & idProduct - http://www.linux-usb.org/usb.ids
370     */
371     0x12, 0x01, 0x10, 0x01,
372     0xEF, 0x02, 0x01,
373     0x08,
374     0x84, 0x84, 0x00, 0x00,
375     0x00, 0x01,
376     0x01, 0x02, 03,
377     0x01,
378 
379     /* Configuration 3 descriptor 9 bytes */
380     0x09, 0x02,
381     34, 0x00,        /* wTotalLength */
382     1,               /* bNumInterfaces */
383     3,               /* bConfigurationValue */
384     0x00,0x40,0x00,  /* iConfiguration, bmAttributes, bMaxPower */
385 
386     /* Interface 1.0 descriptor 9 bytes */
387     0x09, 0x04,
388     0x00,            /* bInterfaceNumber */
389     0x00,            /* bAlternateSetting */
390     0x00,            /* bNumEndpoints */
391     0x02, 0x02, 0x01,/* bInterfaceClass,SubClass,Protocol */
392     0x00,            /* iInterface */
393 
394     /* Interface 1.1 descriptor 9 bytes */
395     0x09, 0x04,
396     0x00,            /* bInterfaceNumber */
397     0x01,            /* bAlternateSetting */
398     0x01,            /* bNumEndpoints */
399     0x02, 0x02, 0x01,/* bInterfaceClass,SubClass,Protocol */
400     0x00,            /* iInterface */
401 
402     /* Endpoint 0x81 descriptor 7 bytes */
403     0x07, 0x05, 0x81,/* ...bEndpointAddress */
404     0x02,
405     0x40, 0x00,
406     0x00,
407 
408     /* Configuration 1 descriptor 9 bytes */
409     0x09, 0x02,
410     32, 0x00,        /* wTotalLength */
411     1,               /* bNumInterfaces */
412     1,               /* bConfigurationValue */
413     0x00,0x40, 0x00, /* iConfiguration, bmAttributes, bMaxPower */
414 
415     /* Interface 1 descriptor 9 bytes */
416     0x09, 0x04,
417     0x00,            /* bInterfaceNumber */
418     0x00,            /* bAlternateSetting */
419     0x02,            /* bNumEndpoints */
420     0x02, 0x02, 0x01,/* bInterfaceClass,SubClass,Protocol */
421     0x00,            /* iInterface */
422 
423     /* Endpoint 0x81 descriptor 7 bytes */
424     0x07, 0x05, 0x81,/* ...bEndpointAddress */
425     0x02,
426     0x40, 0x00,
427     0x00,
428 
429     /* Endpoint 0x02 descriptor 7 bytes */
430     0x07, 0x05, 0x02,/* ...bEndpointAddress */
431     0x02,
432     0x40, 0x00,
433     0x00,
434 
435     /* Configuration 2 descriptor 9 bytes */
436     0x09, 0x02,
437     39, 0x00,        /* wTotalLength */
438     1,               /* bNumInterfaces */
439     2,               /* bConfigurationValue */
440     0x00,0x40, 0x00, /* iConfiguration, bmAttributes, bMaxPower */
441 
442     /* Interface 2 descriptor 9 bytes */
443     0x09, 0x04,
444     0x00,            /* bInterfaceNumber */
445     0x00,            /* bAlternateSetting */
446     0x03,            /* bNumEndpoints */
447     0x02, 0x02, 0x01,/* bInterfaceClass,SubClass,Protocol */
448     0x00,            /* iInterface */
449 
450     /* Endpoint 0x81 descriptor 7 bytes */
451     0x07, 0x05, 0x81,/* ...bEndpointAddress */
452     0x02,
453     0x40, 0x00,
454     0x00,
455 
456     /* Endpoint 0x02 descriptor 7 bytes */
457     0x07, 0x05, 0x02,/* ...bEndpointAddress */
458     0x02,
459     0x40, 0x00,
460     0x00,
461 
462     /* Endpoint 0x83 descriptor 7 bytes */
463     0x07, 0x05, 0x83,/* ...bEndpointAddress */
464     0x02,
465     0x40, 0x00,
466     0x00,
467 
468 };
469 
470 
471 static unsigned char string_framework[] = {
472 
473     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
474         0x09, 0x04, 0x01, 0x0c,
475         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
476         0x6f, 0x67, 0x69, 0x63,
477 
478     /* Product string descriptor : Index 2 - "EL Composite device" */
479         0x09, 0x04, 0x02, 0x13,
480         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
481         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
482         0x69, 0x63, 0x65,
483 
484     /* Serial Number string descriptor : Index 3 - "0001" */
485         0x09, 0x04, 0x03, 0x04,
486         0x30, 0x30, 0x30, 0x31
487 };
488 
489 
490     /* Multiple languages are supported on the device, to add
491        a language besides english, the unicode language code must
492        be appended to the language_id_framework array and the length
493        adjusted accordingly. */
494 static unsigned char language_id_framework[] = {
495 
496     /* English. */
497         0x09, 0x04
498 };
499 
500 /* Define the ISR dispatch.  */
501 
502 extern VOID    (*test_isr_dispatch)(void);
503 
504 
505 /* Prototype for test control return.  */
506 
507 void  test_control_return(UINT status);
508 
509 
510 /* Define the ISR dispatch routine.  */
511 
test_isr(void)512 static void    test_isr(void)
513 {
514 
515     /* For further expansion of interrupt-level testing.  */
516 }
517 
test_ux_device_class_entry(UX_SLAVE_CLASS_COMMAND * command)518 static UINT test_ux_device_class_entry(UX_SLAVE_CLASS_COMMAND *command)
519 {
520     device_class_entry_cmd_req = command->ux_slave_class_command_request;
521     return device_class_entry_return;
522 }
523 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)524 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
525 {
526 
527 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
528 
529     switch(event)
530     {
531 
532         case UX_DEVICE_INSERTION:
533 
534             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
535                 cdc_acm_host_control = cdc_acm;
536             else
537                 cdc_acm_host_data = cdc_acm;
538             break;
539 
540         case UX_DEVICE_REMOVAL:
541 
542             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
543                 cdc_acm_host_control = UX_NULL;
544             else
545                 cdc_acm_host_data = UX_NULL;
546             break;
547 
548         default:
549             break;
550     }
551     return 0;
552 }
553 
test_cdc_instance_activate(VOID * cdc_instance)554 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
555 {
556 
557     /* Save the CDC instance.  */
558     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
559 }
test_cdc_instance_deactivate(VOID * cdc_instance)560 static VOID    test_cdc_instance_deactivate(VOID *cdc_instance)
561 {
562 
563     /* Reset the CDC instance.  */
564     cdc_acm_slave = UX_NULL;
565 }
566 
test_cdc_instance_parameter_change(VOID * cdc_instance)567 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
568 {
569 
570     /* Set CDC parameter change flag. */
571     cdc_acm_slave_change = UX_TRUE;
572 }
573 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)574 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
575 {
576 }
577 /* TODO: _ux_system_uninitialize, patch implement to lib if necessary */
578 #if 0
579 UINT  _ux_system_uninitialize(VOID)
580 {
581 
582     /* Delete the Mutex object used by USBX to control critical sections. */
583     if (_ux_system->ux_system_mutex.tx_mutex_id != TX_CLEAR_ID)
584         _ux_utility_mutex_delete(&_ux_system -> ux_system_mutex);
585 
586     return(UX_SUCCESS);
587 }
588 #endif
589 /* TODO: _ux_device_stack_uninitialize, patch implement to lib if necessary */
590 #if 0
591 UINT  _ux_device_stack_uninitialize(VOID)
592 {
593 UX_SLAVE_DEVICE                 *device;
594 UX_SLAVE_ENDPOINT               *endpoints_pool;
595 UX_SLAVE_TRANSFER               *transfer_request;
596 ULONG                           endpoints_found;
597 
598     /* If trace is enabled, insert this event into the trace buffer.  */
599     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INITIALIZE, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
600 
601     /* Get the pointer to the device. */
602     device =  &_ux_system_slave -> ux_system_slave_device;
603 
604     /* Free class memory. */
605     if (_ux_system_slave -> ux_system_slave_class_array)
606         _ux_utility_memory_free(_ux_system_slave -> ux_system_slave_class_array);
607 
608     /* Allocate some memory for the Control Endpoint.  First get the address of the transfer request for the
609        control endpoint. */
610     transfer_request =  &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
611 
612     /* Free memory for the control endpoint buffer. */
613     if (transfer_request -> ux_slave_transfer_request_data_pointer)
614         _ux_utility_memory_free(transfer_request -> ux_slave_transfer_request_data_pointer);
615 
616     /* Get the number of endoints found in the device framework.  */
617     endpoints_found = device -> ux_slave_device_endpoints_pool_number;
618 
619     /* Get the endpoint pool address in the device container.  */
620     endpoints_pool =  device -> ux_slave_device_endpoints_pool;
621 
622     /* Parse all endpoints and fee memory and semaphore. */
623     while (endpoints_found-- != 0)
624     {
625         /* Free the memory for endpoint data pointer. */
626         if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer)
627             _ux_utility_memory_free(endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer);
628 
629         /* Remove the TX semaphore for the endpoint.  */
630         if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore.tx_semaphore_id != TX_CLEAR_ID)
631             _ux_utility_semaphore_delete(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore);
632 
633         /* Next endpoint.  */
634         endpoints_pool++;
635     }
636 
637     /* Free the endpoint pool address in the device container. */
638     if (device -> ux_slave_device_endpoints_pool)
639         _ux_utility_memory_free(device -> ux_slave_device_endpoints_pool);
640 
641     /* Free memory for interface pool.  */
642     if (device -> ux_slave_device_interfaces_pool)
643         _ux_utility_memory_free(device -> ux_slave_device_interfaces_pool);
644 
645     /* Return successful completion.  */
646     return(UX_SUCCESS);
647 }
648 #endif
649 #if 0 /* _ux_host_stack_uninitialize, move implement to lib if necessary */
650 VOID _ux_host_stack_uninitialize(VOID)
651 {
652     if (_ux_system_host->ux_system_host_hcd_thread.tx_thread_id != TX_CLEAR_ID)
653     {
654 
655         tx_thread_terminate(&_ux_system_host->ux_system_host_hcd_thread);
656         tx_thread_delete(&_ux_system_host->ux_system_host_hcd_thread);
657     }
658 
659     if (_ux_system_host->ux_system_host_enum_thread.tx_thread_id != TX_CLEAR_ID)
660     {
661 
662         tx_thread_terminate(&_ux_system_host->ux_system_host_enum_thread);
663         tx_thread_delete(&_ux_system_host->ux_system_host_enum_thread);
664     }
665 
666 #if defined(UX_OTG_SUPPORT)
667     if (_ux_system_host->ux_system_host_hnp_polling_thread.tx_thread_id != TX_CLEAR_ID)
668     {
669         tx_thread_terminate(&_ux_system_host->ux_system_host_hnp_polling_thread);
670         tx_thread_delete(&_ux_system_host->ux_system_host_hnp_polling_thread);
671     }
672     if (_ux_system_host->ux_system_host_hnp_polling_thread_stack)
673         ux_utility_memory_free(_ux_system_host->ux_system_host_hnp_polling_thread_stack);
674 #endif
675 
676     if (_ux_system_host->ux_system_host_hcd_semaphore.tx_semaphore_id != TX_CLEAR_ID)
677         ux_utility_semaphore_delete(&_ux_system_host->ux_system_host_hcd_semaphore);
678 
679     if (_ux_system_host->ux_system_host_enum_semaphore.tx_semaphore_id != TX_CLEAR_ID)
680         ux_utility_semaphore_delete(&_ux_system_host->ux_system_host_enum_semaphore);
681 
682 
683     if (_ux_system_host -> ux_system_host_enum_thread_stack)
684         ux_utility_memory_free(_ux_system_host -> ux_system_host_enum_thread_stack);
685 
686     if (_ux_system_host -> ux_system_host_device_array)
687         ux_utility_memory_free(_ux_system_host -> ux_system_host_device_array);
688 
689     if (_ux_system_host -> ux_system_host_class_array)
690         ux_utility_memory_free(_ux_system_host -> ux_system_host_class_array);
691 
692     if (_ux_system_host -> ux_system_host_hcd_array)
693         ux_utility_memory_free(_ux_system_host -> ux_system_host_hcd_array);
694 }
695 #endif
696 
697 /* Define what the initial system looks like.  */
698 
699 #ifdef CTEST
test_application_define(void * first_unused_memory)700 void test_application_define(void *first_unused_memory)
701 #else
702 void usbx_host_device_initialize_test_application_define(void *first_unused_memory)
703 #endif
704 {
705 
706 UINT                    status;
707 CHAR *                  stack_pointer;
708 CHAR *                  memory_pointer;
709 ULONG                   test_n;
710 
711 ULONG                   mem_count;
712 ULONG                   sem_count;
713 ULONG                   thread_count;
714 
715     printf("Running Host & Device Init/Uninit Test.............................. ");
716 
717     /* Enable memory logging for tests. */
718     ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
719 
720     /* Reset testing counts. */
721     ux_test_utility_sim_mutex_create_count_reset();
722     ux_test_utility_sim_sem_create_count_reset();
723     ux_test_utility_sim_sem_get_count_reset();
724     /* Reset error generations */
725     ux_test_utility_sim_sem_error_generation_stop();
726     ux_test_utility_sim_mutex_error_generation_stop();
727     ux_test_utility_sim_sem_get_error_generation_stop();
728 
729     /* Initialize the free memory pointer */
730     stack_pointer = (CHAR *) usbx_memory;
731     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
732 
733     stepinfo(">>>>>>>>>>>>>>>> Test ux_system_initialize\n");
734 
735     /* Initialize with very small memory should report error */
736     status = ux_system_initialize(memory_pointer, 8, UX_NULL, 0);
737     if (status != UX_MEMORY_INSUFFICIENT)
738     {
739 
740         printf("ERROR #1: should report memory error when initialize with small buffer\n");
741         test_control_return(1);
742     }
743 
744     /* Initialize with mutex error */
745     ux_test_utility_sim_mutex_error_generation_start(0);
746     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
747     if (status != UX_MUTEX_ERROR)
748     {
749 
750         printf("ERROR #2: should report mutex error when system mutex not created\n");
751         test_control_return(1);
752     }
753     ux_test_utility_sim_mutex_error_generation_stop();
754 
755     /* Initialize USBX Memory */
756     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE / 2, memory_pointer + UX_DEMO_MEMORY_SIZE/ 2, UX_DEMO_MEMORY_SIZE/ 2);
757     /* Check for error.  */
758     if (status != UX_SUCCESS)
759     {
760 
761         printf("ERROR #3\n");
762         test_control_return(1);
763     }
764 
765     /* Register the error callback. */
766     _ux_utility_error_callback_register(test_ux_error_callback);
767 
768     stepinfo(">>>>>>>>>>>>>>>> Test ux_host_stack_initialize\n");
769 
770     /* Initialize to check resources usage */
771     _ux_system_uninitialize();
772     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
773     if (status != UX_SUCCESS)
774     {
775 
776         printf("ERROR #4\n");
777         test_control_return(1);
778     }
779 
780     ux_test_utility_sim_sem_create_count_reset();
781     ux_test_utility_sim_thread_create_count_reset();
782     ux_test_utility_sim_mem_alloc_count_reset();
783 
784     /* The code below is required for installing the host portion of USBX */
785     status =  ux_host_stack_initialize(test_host_change_function);
786     if (status != UX_SUCCESS)
787     {
788 
789         printf("ERROR #5\n");
790         test_control_return(1);
791     }
792     mem_count = ux_test_utility_sim_mem_alloc_count();
793     sem_count = ux_test_utility_sim_sem_create_count();
794     thread_count = ux_test_utility_sim_thread_create_count();
795 
796 #if 1
797     /* Test memory allocation errors. */
798     for (test_n = 0; test_n < mem_count; test_n ++)
799     {
800 
801         stepinfo(" .memTest %2ld / %2ld\n", test_n, mem_count - 1);
802 
803         /* Re-initialize memory! */
804         if (status == UX_SUCCESS)
805             _ux_host_stack_uninitialize();
806         _ux_system_uninitialize();
807         status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
808         if (status != UX_SUCCESS)
809         {
810 
811             printf("ERROR #6.%ld\n", test_n);
812             test_control_return(1);
813         }
814 
815         /* Start error simulation */
816         ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
817         status = ux_host_stack_initialize(test_host_change_function);
818         ux_test_utility_sim_mem_alloc_error_generation_stop();
819         if (status != UX_MEMORY_INSUFFICIENT)
820         {
821 
822             printf("ERROR #7.%ld: memory error should be reported\n", test_n);
823             test_control_return(1);
824         }
825     }
826 #endif
827 #if 1
828     /* Test semaphore creation errors. */
829     for (test_n = 0; test_n < sem_count; test_n ++)
830     {
831 
832         stepinfo(" .semTest %2ld / %2ld\n", test_n, sem_count - 1);
833 
834         /* Re-initialize memory! */
835         if (status == UX_SUCCESS)
836             _ux_host_stack_uninitialize();
837         _ux_system_uninitialize();
838         status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
839         if (status != UX_SUCCESS)
840         {
841 
842             printf("ERROR #8.%ld\n", test_n);
843             test_control_return(1);
844         }
845 
846         /* Start error simulation */
847         ux_test_utility_sim_sem_error_generation_start(test_n);
848         status = ux_host_stack_initialize(test_host_change_function);
849         ux_test_utility_sim_sem_error_generation_stop();
850         if (status != UX_SEMAPHORE_ERROR)
851         {
852 
853             printf("ERROR #9.%ld: semaphore error should be reported\n", test_n);
854             test_control_return(1);
855         }
856     }
857 #endif
858 #if 1
859     /* Test thread creation errors. */
860     for (test_n = 0; test_n < thread_count; test_n ++)
861     {
862 
863         stepinfo(" .threadTest %2ld / %2ld\n", test_n, thread_count - 1);
864 
865         /* Re-initialize memory! */
866         if (status == UX_SUCCESS)
867             _ux_host_stack_uninitialize();
868         _ux_system_uninitialize();
869         status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
870         if (status != UX_SUCCESS)
871         {
872 
873             printf("ERROR #10.%ld\n", test_n);
874             test_control_return(1);
875         }
876 
877         /* Start error simulation */
878         ux_test_utility_sim_thread_error_generation_start(test_n);
879         status = ux_host_stack_initialize(test_host_change_function);
880         ux_test_utility_sim_thread_error_generation_stop();
881         if (status != UX_THREAD_ERROR)
882         {
883 
884             printf("ERROR #11.%ld: thread error should be reported\n", test_n);
885             test_control_return(1);
886         }
887     }
888 #endif
889 
890     _ux_host_stack_uninitialize();
891     _ux_system_uninitialize();
892     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
893     if (status != UX_SUCCESS)
894     {
895 
896         printf("ERROR #%d: ux_system_initialize fail\n", __LINE__);
897         test_control_return(1);
898     }
899     status = ux_host_stack_initialize(test_host_change_function);
900     if (status != UX_SUCCESS)
901     {
902 
903         printf("ERROR #%d: ux_host_stack_initialize fail\n", __LINE__);
904         test_control_return(1);
905     }
906 
907     stepinfo(">>>>>>>>>>>>>>>> Test ux_host_stack_class_register\n");
908 
909     for (test_n = 0; test_n < UX_MAX_CLASS_DRIVER; test_n ++)
910     {
911         stepinfo(" .classReg %2ld / %2d : %s\n", test_n, UX_MAX_CLASS_DRIVER - 1, test_host_classes[test_n].class_name);
912 
913         status = ux_host_stack_class_register(test_host_classes[test_n].class_name, test_host_classes[test_n].class_entry_function);
914         if (status != UX_SUCCESS)
915         {
916 
917             printf("ERROR #%d\n", __LINE__);
918             test_control_return(1);
919         }
920     }
921 
922     /* Register again report error */
923 #if UX_MAX_CLASS_DRIVER == 1
924     status =  ux_host_stack_class_register(test_ux_system_host_class_dummy0_name, test_ux_host_class_dummy0_entry);
925 #else
926     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
927 #endif
928     if (status != UX_HOST_CLASS_ALREADY_INSTALLED)
929     {
930 
931         printf("ERROR #%d: 0x%x\n", __LINE__, status);
932         test_control_return(1);
933     }
934 
935     /* Register more report error */
936     status = ux_host_stack_class_register(test_host_classes[UX_MAX_CLASS_DRIVER].class_name, test_host_classes[UX_MAX_CLASS_DRIVER].class_entry_function);
937     if (status != UX_MEMORY_ARRAY_FULL)
938     {
939 
940         printf("ERROR #%d: register more than %d class should report error\n", __LINE__, UX_MAX_CLASS_DRIVER);
941         test_control_return(1);
942     }
943 
944     stepinfo(">>>>>>>>>>>>>>>> Test ux_device_stack_initialize\n");
945 
946 #if !defined(UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE)
947     /* No interface found, error should be reported. */
948     status = ux_device_stack_initialize(device_framework_no_interface, sizeof(device_framework_no_interface),
949                                         device_framework_no_interface, sizeof(device_framework_no_interface),
950                                         string_framework, STRING_FRAMEWORK_LENGTH,
951                                         language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
952     if (status == UX_SUCCESS)
953     {
954 
955         printf("ERROR #%d\n", __LINE__);
956         test_control_return(1);
957     }
958 #endif
959 
960     /* Try a testing framework. */
961     status = ux_device_stack_initialize(device_framework_testing, sizeof(device_framework_testing),
962                                         device_framework_testing, sizeof(device_framework_testing),
963                                         string_framework, STRING_FRAMEWORK_LENGTH,
964                                         language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
965     if (status != UX_SUCCESS)
966     {
967 
968         printf("ERROR #%d: %x\n", __LINE__, status);
969         test_control_return(1);
970     }
971 
972     /* Uninitialize the stack to change framework to the one used for enumeration. */
973     ux_device_stack_uninitialize();
974 
975     /* Test framework with no endpoint. */
976     status = ux_device_stack_initialize(device_framework_no_endpoint, sizeof(device_framework_no_endpoint),
977                                         device_framework_no_endpoint, sizeof(device_framework_no_endpoint),
978                                         string_framework, STRING_FRAMEWORK_LENGTH,
979                                         language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
980     if (status != UX_SUCCESS)
981     {
982 
983         printf("ERROR #%d\n", __LINE__);
984         test_control_return(1);
985     }
986 
987     /* Uninitialize the stack to change framework to the one used for enumeration. */
988     ux_device_stack_uninitialize();
989 
990     /* The code below is required for installing the device portion of USBX. No call back for
991        device status change in this example. */
992     ux_test_utility_sim_mem_alloc_count_reset();
993     ux_test_utility_sim_sem_create_count_reset();
994     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
995                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
996                                        string_framework, STRING_FRAMEWORK_LENGTH,
997                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
998     if(status!=UX_SUCCESS)
999     {
1000 
1001         printf("ERROR #%d\n", __LINE__);
1002         test_control_return(1);
1003     }
1004     mem_count = ux_test_utility_sim_mem_alloc_count();
1005     sem_count = ux_test_utility_sim_sem_create_count();
1006     ux_test_utility_sim_mem_alloc_log_lock();
1007 #if 1 /* FIXME: _ux_device_stack_uninitialize must check resources before free them */
1008     for (test_n = 0; test_n < mem_count; test_n ++)
1009     {
1010         stepinfo(" .dStackMEM %2ld / %2ld\n", test_n, mem_count - 1);
1011 
1012         /* Confirm uninitialize (no need since stack_initialize fixed) */
1013         // ux_device_stack_uninitialize();
1014 
1015         /* Start error generation */
1016         ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
1017 
1018         /* Check error */
1019         status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1020                                         device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1021                                         string_framework, STRING_FRAMEWORK_LENGTH,
1022                                         language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1023         /* Stop error generation */
1024         ux_test_utility_sim_mem_alloc_error_generation_stop();
1025         if(status != UX_MEMORY_INSUFFICIENT)
1026         {
1027 
1028             printf("ERROR #%d.%ld: memory error should be reported\n", __LINE__, test_n);
1029             test_control_return(1);
1030         }
1031     }
1032 #endif
1033 #if 1 /* FIXME: _ux_device_stack_uninitialize must check resources before free them */
1034     for (test_n = 0; test_n < sem_count; test_n ++)
1035     {
1036         stepinfo(" .dStackSEM %2ld / %2ld\n", test_n, sem_count - 1);
1037 
1038         /* Confirm uninitialize (no need since stack_initialize fixed) */
1039         // ux_device_stack_uninitialize();
1040 
1041         /* Start error generation */
1042         ux_test_utility_sim_sem_error_generation_start(test_n);
1043 
1044         /* Check error */
1045         status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1046                                         device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1047                                         string_framework, STRING_FRAMEWORK_LENGTH,
1048                                         language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1049         /* Stop error generation */
1050         ux_test_utility_sim_sem_error_generation_stop();
1051         if(status != UX_SEMAPHORE_ERROR)
1052         {
1053 
1054             printf("ERROR #%d.%ld: semaphore error should be reported\n", __LINE__, test_n);
1055             test_control_return(1);
1056         }
1057     }
1058 #endif
1059     /* Do a good initialize for enumeration test. */
1060     ux_device_stack_uninitialize();
1061     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1062                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1063                                        string_framework, STRING_FRAMEWORK_LENGTH,
1064                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1065     if(status!=UX_SUCCESS)
1066     {
1067 
1068         printf("ERROR #%d\n", __LINE__);
1069         test_control_return(1);
1070     }
1071 
1072     stepinfo(">>>>>>>>>>>>>>>> Test ux_device_stack_class_register\n");
1073 
1074     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
1075     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
1076     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
1077     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
1078 
1079     for (test_n = 0; test_n < UX_MAX_SLAVE_CLASS_DRIVER; test_n ++)
1080     {
1081         stepinfo(" .dStackClassReg %2ld / %2d\n", test_n, UX_MAX_SLAVE_CLASS_DRIVER - 1);
1082 
1083         /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1084         status =  ux_device_stack_class_register(test_device_classes[test_n].class_name, test_device_classes[test_n].class_entry_function,
1085                                                  test_device_classes[test_n].configuration_number, test_device_classes[test_n].interface_number,
1086                                                  &parameter);
1087 
1088         if(status!=UX_SUCCESS)
1089         {
1090 
1091             printf("ERROR #%d\n", __LINE__);
1092             test_control_return(1);
1093         }
1094     }
1095 
1096     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1097     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1098                                             1,0,  &parameter);
1099 
1100     if(status == UX_SUCCESS)
1101     {
1102 
1103         printf("ERROR #%d: register more than %d class should report error\n", __LINE__, UX_MAX_SLAVE_CLASS_DRIVER);
1104         test_control_return(1);
1105     }
1106 
1107     for (test_n = 0; test_n < UX_MAX_SLAVE_CLASS_DRIVER; test_n ++)
1108     {
1109         stepinfo(" .dStackClassUnReg %2ld / %2d\n", test_n, UX_MAX_SLAVE_CLASS_DRIVER - 1);
1110 
1111         /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1112         status =  ux_device_stack_class_unregister(test_device_classes[UX_MAX_SLAVE_CLASS_DRIVER - 1 - test_n].class_name,
1113                                                    test_device_classes[UX_MAX_SLAVE_CLASS_DRIVER - 1 - test_n].class_entry_function);
1114 
1115         if(status!=UX_SUCCESS)
1116         {
1117 
1118             printf("ERROR #%d\n", __LINE__);
1119             test_control_return(1);
1120         }
1121     }
1122 
1123     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
1124 
1125     if(status == UX_SUCCESS)
1126     {
1127 
1128         printf("ERROR #%d: unregister none exist class should report error\n", __LINE__);
1129         test_control_return(1);
1130     }
1131 
1132     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_entry,
1133                                              1,0,  &parameter);
1134     if(status != UX_SUCCESS)
1135     {
1136 
1137         printf("ERROR #%d\n", __LINE__);
1138         test_control_return(1);
1139     }
1140 
1141     device_class_entry_return = UX_ERROR;
1142     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_entry);
1143     if(status == UX_SUCCESS)
1144     {
1145 
1146         printf("ERROR #%d\n", __LINE__);
1147         test_control_return(1);
1148     }
1149     device_class_entry_return = UX_SUCCESS;
1150     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
1151     if(status != UX_SUCCESS)
1152     {
1153 
1154         printf("ERROR #%d\n", __LINE__);
1155         test_control_return(1);
1156     }
1157 
1158     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1159     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1160                                             1,0,  &parameter);
1161 
1162     if(status != UX_SUCCESS)
1163     {
1164 
1165         printf("ERROR #%d: register more than %d class should report error\n", __LINE__, UX_MAX_SLAVE_CLASS_DRIVER);
1166         test_control_return(1);
1167     }
1168 
1169 #if 0 /* FIXME: ? WHY Segmentation faul on _ux_utility_mutex_create(&_ux_system -> ux_system_mutex, "ux_mutex") */
1170     stepinfo(">>>>>>>>>>>>>>>> Uninitialize all\n");
1171     /* Missing HCD uninitialize (since initialize called on registering) */
1172     /* No need ux_host_stack_class_unregister, since there is no entry call */
1173     ux_device_stack_uninitialize();
1174     _ux_host_stack_uninitialize();
1175     _ux_system_uninitialize();
1176 
1177     stepinfo(">>>>>>>>>>>>>>>> ux_system_initialize\n");
1178     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
1179     if (status != UX_SUCCESS)
1180     {
1181 
1182         printf("ERROR #%d\n", __LINE__);
1183         test_control_return(1);
1184     }
1185     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_initialize\n");
1186     status =  ux_host_stack_initialize(test_host_change_function);
1187     if (status != UX_SUCCESS)
1188     {
1189 
1190         printf("ERROR #%d\n", __LINE__);
1191         test_control_return(1);
1192     }
1193     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_class_register\n");
1194     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
1195     if (status != UX_SUCCESS)
1196     {
1197 
1198         printf("ERROR #%d\n", __LINE__);
1199         test_control_return(1);
1200     }
1201     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_hcd_register\n");
1202     status =  ux_host_stack_hcd_register(test_hcds[test_n].hcd_name, test_hcds[test_n].hcd_init_function, test_hcds[test_n].hcd_param1, test_hcds[test_n].hcd_param2);
1203     if (status != UX_SUCCESS)
1204     {
1205 
1206         printf("ERROR #%d\n", __LINE__);
1207         test_control_return(1);
1208     }
1209     stepinfo(">>>>>>>>>>>>>>>> ux_device_stack_initialize\n");
1210     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1211                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1212                                        string_framework, STRING_FRAMEWORK_LENGTH,
1213                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1214     if(status!=UX_SUCCESS)
1215     {
1216 
1217         printf("ERROR #%d\n", __LINE__);
1218         test_control_return(1);
1219     }
1220     stepinfo(">>>>>>>>>>>>>>>> ux_device_stack_class_register\n");
1221     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1222                                              1,0,  &parameter);
1223 
1224     if(status!=UX_SUCCESS)
1225     {
1226 
1227         printf("ERROR #%d\n", __LINE__);
1228         test_control_return(1);
1229     }
1230 #endif
1231 
1232     stepinfo(">>>>>>>>>>>>>>>> Test _ux_test_dcd_sim_slave_initialize\n");
1233 
1234     /* Initialize the simulated device controller.  */
1235     status =  _ux_test_dcd_sim_slave_initialize();
1236 
1237     /* Check for error.  */
1238     if (status != TX_SUCCESS)
1239     {
1240 
1241         printf("ERROR #%d\n", __LINE__);
1242         test_control_return(1);
1243     }
1244 
1245     stepinfo(">>>>>>>>>>>>>>>> Test ux_host_stack_hcd_register\n");
1246 
1247     for (test_n = 0; test_n < UX_MAX_HCD; test_n ++)
1248     {
1249         stepinfo(" .hcdReg %2ld / %2d\n", test_n, UX_MAX_HCD - 1);
1250 
1251         status =  ux_host_stack_hcd_register(test_hcds[test_n].hcd_name, test_hcds[test_n].hcd_init_function, test_hcds[test_n].hcd_param1, test_hcds[test_n].hcd_param2);
1252         if (status != UX_SUCCESS)
1253         {
1254 
1255             printf("ERROR #%d\n", __LINE__);
1256             test_control_return(1);
1257         }
1258     }
1259 
1260     /* Register more will report error */
1261     status =  ux_host_stack_hcd_register(test_hcds[UX_MAX_HCD].hcd_name, test_hcds[UX_MAX_HCD].hcd_init_function, test_hcds[UX_MAX_HCD].hcd_param1, test_hcds[UX_MAX_HCD].hcd_param2);
1262     if (status == UX_SUCCESS)
1263     {
1264 
1265         printf("ERROR #%d: error should reported if try to add more than %d HCDs\n", __LINE__, UX_MAX_HCD);
1266         test_control_return(1);
1267     }
1268 
1269     /* Create the main host simulation thread.  */
1270     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
1271             stack_pointer, UX_DEMO_STACK_SIZE,
1272             20, 20, 1, TX_AUTO_START);
1273 
1274     /* Check for error.  */
1275     if (status != TX_SUCCESS)
1276     {
1277 
1278         printf("ERROR #%d\n", __LINE__);
1279         test_control_return(1);
1280     }
1281 
1282     /* Create the main slave simulation  thread.  */
1283     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
1284             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1285             20, 20, 1, TX_AUTO_START);
1286 
1287     /* Check for error.  */
1288     if (status != TX_SUCCESS)
1289     {
1290 
1291         printf("ERROR #%d\n", __LINE__);
1292         test_control_return(1);
1293     }
1294 }
1295 
tx_test_thread_host_simulation_entry(ULONG arg)1296 void  tx_test_thread_host_simulation_entry(ULONG arg)
1297 {
1298 
1299 UINT                                                status;
1300 ULONG                                               test_n;
1301 ULONG                                               mem_free;
1302 
1303     stepinfo("\n");
1304 
1305 #if UX_MAX_CLASS_DRIVER > 1 /* CDC is not first class ... */
1306     /* Test connect. */
1307     stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
1308     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1309     tx_thread_sleep(100);
1310     if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
1311     {
1312 
1313         printf("ERROR #%d: connection not detected\n", __LINE__);
1314         test_control_return(1);
1315     }
1316     mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1317 
1318     /* Test disconnect. */
1319     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
1320     ux_test_dcd_sim_slave_disconnect();
1321     ux_test_hcd_sim_host_disconnect();
1322     test_n = 10;
1323     while((cdc_acm_host_control || cdc_acm_host_data || cdc_acm_slave) && test_n --)
1324         tx_thread_sleep(10);
1325 
1326     if (cdc_acm_host_control || cdc_acm_host_data || cdc_acm_slave)
1327     {
1328 
1329         printf("ERROR #%d: instance not removed when disconnect, %p %p %p\n", __LINE__, cdc_acm_host_control, cdc_acm_host_data, cdc_acm_slave);
1330         test_control_return(1);
1331     }
1332     if (_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available <= mem_free)
1333     {
1334 
1335         printf("ERROR #%d: memory not freed when disconnect\n", __LINE__);
1336         test_control_return(1);
1337     }
1338 #endif
1339     /* Deinitialize the class.  */
1340     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
1341 
1342     /* Deinitialize the device side of usbx.  */
1343     _ux_device_stack_uninitialize();
1344 
1345     /* And finally the usbx system resources.  */
1346     _ux_system_uninitialize();
1347 
1348     /* Successful test.  */
1349     printf("SUCCESS!\n");
1350     test_control_return(0);
1351 
1352 }
1353 
tx_test_thread_slave_simulation_entry(ULONG arg)1354 void  tx_test_thread_slave_simulation_entry(ULONG arg)
1355 {
1356 
1357     while(1)
1358     {
1359 
1360         /* Sleep so ThreadX on Win32 will delete this thread. */
1361         tx_thread_sleep(10);
1362     }
1363 }
1364