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_storage.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_class_storage.h"
14
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18
19 /* Define constants. */
20 #define UX_DEMO_STACK_SIZE 2048
21 #define UX_DEMO_MEMORY_SIZE (256*1024)
22 #define UX_DEMO_BUFFER_SIZE 2048
23
24 #define UX_RAM_DISK_SIZE (200 * 1024)
25 #define UX_RAM_DISK_LAST_LBA ((UX_RAM_DISK_SIZE / 512) -1)
26
27 /* Define local/extern function prototypes. */
28 VOID _fx_ram_driver(FX_MEDIA *media_ptr);
29
30 static void demo_thread_entry(ULONG);
31 static TX_THREAD tx_demo_thread_host_simulation;
32 static TX_THREAD tx_demo_thread_slave_simulation;
33 static void tx_demo_thread_host_simulation_entry(ULONG);
34
35 static UINT demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
36 static UINT demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
37 static UINT demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
38
39 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
40
41 /* Define global data structures. */
42
43 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
44
45 static ULONG error_counter;
46
47 static TX_THREAD demo_thread;
48
49 static UX_HOST_CLASS_STORAGE *storage;
50 static UX_SLAVE_CLASS_STORAGE_PARAMETER global_storage_parameter;
51
52 static FX_MEDIA ram_disk1;
53 static FX_MEDIA ram_disk2;
54 static CHAR ram_disk_memory1[UX_RAM_DISK_SIZE];
55 static CHAR ram_disk_memory2[UX_RAM_DISK_SIZE];
56 static UCHAR buffer1[512];
57 static UCHAR buffer2[512];
58
59 static FX_MEDIA *ram_disks[] = {&ram_disk1, &ram_disk2};
60 static UCHAR *buffers[] = {buffer1, buffer2};
61 static CHAR *ram_disk_memory[] = { ram_disk_memory1, ram_disk_memory2 };
62
63 static ULONG set_cfg_counter;
64
65 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
66 static ULONG rsc_sem_on_set_cfg;
67 static ULONG rsc_sem_get_on_set_cfg;
68 static ULONG rsc_mutex_on_set_cfg;
69
70 static ULONG rsc_enum_sem_usage;
71 static ULONG rsc_enum_sem_get_count;
72 static ULONG rsc_enum_mutex_usage;
73 static ULONG rsc_enum_mem_alloc_count;
74
75 static ULONG rsc_storage_sem_usage;
76 static ULONG rsc_storage_sem_get_count;
77 static ULONG rsc_storage_mutex_usage;
78 static ULONG rsc_storage_mem_alloc_count;
79
80 static ULONG interaction_count;
81
82 static UCHAR error_callback_ignore = UX_TRUE;
83 static ULONG error_callback_counter;
84
85 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
86 static UCHAR device_framework_full_speed[] = {
87
88 /* Device descriptor */
89 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
90 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
91 0x03, 0x01,
92
93 /* Configuration descriptor */
94 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
95 0x32,
96
97 /* Interface descriptor */
98 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
99 0x00,
100
101 /* Endpoint descriptor (Bulk In) */
102 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
103
104 /* Endpoint descriptor (Bulk Out) */
105 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00
106
107 };
108
109
110 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
111 static UCHAR device_framework_high_speed[] = {
112
113 /* Device descriptor */
114 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
115 0x81, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
116 0x03, 0x01,
117
118 /* Device qualifier descriptor */
119 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
120 0x01, 0x00,
121
122 /* Configuration descriptor */
123 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
124 0x32,
125
126 /* Interface descriptor */
127 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
128 0x00,
129
130 /* Endpoint descriptor (Bulk In) */
131 0x07, 0x05, 0x81, 0x02, 0x00, 0x01, 0x00,
132
133 /* Endpoint descriptor (Bulk Out) */
134 0x07, 0x05, 0x02, 0x02, 0x00, 0x01, 0x00
135
136 };
137
138
139 /* String Device Framework :
140 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
141 Byte 2 : Byte containing the index of the descriptor
142 Byte 3 : Byte containing the length of the descriptor string
143 */
144
145 #define STRING_FRAMEWORK_LENGTH 38
146 static UCHAR string_framework[] = {
147
148 /* Manufacturer string descriptor : Index 1 */
149 0x09, 0x04, 0x01, 0x0c,
150 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
151 0x6f, 0x67, 0x69, 0x63,
152
153 /* Product string descriptor : Index 2 */
154 0x09, 0x04, 0x02, 0x0a,
155 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x44, 0x69,
156 0x73, 0x6b,
157
158 /* Serial Number string descriptor : Index 3 */
159 0x09, 0x04, 0x03, 0x04,
160 0x30, 0x30, 0x30, 0x31
161 };
162
163
164 /* Multiple languages are supported on the device, to add
165 a language besides english, the unicode language code must
166 be appended to the language_id_framework array and the length
167 adjusted accordingly. */
168 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
169 static UCHAR language_id_framework[] = {
170
171 /* English. */
172 0x09, 0x04
173 };
174
175
176 /* Setup requests */
177
178 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
179
180 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
181 /* function, request to match,
182 port action, port status,
183 request action, request EP, request data, request actual length, request status,
184 status, additional callback,
185 no_return */
186 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
187 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
188 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
189 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
190 UX_TRUE}, /* Invoke callback & continue */
191 { 0 }
192 };
193
194
195
196 /* Define the ISR dispatch. */
197
198 extern VOID (*test_isr_dispatch)(void);
199
200
201 /* Prototype for test control return. */
202
203 void test_control_return(UINT status);
204
205
206 /* Define the ISR dispatch routine. */
207
test_isr(void)208 static void test_isr(void)
209 {
210
211 /* For further expansion of interrupt-level testing. */
212 }
213
214
error_callback(UINT system_level,UINT system_context,UINT error_code)215 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
216 {
217
218 error_callback_counter ++;
219
220 if (!error_callback_ignore)
221 {
222 {
223 /* Failed test. */
224 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
225 test_control_return(1);
226 }
227 }
228 }
229
host_storage_instance_get(ULONG timeout_x10ms)230 static UINT host_storage_instance_get(ULONG timeout_x10ms)
231 {
232
233 UINT status;
234 UX_HOST_CLASS *class;
235
236
237 /* Find the main storage container */
238 status = ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
239 if (status != UX_SUCCESS)
240 return(status);
241
242 /* Get storage instance, wait it to be live and media attached. */
243 do
244 {
245 if (timeout_x10ms)
246 {
247 ux_utility_delay_ms(10);
248 if (timeout_x10ms != 0xFFFFFFFF)
249 timeout_x10ms --;
250 }
251
252 status = ux_host_stack_class_instance_get(class, 0, (void **) &storage);
253 if (status == UX_SUCCESS)
254 {
255 if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_LIVE &&
256 class -> ux_host_class_ext != UX_NULL &&
257 class -> ux_host_class_media != UX_NULL)
258 return(UX_SUCCESS);
259 }
260
261 } while(timeout_x10ms > 0);
262
263 return(UX_ERROR);
264 }
265
sleep_break_on_error(VOID)266 static UINT sleep_break_on_error(VOID)
267 {
268
269 if (error_callback_counter >= 3)
270 return error_callback_counter;
271
272 return UX_SUCCESS;
273 }
274
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)275 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
276 {
277
278 set_cfg_counter ++;
279
280 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
281 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
282 rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
283 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
284 }
285
286
287 /* Define what the initial system looks like. */
288
289 #ifdef CTEST
test_application_define(void * first_unused_memory)290 void test_application_define(void *first_unused_memory)
291 #else
292 void usbx_storage_basic_memory_test_application_define(void *first_unused_memory)
293 #endif
294 {
295
296 UINT status;
297 CHAR * stack_pointer;
298 CHAR * memory_pointer;
299 ULONG mem_free;
300 ULONG test_n;
301
302
303 /* Inform user. */
304 printf("Running Storage Basic Memory Test................................... ");
305 stepinfo("\n");
306
307 /* Reset testing counts. */
308 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
309 ux_test_utility_sim_mem_alloc_count_reset();
310 ux_test_utility_sim_mutex_create_count_reset();
311 ux_test_utility_sim_sem_create_count_reset();
312 ux_test_utility_sim_sem_get_count_reset();
313 /* Reset error generations */
314 ux_test_utility_sim_sem_error_generation_stop();
315 ux_test_utility_sim_mutex_error_generation_stop();
316 ux_test_utility_sim_sem_get_error_generation_stop();
317
318 /* Initialize the free memory pointer */
319 stack_pointer = (CHAR *) usbx_memory;
320 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
321
322 /* Initialize USBX. Memory */
323 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
324
325 /* Check for error. */
326 if (status != UX_SUCCESS)
327 {
328
329 printf("ERROR #%d\n", __LINE__);
330 test_control_return(1);
331 }
332
333 /* Register the error callback. */
334 _ux_utility_error_callback_register(error_callback);
335
336 /* The code below is required for installing the device portion of USBX.
337 In this demo, DFU is possible and we have a call back for state change. */
338 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
339 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
340 string_framework, STRING_FRAMEWORK_LENGTH,
341 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
342 if(status!=UX_SUCCESS)
343 {
344
345 printf("ERROR #%d\n", __LINE__);
346 test_control_return(1);
347 }
348
349 /* Store the number of LUN in this device storage instance. */
350 global_storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;
351
352 /* Initialize the storage class parameters for reading/writing to the first Flash Disk. */
353 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = UX_RAM_DISK_LAST_LBA;
354 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;
355 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;
356 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;
357 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = demo_thread_media_read;
358 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = demo_thread_media_write;
359 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = demo_thread_media_status;
360
361 /* Initialize the storage class parameters for reading/writing to the second Flash Disk. */
362 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba = UX_RAM_DISK_LAST_LBA;
363 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length = 512;
364 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type = 0;
365 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag = 0x80;
366 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read = demo_thread_media_read;
367 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write = demo_thread_media_write;
368 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status = demo_thread_media_status;
369
370 /* Reset testing counts. */
371 ux_test_utility_sim_mem_alloc_count_reset();
372
373 /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
374 status = ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
375 1, 0, (VOID *)&global_storage_parameter);
376 if(status!=UX_SUCCESS)
377 {
378
379 printf("ERROR #%d\n", __LINE__);
380 test_control_return(1);
381 }
382
383 rsc_storage_mem_alloc_count = ux_test_utility_sim_mem_alloc_count();
384
385 /* Lock log base for tests. */
386 ux_test_utility_sim_mem_alloc_log_lock();
387
388 stepinfo("init mem : %ld\n", rsc_storage_mem_alloc_count);
389
390 if (rsc_storage_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors class register test\n");
391 mem_free = (~0);
392 for (test_n = 0; test_n < rsc_storage_mem_alloc_count; test_n ++)
393 {
394
395 stepinfo("%4ld / %4ld\n", test_n, rsc_storage_mem_alloc_count - 1);
396
397 /* Unregister. */
398 ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
399
400 /* Update memory free level (unregister). */
401 if (mem_free == (~0))
402 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
403 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
404 {
405
406 printf("ERROR #%d.%ld: Memory level different after re-register %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
407 test_control_return(1);
408 }
409
410 /* Set memory error generation */
411 ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
412
413 /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
414 status = ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
415 1, 0, (VOID *)&global_storage_parameter);
416 if (status == UX_SUCCESS)
417 {
418 printf("ERROR #%d.%ld: Class registered when there is memory error\n", __LINE__, test_n);
419 test_control_return(1);
420 }
421 }
422 ux_test_utility_sim_mem_alloc_error_generation_stop();
423 if (rsc_storage_mem_alloc_count) stepinfo("\n");
424
425 /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
426 status = ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
427 1, 0, (VOID *)&global_storage_parameter);
428 if(status!=UX_SUCCESS)
429 {
430
431 printf("ERROR #%d\n", __LINE__);
432 test_control_return(1);
433 }
434
435 /* Initialize the simulated device controller. */
436 status = _ux_dcd_sim_slave_initialize();
437
438 /* Check for error. */
439 if (status != UX_SUCCESS)
440 {
441
442 printf("ERROR #%d\n", __LINE__);
443 test_control_return(1);
444 }
445
446 /* The code below is required for installing the host portion of USBX */
447 status = ux_host_stack_initialize(UX_NULL);
448 if (status != UX_SUCCESS)
449 {
450
451 printf("ERROR #%d\n", __LINE__);
452 test_control_return(1);
453 }
454
455 /* Register storage class. */
456 status = ux_host_stack_class_register(_ux_system_host_class_storage_name, ux_host_class_storage_entry);
457 if (status != UX_SUCCESS)
458 {
459
460 printf("ERROR #%d\n", __LINE__);
461 test_control_return(1);
462 }
463
464 /* Register all the USB host controllers available in this system */
465 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
466
467 /* Check for error. */
468 if (status != UX_SUCCESS)
469 {
470
471 printf("ERROR #%d\n", __LINE__);
472 test_control_return(1);
473 }
474
475 /* Create the main host simulation thread. */
476 status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
477 stack_pointer, UX_DEMO_STACK_SIZE,
478 20, 20, 1, TX_AUTO_START);
479
480 /* Check for error. */
481 if (status != TX_SUCCESS)
482 {
483
484 printf("ERROR #%d\n", __LINE__);
485 test_control_return(1);
486 }
487
488 }
489
490
tx_demo_thread_host_simulation_entry(ULONG arg)491 static void tx_demo_thread_host_simulation_entry(ULONG arg)
492 {
493
494 UINT status;
495 ULONG mem_free;
496 ULONG test_n;
497
498
499 /* Initialize FileX. */
500 fx_system_initialize();
501
502 /* Reset ram disks memory. */
503 ux_utility_memory_set(ram_disk_memory1, 0, UX_RAM_DISK_SIZE);
504 ux_utility_memory_set(ram_disk_memory2, 0, UX_RAM_DISK_SIZE);
505
506 /* Format the ram drive. */
507 status = fx_media_format(&ram_disk1, _fx_ram_driver, ram_disk_memory1, buffer1, 512, "RAM DISK1", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
508 status |= fx_media_format(&ram_disk2, _fx_ram_driver, ram_disk_memory2, buffer2, 512, "RAM DISK2", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
509 if (status != FX_SUCCESS)
510 {
511
512 /* Storage basic test error. */
513 printf("ERROR #8\n");
514 test_control_return(1);
515 }
516
517 /* Open the ram_disk. */
518 status = fx_media_open(&ram_disk1, "RAM DISK1", _fx_ram_driver, ram_disk_memory1, buffer1, 512);
519 status |= fx_media_open(&ram_disk2, "RAM DISK2", _fx_ram_driver, ram_disk_memory2, buffer2, 512);
520 if (status != FX_SUCCESS)
521 {
522
523 /* Storage basic test error. */
524 printf("ERROR %d\n", __LINE__);
525 test_control_return(1);
526 }
527
528 /* Find the storage class. */
529 status = host_storage_instance_get(100);
530 if (status != UX_SUCCESS)
531 {
532
533 printf("ERROR #%d\n", __LINE__);
534 test_control_return(1);
535 }
536
537 /* Test disconnect. */
538 ux_test_dcd_sim_slave_disconnect();
539 ux_test_hcd_sim_host_disconnect();
540
541 /* Check connection. */
542 status = host_storage_instance_get(0);
543 if (status == UX_SUCCESS)
544 {
545
546 printf("ERROR #%d\n", __LINE__);
547 test_control_return(1);
548 }
549
550 /* Reset testing counts. */
551 ux_test_utility_sim_mem_alloc_count_reset();
552 ux_test_utility_sim_mutex_create_count_reset();
553 ux_test_utility_sim_sem_create_count_reset();
554 ux_test_utility_sim_sem_get_count_reset();
555 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
556
557 /* Save free memory usage. */
558 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
559 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
560 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
561
562 /* Check connection. */
563 status = host_storage_instance_get(50);
564 if (status != UX_SUCCESS)
565 {
566
567 printf("ERROR #%d\n", __LINE__);
568 test_control_return(1);
569 }
570
571 /* Log create counts for further tests. */
572 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
573 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
574 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
575 /* Log create counts when instances active for further tests. */
576 rsc_storage_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
577 rsc_storage_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
578 rsc_storage_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
579
580 /* Lock log base for tests. */
581 ux_test_utility_sim_mem_alloc_log_lock();
582
583 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
584 stepinfo("storage mem : %ld\n", rsc_storage_mem_alloc_count);
585 stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
586
587 /* Simulate detach and attach for FS enumeration,
588 and check if there is memory error in normal enumeration.
589 */
590 stepinfo(">>>>>>>>>>>> Enumeration test\n");
591 mem_free = (~0);
592 for (test_n = 0; test_n < 3; test_n++)
593 {
594 stepinfo("%4ld / 2\n", test_n);
595
596 /* Disconnect. */
597 ux_test_dcd_sim_slave_disconnect();
598 ux_test_hcd_sim_host_disconnect();
599
600 /* Check */
601 if (host_storage_instance_get(0) == UX_SUCCESS)
602 {
603
604 printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
605 test_control_return(1);
606 }
607
608 /* Update memory free level (disconnect) */
609 if (mem_free == (~0))
610 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
611 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
612 {
613
614 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
615 test_control_return(1);
616 }
617
618 /* Connect. */
619 error_callback_counter = 0;
620 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
621 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
622
623 /* Wait and break on error. */
624 ux_test_breakable_sleep(100, sleep_break_on_error);
625
626 /* Check */
627 if (host_storage_instance_get(0) != UX_SUCCESS)
628 {
629
630 printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
631 test_control_return(1);
632 }
633 }
634 stepinfo("\n");
635
636 /* Simulate detach and attach for FS enumeration,
637 and test possible memory allocation error handlings.
638 */
639 if (rsc_storage_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
640 mem_free = (~0);
641 for (test_n = 0; test_n < rsc_storage_mem_alloc_count; test_n ++)
642 {
643
644 stepinfo("%4ld / %4ld\n", test_n, rsc_storage_mem_alloc_count - 1);
645
646 /* Disconnect. */
647 ux_test_dcd_sim_slave_disconnect();
648 ux_test_hcd_sim_host_disconnect();
649
650 /* Check */
651 if (host_storage_instance_get(0) == UX_SUCCESS)
652 {
653
654 printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
655 test_control_return(1);
656 }
657
658 /* Update memory free level (disconnect) */
659 if (mem_free == (~0))
660 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
661 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
662 {
663
664 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
665 test_control_return(1);
666 }
667
668 /* Set memory error generation */
669 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
670
671 /* Connect. */
672 error_callback_counter = 0;
673 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
674 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
675
676 /* Wait and break on errors. */
677 ux_test_breakable_sleep(100, sleep_break_on_error);
678
679 /* Check error */
680 if (host_storage_instance_get(0) == UX_SUCCESS)
681 {
682
683 /* Could be media errors,
684 in this case instance is ready,
685 check error trap. */
686 if (error_callback_counter == 0)
687 {
688 printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
689 test_control_return(1);
690 }
691 }
692 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
693 }
694 ux_test_utility_sim_mem_alloc_error_generation_stop();
695 if (rsc_storage_mem_alloc_count) stepinfo("\n");
696
697 /* Finally disconnect the device. */
698 ux_device_stack_disconnect();
699
700 /* And deinitialize the class. */
701 status = ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
702
703 /* Deinitialize the device side of usbx. */
704 _ux_device_stack_uninitialize();
705
706 /* And finally the usbx system resources. */
707 _ux_system_uninitialize();
708
709 /* Successful test. */
710 printf("SUCCESS!\n");
711 test_control_return(0);
712 }
713
714
demo_thread_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)715 static UINT demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
716 {
717
718 static UCHAR lun_init_done[2] = {0, 0};
719 UINT status;
720 ULONG mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE;
721
722
723 (void)storage;
724 (void)media_id;
725
726
727 if (lun > 1)
728 status = (UX_ERROR);
729 else if (lun_init_done[lun] > 0)
730 status = (UX_SUCCESS);
731 else
732 {
733 lun_init_done[lun] ++;
734 mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
735 status = (UX_ERROR);
736 }
737
738 if (media_status)
739 *media_status = mstatus;
740
741 return status;
742 }
743
demo_thread_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)744 UINT demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
745 {
746
747 UINT status = 0;
748
749 if(lba == 0)
750 {
751 ram_disks[lun]->fx_media_driver_logical_sector = 0;
752 ram_disks[lun]->fx_media_driver_sectors = 1;
753 ram_disks[lun]->fx_media_driver_request = FX_DRIVER_BOOT_READ;
754 ram_disks[lun]->fx_media_driver_buffer = data_pointer;
755 _fx_ram_driver(ram_disks[lun]);
756 *(data_pointer) = 0xeb;
757 *(data_pointer+1) = 0x3c;
758 *(data_pointer+2) = 0x90;
759 *(data_pointer+21) = 0xF8;
760
761 *(data_pointer+24) = 0x01;
762 *(data_pointer+26) = 0x10;
763 *(data_pointer+28) = 0x01;
764
765 *(data_pointer+510) = 0x55;
766 *(data_pointer+511) = 0xaa;
767 ux_utility_memory_copy(data_pointer+0x36,"FAT12",5);
768
769
770 status = ram_disks[lun]->fx_media_driver_status;
771 }
772 else
773 {
774 while(number_blocks--)
775 {
776 status = fx_media_read(ram_disks[lun],lba,data_pointer);
777 data_pointer+=512;
778 lba++;
779 }
780 }
781 return(status);
782 }
783
demo_thread_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)784 UINT demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
785 {
786
787 UINT status = 0;
788
789 if(lba == 0)
790 {
791 ram_disks[lun]->fx_media_driver_logical_sector = 0;
792 ram_disks[lun]->fx_media_driver_sectors = 1;
793 ram_disks[lun]->fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
794 ram_disks[lun]->fx_media_driver_buffer = data_pointer;
795 _fx_ram_driver(ram_disks[lun]);
796
797 status = ram_disks[lun]->fx_media_driver_status;
798
799 }
800 else
801 {
802
803 while(number_blocks--)
804 {
805 status = fx_media_write(ram_disks[lun],lba,data_pointer);
806 data_pointer+=512;
807 lba++;
808 }
809 return(status);
810 }
811 return(1);
812 }