1 /* This test is designed to test the ux_utility_memory_.... */
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_device_class_dpump.h"
10 #include "ux_host_class_dpump.h"
11
12 #include "ux_host_stack.h"
13 #include "ux_hcd_sim_host.h"
14 #include "ux_test_hcd_sim_host.h"
15 #include "ux_test_utility_sim.h"
16
17
18 /* Define USBX test constants. */
19
20 #define UX_TEST_STACK_SIZE 4096
21 #define UX_TEST_MEMORY_SIZE (64*1024)
22
23 #define LSB(x) ( (x) & 0x00ff)
24 #define MSB(x) (((x) & 0xff00) >> 8)
25
26 /* Define the counters used in the test application... */
27
28 static ULONG thread_0_counter;
29 static ULONG thread_1_counter;
30 static ULONG error_counter;
31
32 static UCHAR error_callback_ignore = UX_FALSE;
33 static ULONG error_callback_counter;
34
35 static UCHAR bad_name[UX_MAX_HCD_NAME_LENGTH + 1];
36
37
38 /* Define USBX test global variables. */
39
40
41 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
42 static UCHAR device_framework_full_speed[] = {
43
44 /* Device descriptor */
45 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
46 0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x01,
48
49 /* Configuration descriptor */
50 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
51 0x32,
52
53 /* Interface descriptor */
54 0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
55 0x00,
56
57 /* Endpoint descriptor (Bulk Out) */
58 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
59
60 /* Endpoint descriptor (Bulk In) */
61 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00
62 };
63
64
65 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
66 static UCHAR device_framework_high_speed[] = {
67
68 /* Device descriptor */
69 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
70 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
71 0x03, 0x01,
72
73 /* Device qualifier descriptor */
74 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
75 0x01, 0x00,
76
77 /* Configuration descriptor */
78 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
79 0x32,
80
81 /* Interface descriptor */
82 0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
83 0x00,
84
85 /* Endpoint descriptor (Bulk Out) */
86 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
87
88 /* Endpoint descriptor (Bulk In) */
89 0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00
90 };
91
92 /* String Device Framework :
93 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
94 Byte 2 : Byte containing the index of the descriptor
95 Byte 3 : Byte containing the length of the descriptor string
96 */
97 #define STRING_FRAMEWORK_LENGTH 38
98 static UCHAR string_framework[] = {
99
100 /* Manufacturer string descriptor : Index 1 */
101 0x09, 0x04, 0x01, 0x0c,
102 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
103 0x6f, 0x67, 0x69, 0x63,
104
105 /* Product string descriptor : Index 2 */
106 0x09, 0x04, 0x02, 0x0c,
107 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
108 0x44, 0x65, 0x6d, 0x6f,
109
110 /* Serial Number string descriptor : Index 3 */
111 0x09, 0x04, 0x03, 0x04,
112 0x30, 0x30, 0x30, 0x31
113 };
114
115
116 /* Multiple languages are supported on the device, to add
117 a language besides English, the unicode language code must
118 be appended to the language_id_framework array and the length
119 adjusted accordingly. */
120 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
121 static UCHAR language_id_framework[] = {
122
123 /* English. */
124 0x09, 0x04
125 };
126
127 /* Actions/callbacks hook. */
128
129 static UX_TEST_SETUP _SetCfgDescriptor = UX_TEST_SETUP_SetConfigure;
130
ux_test_set_cfg_descriptor_invoked(UX_TEST_ACTION * action,VOID * params)131 static VOID ux_test_set_cfg_descriptor_invoked(UX_TEST_ACTION *action, VOID *params)
132 {
133 /* Unregister HCD. */
134 _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);;
135 }
136
137 static UX_TEST_HCD_SIM_ACTION hcd_unregister_while_enum[] = {
138 /* function, request to match,
139 port action, port status,
140 request action, request EP, request data, request actual length, request status,
141 status, additional callback,
142 no_return */
143 { UX_HCD_TRANSFER_REQUEST, &_SetCfgDescriptor,
144 UX_FALSE, 0,
145 UX_TEST_SETUP_MATCH_REQ_V_I, 0, UX_NULL, 0, UX_SUCCESS,
146 UX_SUCCESS, ux_test_set_cfg_descriptor_invoked,
147 .no_return = UX_TRUE,
148 .do_after = UX_FALSE},
149 { 0 }
150 };
151
152
153 /* Define prototypes for external Controller's (HCD/DCDs), classes and clients. */
154
155 static TX_THREAD ux_test_thread_simulation_0;
156 static void ux_test_thread_simulation_0_entry(ULONG);
157
158 static TX_THREAD ux_test_thread_simulation_1;
159 static void ux_test_thread_simulation_1_entry(ULONG);
160
161 static UX_SLAVE_CLASS_DPUMP *dpump_device = UX_NULL;
162 static VOID ux_test_dpump_instance_activate(VOID *dpump_instance);
163 static VOID ux_test_dpump_instance_deactivate(VOID *dpump_instance);
164
165 /* Prototype for test control return. */
166
167 void test_control_return(UINT status);
168
error_callback(UINT system_level,UINT system_context,UINT error_code)169 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
170 {
171
172 error_callback_counter ++;
173
174 if (!error_callback_ignore)
175 {
176 {
177 /* Failed test. */
178 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
179 }
180 }
181 }
182
183 /* Define what the initial system looks like. */
184
185 #ifdef CTEST
test_application_define(void * first_unused_memory)186 void test_application_define(void *first_unused_memory)
187 #else
188 void usbx_ux_host_stack_hcd_unregister_test_application_define(void *first_unused_memory)
189 #endif
190 {
191
192 UINT status;
193 UCHAR *stack_pointer;
194 UCHAR *memory_pointer;
195 UX_SLAVE_CLASS_DPUMP_PARAMETER parameter;
196
197
198 /* Inform user. */
199 printf("Running ux_host_stack_hcd_unregister Test........................... ");
200
201 /* Initialize the free memory pointer. */
202 stack_pointer = (CHAR *) first_unused_memory;
203 memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
204
205 /* Initialize USBX Memory. */
206 status = ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
207
208 /* Check for error. */
209 if (status != UX_SUCCESS)
210 {
211
212 printf("ERROR #%d: 0x%x\n", __LINE__, status);
213 test_control_return(1);
214 }
215
216 /* Register the error callback. */
217 _ux_utility_error_callback_register(error_callback);
218
219 /* The code below is required for installing the device portion of USBX */
220 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
221 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
222 string_framework, STRING_FRAMEWORK_LENGTH,
223 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
224 if (status != UX_SUCCESS)
225 {
226
227 printf("ERROR #%d: 0x%x\n", __LINE__, status);
228 test_control_return(1);
229 }
230
231 /* Set the parameters for callback when insertion/extraction of a Data Pump device. */
232 parameter.ux_slave_class_dpump_instance_activate = ux_test_dpump_instance_activate;
233 parameter.ux_slave_class_dpump_instance_deactivate = ux_test_dpump_instance_deactivate;
234
235 /* Initialize the device dpump class. The class is connected with interface 0 */
236 status = ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
237 1, 0, ¶meter);
238 if (status != UX_SUCCESS)
239 {
240
241 printf("ERROR #%d: 0x%x\n", __LINE__, status);
242 test_control_return(1);
243 }
244
245 /* Initialize the simulated device controller. */
246 status = _ux_dcd_sim_slave_initialize();
247
248 /* Check for error. */
249 if (status != UX_SUCCESS)
250 {
251
252 printf("ERROR #%d: 0x%x\n", __LINE__, status);
253 test_control_return(1);
254 }
255
256 /* Create the simulation thread. */
257 status = tx_thread_create(&ux_test_thread_simulation_0, "test simulation", ux_test_thread_simulation_0_entry, 0,
258 stack_pointer, UX_TEST_STACK_SIZE,
259 20, 20, 1, TX_AUTO_START);
260
261 /* Check for error. */
262 if (status != UX_SUCCESS)
263 {
264
265 printf("ERROR #%d: 0x%x\n", __LINE__, status);
266 test_control_return(1);
267 }
268 }
269
270 #define UX_TEST_CONN_PASS 0
271 #define UX_TEST_CONN_WAIT 1
272 #define UX_TEST_CONN_CHECK 2
ux_test_hcd_register(char * s,int line,int connection_wait)273 static void ux_test_hcd_register(char *s, int line, int connection_wait)
274 {
275 UINT status;
276 INT i;
277 UX_DEVICE *device;
278 char *nothing = "";
279 if (s == UX_NULL)
280 s = nothing;
281 status = _ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
282 if (status != UX_SUCCESS)
283 {
284 printf("ERROR #%s%d.%d: 0x%x\n", s, line, __LINE__, status);
285 test_control_return(1);
286 }
287 if (!connection_wait)
288 return;
289 /* Wait for connection. */
290 for (i = 0; i < 100; i ++)
291 {
292 tx_thread_sleep(UX_MS_TO_TICK_NON_ZERO(10));
293 status = _ux_host_stack_device_get(0, &device);
294 if (status == UX_SUCCESS && dpump_device != UX_NULL)
295 break;
296 }
297 if (connection_wait > UX_TEST_CONN_WAIT)
298 {
299 if (dpump_device == UX_NULL)
300 {
301 printf("ERROR #%s%d.%d\n", s, line, __LINE__);
302 test_control_return(1);
303 }
304 if (status != UX_SUCCESS || device == UX_NULL)
305 {
306 printf("ERROR #%s%d.%d\n", s, line, __LINE__);
307 test_control_return(1);
308 }
309 }
310 }
311
entry_function(UX_HCD * hcd,UINT function,VOID * parameter)312 static UINT entry_function(UX_HCD* hcd, UINT function, VOID* parameter)
313 {
314 return(UX_SUCCESS);
315
316
317 }
318
ux_test_thread_simulation_0_entry(ULONG arg)319 static void ux_test_thread_simulation_0_entry(ULONG arg)
320 {
321
322 UINT status;
323 ULONG rfree;
324 INT i, try;
325 char hdr[64];
326 UX_DEVICE *device;
327
328
329 /* Initialize host stack. */
330 status = ux_host_stack_initialize(UX_NULL);
331 if (status != UX_SUCCESS)
332 {
333 printf("ERROR #%d: 0x%x\n", __LINE__, status);
334 test_control_return(1);
335 }
336
337 /* Register all the host class drivers for this USBX implementation. */
338 status = ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
339 if (status != UX_SUCCESS)
340 {
341 printf("ERROR #%d: 0x%x\n", __LINE__, status);
342 test_control_return(1);
343 }
344
345 /************************** Register & unregister (no device connected). */
346
347 /* Log memory level to check. */
348 rfree = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
349
350 /* Provent HCD & ENUM thread to run. */
351 _ux_utility_thread_suspend(&_ux_system_host -> ux_system_host_hcd_thread);
352 _ux_utility_thread_suspend(&_ux_system_host -> ux_system_host_enum_thread);
353
354 /* Register. */
355 ux_test_hcd_register(UX_NULL, __LINE__, UX_TEST_CONN_PASS);
356
357 /* Unregister. */
358 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
359 if (status != UX_SUCCESS)
360 {
361 printf("ERROR #%d: 0x%x\n", __LINE__, status);
362 test_control_return(1);
363 }
364
365 if (rfree != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
366 {
367 printf("ERROR #%d\n", __LINE__);
368 test_control_return(1);
369 }
370
371 /* Clear semaphore by init. */
372 _ux_utility_semaphore_get(&_ux_system_host -> ux_system_host_enum_semaphore, 0);
373
374 /* Resume threads. */
375 _ux_utility_thread_resume(&_ux_system_host -> ux_system_host_hcd_thread);
376 _ux_utility_thread_resume(&_ux_system_host -> ux_system_host_enum_thread);
377
378 /************************** Register & unregister (device connected). */
379
380 /* Register HCD. */
381 ux_test_hcd_register(UX_NULL, __LINE__, UX_TEST_CONN_CHECK);
382
383 /* Error ignore, there should be UX_CONTROLLER_UNKNOWN. */
384 error_callback_ignore = UX_TRUE;
385
386 /* Unregister HCD. */
387 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
388 if (status != UX_SUCCESS)
389 {
390 printf("ERROR #%d: 0x%x\n", __LINE__, status);
391 test_control_return(1);
392 }
393
394 /* Get host device. */
395 status = _ux_host_stack_device_get(0, &device);
396 if (status != UX_DEVICE_HANDLE_UNKNOWN)
397 {
398 printf("ERROR #%d: 0x%x\n", __LINE__, status);
399 test_control_return(1);
400 }
401
402 /************************** Unregister HCD not found. */
403
404 /* Unregister HCD. */
405 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_ehci_name, 0, 0);
406 if (status == UX_SUCCESS)
407 {
408 printf("ERROR #%d: 0x%x\n", __LINE__, status);
409 test_control_return(1);
410 }
411
412 /************************** Unregister HCD bad name. */
413
414 /* Bad string (error callback reported). */
415 _ux_utility_memory_set(bad_name, '0', UX_MAX_HCD_NAME_LENGTH + 1);
416
417 /* Unregister HCD. */
418 status = _ux_host_stack_hcd_unregister(bad_name, 0, 0);
419 if (status == UX_SUCCESS)
420 {
421 printf("ERROR #%d: 0x%x\n", __LINE__, status);
422 test_control_return(1);
423 }
424
425 /************************** Unregister HCD other cases not tested. */
426 /* E.g., HCD name match but parameters not, HCD parameters match but name not. */
427 /* E.g., All connected devices are not rooted from the HCD to unregister. */
428
429 /* No error ignore. */
430 error_callback_ignore = UX_FALSE;
431
432 /************************** Register & unregister several times (not corrupted). */
433
434 // ux_test_dcd_sim_slave_disconnect();
435 // ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
436
437 for (try = 0; try < 4; try ++)
438 {
439 // printf("#%d.%d\n", try, __LINE__);
440 sprintf(hdr, "%i", try);
441
442 /* Log memory level to check. */
443 rfree = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
444
445 /* Register HCD. */
446 ux_test_hcd_register(hdr, __LINE__, UX_TEST_CONN_CHECK);
447
448 error_callback_ignore = UX_TRUE;
449
450 if(try < 3)
451 /* Unregister HCD. */
452 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
453 else
454 {
455 /* Test line 127 */
456 _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 1, 0);
457
458 /* Test line 128 */
459 _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 1);
460
461 /* Test line 138 */
462 _ux_host_stack_hcd_unregister("noname", 0, 0);
463
464 /* ALl previous 3 calls would fail. Call the unregister again to properly
465 unregister this HCD. */
466 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
467
468 }
469
470 if (status != UX_SUCCESS)
471 {
472 printf("ERROR #%d.%d: 0x%x\n", try, __LINE__, status);
473 test_control_return(1);
474 }
475
476
477 /* Get host device. */
478 status = _ux_host_stack_device_get(0, &device);
479 if (status != UX_DEVICE_HANDLE_UNKNOWN)
480 {
481 printf("ERROR #%d.%d: 0x%x\n", try, __LINE__, status);
482 test_control_return(1);
483 }
484
485 /* Check memory level. */
486 if (rfree != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
487 {
488 printf("ERROR #%d.%d\n", try, __LINE__);
489 test_control_return(1);
490 }
491
492 error_callback_ignore = UX_FALSE;
493
494 // ux_test_dcd_sim_slave_disconnect();
495 // ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
496
497 } /* for (try = 0; try < 3; try ++) */
498
499 /************************** Register & unregister when enumeration in progress. */
500
501 /* Log memory level to check. */
502 rfree = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
503
504 /* Capture GetDeviceDescriptor and unregister HCD at that time. */
505 ux_test_hcd_sim_host_set_actions(hcd_unregister_while_enum);
506
507 /* Register HCD. */
508 error_callback_ignore = UX_TRUE;
509 ux_test_hcd_register(UX_NULL, __LINE__, UX_TEST_CONN_WAIT);
510
511 /* Get host device. */
512 status = _ux_host_stack_device_get(0, &device);
513 if (status != UX_DEVICE_HANDLE_UNKNOWN)
514 {
515 printf("ERROR #%d: 0x%x\n", __LINE__, status);
516 test_control_return(1);
517 }
518 error_callback_ignore = UX_FALSE;
519
520 /* Check memory level. */
521 if (rfree != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
522 {
523 printf("ERROR #%d\n", __LINE__);
524 test_control_return(1);
525 }
526
527 #if UX_MAX_HCD > 1 && UX_MAX_DEVICES > 1
528
529 /************************** Unregister all devices on HCD RH. */
530
531 /* Skip first slot, to use later device slots. */
532 _ux_system_host->ux_system_host_device_array[0].ux_device_handle = UX_USED;
533
534 /* Register several HCD. */
535 ux_test_hcd_register("", __LINE__, UX_TEST_CONN_CHECK);
536 status = _ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,1,0);
537 if (status != UX_SUCCESS)
538 {
539 printf("ERROR #%d: 0x%x\n", __LINE__, status);
540 test_control_return(1);
541 }
542 if (_ux_system_host->ux_system_host_device_array[1].ux_device_handle == UX_UNUSED)
543 {
544 printf("ERROR #%d\n", __LINE__);
545 test_control_return(1);
546 }
547
548 /* Mark slot free. */
549 _ux_system_host->ux_system_host_device_array[0].ux_device_handle = UX_UNUSED;
550
551 /* Unregister HCD, device on slot 1 is removed. */
552 error_callback_ignore = UX_TRUE;
553 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
554 error_callback_ignore = UX_FALSE;
555 if (status != UX_SUCCESS)
556 {
557 printf("ERROR #%d: 0x%x\n", __LINE__, status);
558 test_control_return(1);
559 }
560
561 /* Device should be removed. */
562 if (_ux_system_host->ux_system_host_device_array[1].ux_device_handle != UX_UNUSED)
563 {
564 printf("ERROR #%d\n", __LINE__);
565 test_control_return(1);
566 }
567 #endif
568
569 {
570 UX_HCD* hcd;
571 UX_DEVICE* device;
572
573 hcd = _ux_system_host->ux_system_host_hcd_array;
574 hcd->ux_hcd_status = UX_USED;
575 hcd->ux_hcd_io = 0;
576 hcd->ux_hcd_irq = 0;
577 hcd->ux_hcd_entry_function = entry_function;
578 strcpy(hcd->ux_hcd_name, _ux_system_host_hcd_simulator_name);
579 device = _ux_system_host->ux_system_host_device_array;
580
581 #if UX_MAX_DEVICES>1
582 device->ux_device_hcd = hcd;
583 #endif
584 #if UX_MAX_DEVICES>1
585 if (_ux_system_host->ux_system_host_max_devices == 0)
586 {
587 printf("ERROR #%d: ux_system_host_max_devices= %ld errors\n", __LINE__, _ux_system_host->ux_system_host_max_devices);
588 test_control_return(1);
589
590 }
591 device->ux_device_parent = device;
592
593 #endif
594 device->ux_device_handle = 1;
595
596 status = _ux_host_stack_hcd_unregister(_ux_system_host_hcd_simulator_name, 0, 0);
597 if(status)
598 error_counter++;
599 }
600 /* Check for errors from other threads. */
601 if (error_counter)
602 {
603
604 /* Test error. */
605 printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
606 test_control_return(1);
607 }
608 else
609 {
610
611 /* Successful test. */
612 printf("SUCCESS!\n");
613 test_control_return(0);
614 }
615
616
617 }
618
619
ux_test_dpump_instance_activate(VOID * dpump_instance)620 static VOID ux_test_dpump_instance_activate(VOID *dpump_instance)
621 {
622
623 /* Save the DPUMP instance. */
624 dpump_device = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
625 }
626
ux_test_dpump_instance_deactivate(VOID * dpump_instance)627 static VOID ux_test_dpump_instance_deactivate(VOID *dpump_instance)
628 {
629
630 /* Reset the DPUMP instance. */
631 dpump_device = UX_NULL;
632 }
633