1 /* This test is designed to test the BOS.  */
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 "ux_test.h"
10 #include "ux_test_utility_sim.h"
11 #include "ux_test_hcd_sim_host.h"
12 #include "ux_test_dcd_sim_slave.h"
13 #include "ux_host_class_dummy.h"
14 
15 
16 /* Define USBX test constants.  */
17 
18 #define UX_TEST_STACK_SIZE      4096
19 #define UX_TEST_BUFFER_SIZE     2048
20 #define UX_TEST_RUN             1
21 #define UX_TEST_MEMORY_SIZE     (64*1024)
22 
23 
24 /* Define the counters used in the test application...  */
25 
26 static ULONG                           thread_0_counter;
27 static ULONG                           thread_1_counter;
28 static ULONG                           error_counter;
29 
30 static UCHAR                           buffer[UX_TEST_BUFFER_SIZE];
31 
32 static UX_HOST_CLASS_DUMMY             *dummy;
33 
34 static UX_DEVICE                       *device;
35 
36 /* Define USBX test global variables.  */
37 
38 #define DW3(x)     (((x) >> 24) & 0xFFu)
39 #define DW2(x)     (((x) >> 16) & 0xFFu)
40 #define DW1(x)     (((x) >>  8) & 0xFFu)
41 #define DW0(x)     ( (x)        & 0xFFu)
42 #define W1(x)      (((x) >>  8) & 0xFFu)
43 #define W0(x)      ( (x)        & 0xFFu)
44 
45 #define _DEVICE_DESCRIPTOR \
46     /* Device descriptor.  */       \
47     18, UX_DEVICE_DESCRIPTOR_ITEM,  \
48     W0(0x201), W1(0x201),           \
49     UX_CLASS_BILLBOARD_CLASS,       \
50     UX_CLASS_BILLBOARD_SUBCLASS,    \
51     UX_CLASS_BILLBOARD_PROTOCOL,    \
52     64,                             \
53     W0(0xec08), W1(0xec08),         \
54     W0(0x0001), W1(0x0001),         \
55     W0(0x0001), W1(0x0001),         \
56     0, 0, 0,                        \
57     1
58 
59 #define _DEVICE_QUALIFIER_DESCRIPTOR \
60     /* Device Qualifier Descriptor.  */     \
61     10, UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM,\
62     W0(0x201), W1(0x201),                   \
63     UX_CLASS_BILLBOARD_CLASS,               \
64     UX_CLASS_BILLBOARD_SUBCLASS,            \
65     UX_CLASS_BILLBOARD_PROTOCOL,            \
66     8,                                      \
67     1,                                      \
68     0
69 
70 #define _CONFIGURATION_DESCRIPTOR_LENGTH (9+9+7*4)
71 #define _CONFIGURATION_DESCRIPTOR \
72     /* Configuration Descriptor.  */        \
73     9, UX_CONFIGURATION_DESCRIPTOR_ITEM,    \
74     W0(_CONFIGURATION_DESCRIPTOR_LENGTH),   \
75     W1(_CONFIGURATION_DESCRIPTOR_LENGTH),   \
76     1, 1,                                   \
77     0, 0xc0, 0x32
78 
79 #define _INTERFACE_DESCRIPTOR   \
80     /* Interface Descriptor.  */    \
81     9, UX_INTERFACE_DESCRIPTOR_ITEM,\
82     0, 0, 4,                        \
83     UX_CLASS_BILLBOARD_CLASS,       \
84     UX_CLASS_BILLBOARD_SUBCLASS,    \
85     UX_CLASS_BILLBOARD_PROTOCOL,    \
86     0
87 
88 #define _ENDPOINT_DESCRIPTOR(addr,attr,mps,interval) \
89     /* Endpoint descriptor.  */     \
90     7, UX_ENDPOINT_DESCRIPTOR_ITEM, \
91     (addr), (attr),                 \
92     W0(mps), W1(mps),               \
93     (interval)
94 
95 #define _BOS_DESCRIPTORS_LENGTH (5+7+56+8+8+8)
96 #define _BOS_DESCRIPTORS \
97     /* BOS descriptor.  */                                      \
98     5, UX_BOS_DESCRIPTOR_ITEM,                                  \
99     W0(_BOS_DESCRIPTORS_LENGTH), W1(_BOS_DESCRIPTORS_LENGTH), 1,\
100     /* USB 2.0 Extension descriptor  */                                       \
101     7, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_USB_2_0_EXTENSION, \
102     DW0(0x00000002u), DW1(0x00000002u), DW2(0x00000002u), DW3(0x00000002u),   \
103     /* Billboard Capability Descriptor Example (44+3*4=56)  */\
104     56, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD, 0,   \
105     1, 0,                                                                   \
106     W0(0), W1(0),                                                           \
107     0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
108     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
109     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
110     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
111     W0(0x0000), W0(0x0000),                                                 \
112     0x00, 0x00,                                                             \
113     W0(0x8087), W1(0x8087), 0x00, 0x00,                                     \
114     W0(0x8087), W1(0x8087), 0x01, 0x00,                                     \
115     W0(0xFF01), W1(0xFF01), 0x00, 0x00,                                     \
116     /* Billboard Alternate Mode Capability Descriptor Examples  */\
117     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
118     0, DW0(0x00000010), DW1(0x00000010), DW2(0x00000010), DW3(0x00000010),  \
119     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
120     1, DW0(0x00000002), DW1(0x00000002), DW2(0x00000002), DW3(0x00000002),  \
121     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
122     2, DW0(0x000C00C5), DW1(0x000C00C5), DW2(0x000C00C5), DW3(0x000C00C5)
123 
124 
125 static UCHAR device_framework_full_speed[] = {
126 
127     _DEVICE_DESCRIPTOR,
128     _BOS_DESCRIPTORS,
129     _CONFIGURATION_DESCRIPTOR,
130     _INTERFACE_DESCRIPTOR,
131     _ENDPOINT_DESCRIPTOR(0x81, 0, 8, 0), /* Control.  */
132     _ENDPOINT_DESCRIPTOR(0x82, 1, 8, 1), /* Isochronous.  */
133     _ENDPOINT_DESCRIPTOR(0x83, 2, 8, 0), /* Bulk.  */
134     _ENDPOINT_DESCRIPTOR(0x84, 3, 8, 1), /* Interrupt.  */
135 };
136 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
137 
138 static UCHAR device_framework_high_speed[] = {
139 
140     _DEVICE_DESCRIPTOR,
141     _BOS_DESCRIPTORS,
142     _DEVICE_QUALIFIER_DESCRIPTOR,
143     _CONFIGURATION_DESCRIPTOR,
144     _INTERFACE_DESCRIPTOR,
145     _ENDPOINT_DESCRIPTOR(0x81, 0, 8, 0), /* Control.  */
146     _ENDPOINT_DESCRIPTOR(0x82, 1, 8, 1), /* Isochronous.  */
147     _ENDPOINT_DESCRIPTOR(0x83, 2, 8, 0), /* Bulk.  */
148     _ENDPOINT_DESCRIPTOR(0x84, 3, 8, 1), /* Interrupt.  */
149 };
150 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
151 
152 #define _INT_INTERVAL_B_OFFSET      (-1)
153 #define _INT_MPS_B_OFFSET           (-3)
154 #define _BULK_MPS_B_OFFSET          (_INT_MPS_B_OFFSET-7)
155 #define _ISO_INTERVAL_B_OFFSET      (_INT_INTERVAL_B_OFFSET-2*7)
156 #define _ISO_MPS_B_OFFSET           (_BULK_MPS_B_OFFSET-7)
157 #define _CTRL_MPS_B_OFFSET          (_ISO_MPS_B_OFFSET-7)
158 
159 
160 /* String Device Framework :
161      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
162      Byte 2       : Byte containing the index of the descriptor
163      Byte 3       : Byte containing the length of the descriptor string
164 */
165 static UCHAR string_framework[] = {
166 
167     /* Manufacturer string descriptor : Index 1 */
168         0x09, 0x04, 0x01, 0x0c,
169         0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
170         0x6f, 0x67, 0x69, 0x63,
171 
172     /* Product string descriptor : Index 2 */
173         0x09, 0x04, 0x02, 0x0c,
174         0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
175         0x44, 0x65, 0x6d, 0x6f,
176 
177     /* Serial Number string descriptor : Index 3 */
178         0x09, 0x04, 0x03, 0x04,
179         0x30, 0x30, 0x30, 0x31
180 };
181 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
182 
183 
184 /* Multiple languages are supported on the device, to add
185        a language besides English, the unicode language code must
186        be appended to the language_id_framework array and the length
187        adjusted accordingly. */
188 static UCHAR language_id_framework[] = {
189 
190     /* English. */
191         0x09, 0x04
192 };
193 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
194 
195 
196 /* Define prototypes for external Host Controller's (HCDs), classes and clients.  */
197 
198 static TX_THREAD           ux_test_thread_host_simulation;
199 static TX_THREAD           ux_test_thread_slave_simulation;
200 static void                ux_test_thread_host_simulation_entry(ULONG);
201 static void                ux_test_thread_slave_simulation_entry(ULONG);
202 
203 static UINT                test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst);
204 
205 /* Define the ISR dispatch.  */
206 
207 extern VOID    (*test_isr_dispatch)(void);
208 
209 
210 /* Prototype for test control return.  */
211 
212 void  test_control_return(UINT status);
213 
214 
215 /* Define the ISR dispatch routine.  */
216 
test_isr(void)217 static void    test_isr(void)
218 {
219 
220     /* For further expansion of interrupt-level testing.  */
221 }
222 
223 static ULONG enum_done_count = 0;
error_callback(UINT system_level,UINT system_context,UINT error_code)224 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
225 {
226     if (error_code == UX_DEVICE_ENUMERATION_FAILURE)
227         enum_done_count ++;
228 
229     if (error_code != UX_DEVICE_HANDLE_UNKNOWN &&
230         error_code != UX_DEVICE_ENUMERATION_FAILURE)
231     {
232         /* Failed test.  */
233         printf("Error #%d, system_level: %d, system_context: %d, error code: 0x%x\n", __LINE__, system_level, system_context, error_code);
234         test_control_return(1);
235     }
236 }
237 
238 /* Define what the initial system looks like.  */
239 
240 #ifdef CTEST
test_application_define(void * first_unused_memory)241 void test_application_define(void *first_unused_memory)
242 #else
243 void    usbx_ux_host_stack_enum_bMaxPacketSize0_application_define(void *first_unused_memory)
244 #endif
245 {
246 
247 UINT status;
248 CHAR                            *stack_pointer;
249 CHAR                            *memory_pointer;
250 
251 
252     printf("Running ux_host_stack wMaxPacketSize Test...........................");
253 
254     /* Initialize the free memory pointer.  */
255     stack_pointer = (CHAR *) first_unused_memory;
256     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
257 
258     /* Initialize USBX Memory.  */
259     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
260 
261     /* Check for error.  */
262     if (status != UX_SUCCESS)
263     {
264 
265         printf("ERROR #%d\n", __LINE__);
266         test_control_return(1);
267     }
268 
269     /* Register the error callback. */
270     _ux_utility_error_callback_register(error_callback);
271 
272     /* The code below is required for installing the host portion of USBX.  */
273     status =  ux_host_stack_initialize(test_host_change_function);
274 
275     /* Check for error.  */
276     if (status != UX_SUCCESS)
277     {
278 
279         printf("ERROR #%d\n", __LINE__);
280         test_control_return(1);
281     }
282 
283     /* Register a dummy class.  */
284     status  = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
285     UX_TEST_CHECK_SUCCESS(status);
286 
287     /* The code below is required for installing the device portion of USBX */
288     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
289                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
290                                        string_framework, STRING_FRAMEWORK_LENGTH,
291                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
292 
293     /* Check for error.  */
294     if (status != UX_SUCCESS)
295     {
296 
297         printf("ERROR #%d\n", __LINE__);
298         test_control_return(1);
299     }
300 
301     /* Initialize the simulated device controller.  */
302     status =  _ux_dcd_sim_slave_initialize();
303 
304     /* Check for error.  */
305     if (status != UX_SUCCESS)
306     {
307 
308         printf("ERROR #%d\n", __LINE__);
309         test_control_return(1);
310     }
311 
312     /* Register all the USB host controllers available in this system */
313     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
314 
315     /* Check for error.  */
316     if (status != UX_SUCCESS)
317     {
318 
319         printf("ERROR #%d\n", __LINE__);
320         test_control_return(1);
321     }
322 
323     /* Create the main host simulation thread.  */
324     status =  tx_thread_create(&ux_test_thread_host_simulation, "test host simulation", ux_test_thread_host_simulation_entry, 0,
325             stack_pointer, UX_TEST_STACK_SIZE,
326             20, 20, 1, TX_AUTO_START);
327 
328     /* Check for error.  */
329     if (status != TX_SUCCESS)
330     {
331 
332         printf("ERROR #%d\n", __LINE__);
333         test_control_return(1);
334     }
335 }
336 
ux_test_thread_host_simulation_entry(ULONG arg)337 static void  ux_test_thread_host_simulation_entry(ULONG arg)
338 {
339 
340 UINT                    status;
341 INT                     i, offset;
342 ULONG                   mem_free;
343 const struct _test {
344     ULONG               speed;
345     ULONG               bmAttributes;
346     INT                 wMaxPacketSize_offset;
347     ULONG               wMaxPacketSize;
348     ULONG               bInterval;
349     UINT                expect_no_device;
350 } tests[] = {
351     /* Control endpoint.  */
352     {UX_FULL_SPEED_DEVICE, 0, _CTRL_MPS_B_OFFSET,   0, 0, UX_FALSE},
353     {UX_FULL_SPEED_DEVICE, 0, _CTRL_MPS_B_OFFSET,   8, 0, UX_FALSE},
354     {UX_FULL_SPEED_DEVICE, 0, _CTRL_MPS_B_OFFSET,  16, 0, UX_FALSE},
355     {UX_FULL_SPEED_DEVICE, 0, _CTRL_MPS_B_OFFSET,  20, 0, UX_FALSE},
356     /* Bulk endpoint.  */
357     {UX_FULL_SPEED_DEVICE, 1, _BULK_MPS_B_OFFSET,   0, 0, UX_FALSE},
358     {UX_FULL_SPEED_DEVICE, 1, _BULK_MPS_B_OFFSET,  64, 0, UX_FALSE},
359     {UX_HIGH_SPEED_DEVICE, 1, _BULK_MPS_B_OFFSET, 512, 0, UX_FALSE},
360     {UX_HIGH_SPEED_DEVICE, 1, _BULK_MPS_B_OFFSET, 960, 0, UX_FALSE},
361     {UX_FULL_SPEED_DEVICE, 1, _BULK_MPS_B_OFFSET,  20, 0, UX_FALSE},
362     /* Interrupt endpoint.  */
363     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,   0        , 0, UX_FALSE},
364     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,   0        , 1, UX_FALSE},
365     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  32        , 0, UX_FALSE},
366     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  32        , 1, UX_FALSE},
367     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  32        ,16, UX_FALSE},
368     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  32        ,17, UX_FALSE},
369     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  32        ,17, UX_FALSE},
370     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,1024        , 1, UX_FALSE},
371     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,1025        , 1, UX_FALSE},
372     {UX_FULL_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,  20        , 1, UX_FALSE},
373     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET ,1024|(1<<11), 1, UX_FALSE},
374     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET , 128|(2<<11), 1, UX_FALSE},
375     {UX_HIGH_SPEED_DEVICE, 2, _INT_MPS_B_OFFSET , 512|(3<<11), 1, UX_FALSE},
376     /* Isochronous endpoint.  */
377     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,   0        , 0, UX_FALSE},
378     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,   0        , 1, UX_FALSE},
379     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  32        , 0, UX_FALSE},
380     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  32        ,17, UX_FALSE},
381     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  32        , 1, UX_FALSE},
382     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  32        ,16, UX_FALSE},
383     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  32        ,17, UX_FALSE},
384     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,1025        , 1, UX_FALSE},
385     {UX_FULL_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,  20        , 1, UX_FALSE},
386     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET ,1024|(1<<11), 1, UX_FALSE},
387     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET , 128|(2<<11), 1, UX_FALSE},
388     {UX_HIGH_SPEED_DEVICE, 3, _ISO_MPS_B_OFFSET , 512|(3<<11), 1, UX_FALSE},
389 };
390 #define N_TESTS (sizeof(tests)/sizeof(struct _test))
391 
392     /* Wait device connection.  */
393     stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
394     status = ux_test_wait_for_value_ulong(&enum_done_count, 1);
395     if (status != UX_SUCCESS)
396     {
397         printf("ERROR #%d\n", __LINE__);
398         test_control_return(1);
399     }
400 
401     /* Test disconnect. */
402     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
403     ux_test_dcd_sim_slave_disconnect();
404     ux_test_hcd_sim_host_disconnect();
405     status = ux_test_wait_for_null_wait_time((VOID**)&device, 1100);
406     if (status != UX_SUCCESS)
407     {
408         printf("ERROR #%d\n", __LINE__);
409         test_control_return(1);
410     }
411     mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
412 
413     for (i = 0; i < N_TESTS; i ++)
414     {
415         // printf("Test %d\n", i);
416 
417         enum_done_count = 0;
418         if (tests[i].speed == UX_HIGH_SPEED_DEVICE)
419         {
420             offset = DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED;
421             offset += tests[i].wMaxPacketSize_offset;
422             _ux_utility_short_put(device_framework_high_speed + offset, tests[i].wMaxPacketSize);
423             device_framework_high_speed[offset + 2] = tests[i].bInterval;
424 
425             // for (INT n = offset - 4; n < offset + 3; n ++)
426             //     printf(" %2x", device_framework_high_speed[n]);
427             // printf("\n");
428         }
429         else
430         {
431             offset = DEVICE_FRAMEWORK_LENGTH_FULL_SPEED;
432             offset += tests[i].wMaxPacketSize_offset;
433             _ux_utility_short_put(device_framework_full_speed + offset, tests[i].wMaxPacketSize);
434             device_framework_full_speed[offset + 2] = tests[i].bInterval;
435 
436             // for (INT n = offset - 4; n < offset + 3; n ++)
437             //     printf(" %2x", device_framework_full_speed[n]);
438             // printf("\n");
439         }
440         ux_test_dcd_sim_slave_connect(tests[i].speed);
441         ux_test_hcd_sim_host_connect(tests[i].speed);
442 
443         status = ux_test_wait_for_value_ulong(&enum_done_count, 1);
444         if (status != UX_SUCCESS)
445         {
446             printf("ERROR #%d\n", __LINE__);
447             test_control_return(1);
448         }
449 
450         status = ux_host_stack_device_get(0, &device);
451         if (tests[i].expect_no_device)
452         {
453             if (status == UX_SUCCESS)
454             {
455                 printf("ERROR #%d\n", __LINE__);
456                 test_control_return(1);
457             }
458         }
459         else
460         {
461             if (status != UX_SUCCESS)
462             {
463                 printf("ERROR #%d\n", __LINE__);
464                 test_control_return(1);
465             }
466 
467             ux_test_dcd_sim_slave_disconnect();
468             ux_test_hcd_sim_host_disconnect();
469             status = ux_test_wait_for_null_wait_time((VOID**)&device, 3000);
470             if (status != UX_SUCCESS)
471             {
472                 printf("ERROR #%d\n", __LINE__);
473                 test_control_return(1);
474             }
475         }
476 
477         if (_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available != mem_free)
478         {
479             printf("ERROR #%d\n", __LINE__);
480             test_control_return(1);
481         }
482     }
483 
484     /* Sleep for a tick to make sure everything is complete.  */
485     tx_thread_sleep(1);
486 
487     /* Check for errors from other threads.  */
488     if (error_counter)
489     {
490 
491         /* Test error.  */
492         printf("ERROR #%d\n", __LINE__);
493         test_control_return(1);
494     }
495     else
496     {
497 
498         /* Successful test.  */
499         printf("SUCCESS\n");
500         test_control_return(0);
501     }
502 }
503 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)504 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
505 {
506 
507 UX_HOST_CLASS_DUMMY *dummy_ptr = (UX_HOST_CLASS_DUMMY *) inst;
508 
509     // printf("hCHG:%lx,%p,%p\n", event, cls, inst);
510     switch(event)
511     {
512 
513         case UX_DEVICE_INSERTION:
514 
515             // printf("hINS:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
516             if (dummy == UX_NULL)
517             {
518                 dummy = dummy_ptr;
519                 enum_done_count ++;
520             }
521             break;
522 
523         case UX_DEVICE_REMOVAL:
524 
525             // printf("hRMV:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
526             if (dummy == dummy_ptr)
527                 dummy = UX_NULL;
528             break;
529 
530         case UX_DEVICE_CONNECTION:
531             if (device == UX_NULL)
532                 device = (UX_DEVICE *)inst;
533             break;
534 
535         case UX_DEVICE_DISCONNECTION:
536             // printf("hDisc: %p <> %p\n", device, inst);
537             if ((VOID *)device == inst)
538                 device = UX_NULL;
539             break;
540 
541         default:
542             break;
543     }
544     return 0;
545 }
546