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_stack.h"
12 #include "ux_device_class_storage.h"
13 
14 #include "ux_host_stack.h"
15 #include "ux_host_class_storage.h"
16 
17 #include "ux_test_dcd_sim_slave.h"
18 #include "ux_test_hcd_sim_host.h"
19 #include "ux_test_utility_sim.h"
20 
21 FX_MEDIA    *_ux_host_class_storage_driver_media(INT i);
22 VOID        _ux_host_class_storage_driver_entry(FX_MEDIA *media);
23 VOID        _ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG format_open);
24 VOID        _ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
25 INT         _ux_host_class_storage_media_index(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
26 FX_MEDIA    *_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
27 UCHAR       *_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
28 VOID        _ux_host_class_storage_driver_read_write_notify(
29     VOID (*func)(UINT, UINT, UX_HOST_CLASS_STORAGE *, ULONG, ULONG, UCHAR*));
30 
31 static VOID demo_host_media_read_write_notify(UINT fx_req, UINT fx_rc,
32                                 UX_HOST_CLASS_STORAGE *storage,
33                                 ULONG sec_start, ULONG sec_count, UCHAR* buf);
34 
35 /* Define constants.  */
36 #define                             UX_DEMO_STACK_SIZE              2048
37 #define                             UX_DEMO_MEMORY_SIZE             (256*1024)
38 #define                             UX_DEMO_BUFFER_SIZE             (UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3)
39 
40 #define                             UX_RAM_DISK_SIZE                (200 * 1024)
41 #define                             UX_RAM_DISK_LAST_LBA            ((UX_RAM_DISK_SIZE / 512) -1)
42 
43 /* Define local/extern function prototypes.  */
44 VOID               _fx_ram_driver(FX_MEDIA *media_ptr);
45 
46 static void        demo_thread_entry(ULONG);
47 static TX_THREAD   tx_demo_thread_host_simulation;
48 static TX_THREAD   tx_demo_thread_device_simulation;
49 static void        tx_demo_thread_host_simulation_entry(ULONG);
50 static void        tx_demo_thread_device_simulation_entry(ULONG);
51 
52 static UINT        ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst);
53 
54 static UINT        demo_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
55 static UINT        demo_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
56 static UINT        demo_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
57 static UINT        demo_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status);
58 
59 static VOID        ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
60 
61 /* Define global data structures.  */
62 
63 static UCHAR                            usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
64 static UCHAR                            buffer[UX_DEMO_BUFFER_SIZE];
65 
66 static ULONG                            error_counter;
67 
68 static UX_HOST_CLASS_STORAGE            *storage;
69 static UX_HOST_CLASS_STORAGE_MEDIA      *storage_media = UX_NULL;
70 static FX_MEDIA                         *media = UX_NULL;
71 static UX_SLAVE_CLASS_STORAGE_PARAMETER global_storage_parameter;
72 
73 static ULONG                            host_event;
74 static UX_HOST_CLASS                    *host_event_cls;
75 static VOID                             *host_event_inst;
76 
77 static FX_MEDIA                         ram_disk1;
78 static FX_MEDIA                         ram_disk2;
79 static CHAR                             ram_disk_memory1[UX_RAM_DISK_SIZE];
80 static CHAR                             ram_disk_memory2[UX_RAM_DISK_SIZE];
81 static UCHAR                            buffer1[512];
82 static UCHAR                            buffer2[512];
83 
84 static FX_MEDIA                         *ram_disks[] = {&ram_disk1, &ram_disk2};
85 static UCHAR                            *buffers[] = {buffer1, buffer2};
86 static CHAR                             *ram_disk_memory[] = { ram_disk_memory1, ram_disk_memory2 };
87 
88 static UINT                             ram_disk_status = UX_SUCCESS;
89 static ULONG                            ram_disk_media_attention = 0;
90 static ULONG                            ram_disk_media_status = 0;
91 static CHAR                             ram_disk_status_sent = 0;
92 
93 static ULONG                            ram_disk_rw_wait_delay = 0;
94 static ULONG                            ram_disk_rw_wait_start = 0;
95 static UCHAR                            ram_disk_rw_wait_state = 0;/* 0: idle, 1: wait */
96 
97 static UCHAR                            ram_disk_rw_disconnect = 0;/* device disconnect while read/write in progress */
98 static ULONG                            ram_disk_rw_disconnect_count = 0;
99 
100 static CHAR                             ram_disk_flush = 0;
101 static UINT                             ram_disk_flush_status = UX_STATE_NEXT;
102 
103 static ULONG                            set_cfg_counter;
104 
105 static ULONG                            rsc_mem_alloc_cnt_on_set_cfg;
106 static ULONG                            rsc_sem_on_set_cfg;
107 static ULONG                            rsc_sem_get_on_set_cfg;
108 static ULONG                            rsc_mutex_on_set_cfg;
109 
110 static ULONG                            rsc_enum_sem_usage;
111 static ULONG                            rsc_enum_sem_get_count;
112 static ULONG                            rsc_enum_mutex_usage;
113 static ULONG                            rsc_enum_mem_alloc_count;
114 
115 static ULONG                            rsc_storage_sem_usage;
116 static ULONG                            rsc_storage_sem_get_count;
117 static ULONG                            rsc_storage_mutex_usage;
118 static ULONG                            rsc_storage_mem_alloc_count;
119 
120 static ULONG                            interaction_count;
121 
122 static UCHAR                            error_callback_ignore = UX_TRUE;
123 static ULONG                            error_callback_counter;
124 
125 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
126 static UCHAR device_framework_full_speed[] = {
127 
128     /* Device descriptor */
129         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
130         0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
131         0x03, 0x01,
132 
133     /* Configuration descriptor */
134         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
135         0x32,
136 
137     /* Interface descriptor */
138         0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
139         0x00,
140 
141     /* Endpoint descriptor (Bulk In) */
142         0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
143 
144     /* Endpoint descriptor (Bulk Out) */
145         0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00
146 
147     };
148 
149 
150 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
151 static UCHAR device_framework_high_speed[] = {
152 
153     /* Device descriptor */
154         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
155         0x81, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
156         0x03, 0x01,
157 
158     /* Device qualifier descriptor */
159         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
160         0x01, 0x00,
161 
162     /* Configuration descriptor */
163         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
164         0x32,
165 
166     /* Interface descriptor */
167         0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
168         0x00,
169 
170     /* Endpoint descriptor (Bulk In) */
171         0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00,
172 
173     /* Endpoint descriptor (Bulk Out) */
174         0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00
175 
176     };
177 
178 
179 /* String Device Framework :
180     Byte 0 and 1 : Word containing the language ID : 0x0904 for US
181     Byte 2       : Byte containing the index of the descriptor
182     Byte 3       : Byte containing the length of the descriptor string
183 */
184 #define STRING_FRAMEWORK_LENGTH 38
185 static UCHAR string_framework[] = {
186 
187     /* Manufacturer string descriptor : Index 1 */
188         0x09, 0x04, 0x01, 0x0c,
189         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
190         0x6f, 0x67, 0x69, 0x63,
191 
192     /* Product string descriptor : Index 2 */
193         0x09, 0x04, 0x02, 0x0a,
194         0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x44, 0x69,
195         0x73, 0x6b,
196 
197     /* Serial Number string descriptor : Index 3 */
198         0x09, 0x04, 0x03, 0x04,
199         0x30, 0x30, 0x30, 0x31
200     };
201 
202 
203 /* Multiple languages are supported on the device, to add
204     a language besides english, the unicode language code must
205     be appended to the language_id_framework array and the length
206     adjusted accordingly. */
207 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
208 static UCHAR language_id_framework[] = {
209 
210     /* English. */
211         0x09, 0x04
212     };
213 
214 
215 /* Setup requests */
216 
217 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
218 
219 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
220 /* function, request to match,
221    port action, port status,
222    request action, request EP, request data, request actual length, request status,
223    status, additional callback,
224    no_return */
225 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
226         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
227         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
228         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
229         UX_TRUE}, /* Invoke callback & continue */
230 {   0   }
231 };
232 
233 
234 static UX_TEST_HCD_SIM_ACTION fail_on_bulkin[] = {
235 /* function, request to match,
236    port action, port status,
237    request action, request EP, request data, request actual length, request status,
238    status, additional callback,
239    no_return */
240 {   UX_DCD_TRANSFER_REQUEST, UX_NULL,
241         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
242         UX_TEST_MATCH_EP, 0x81, UX_NULL, 0, UX_ERROR,
243         UX_STATE_ERROR, UX_NULL,
244         UX_FALSE}, /* Invoke callback & no continue */
245 {   0   }
246 };
247 
248 
249 static UX_TEST_HCD_SIM_ACTION fail_on_bulkout[] = {
250 /* function, request to match,
251    port action, port status,
252    request action, request EP, request data, request actual length, request status,
253    status, additional callback,
254    no_return */
255 {   UX_DCD_TRANSFER_REQUEST, UX_NULL,
256         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
257         UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
258         UX_STATE_ERROR, UX_NULL,
259         UX_FALSE}, /* Invoke callback & no continue */
260 {   0   }
261 };
262 
263 
264 /* Define the ISR dispatch.  */
265 
266 extern VOID    (*test_isr_dispatch)(void);
267 
268 
269 /* Prototype for test control return.  */
270 
271 void  test_control_return(UINT status);
272 
273 
274 /* Define the ISR dispatch routine.  */
275 
test_isr(void)276 static void    test_isr(void)
277 {
278 
279     /* For further expansion of interrupt-level testing.  */
280 }
281 
282 
error_callback(UINT system_level,UINT system_context,UINT error_code)283 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
284 {
285 
286     error_callback_counter ++;
287 
288     if (!error_callback_ignore)
289     {
290         {
291             /* Failed test.  */
292             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
293             test_control_return(1);
294         }
295     }
296 }
297 
host_storage_instance_get(ULONG timeout_x10ms)298 static UINT host_storage_instance_get(ULONG timeout_x10ms)
299 {
300 
301 UINT                        status;
302 UX_HOST_CLASS               *class;
303 UX_HOST_CLASS_STORAGE_MEDIA *tmp_media;
304 
305     /* Find the main storage container */
306     status =  ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
307     if (status != UX_SUCCESS)
308         return(status);
309 
310     /* Get storage instance, wait it to be live and media attached.  */
311     do
312     {
313         /* Run host tasks.  */
314         ux_system_tasks_run();
315 
316         if (timeout_x10ms)
317         {
318             tx_thread_sleep(UX_MS_TO_TICK_NON_ZERO(10));
319             if (timeout_x10ms != 0xFFFFFFFF)
320                 timeout_x10ms --;
321         }
322 
323         status =  ux_host_stack_class_instance_get(class, 0, (void **) &storage);
324         if (status == UX_SUCCESS)
325         {
326             /* Always use first storage media.  */
327             status = ux_host_class_storage_media_get(storage, 0, &tmp_media);
328             if (status == UX_SUCCESS && storage_media == UX_NULL)
329             {
330                 stepinfo("%s:%d >>>>>>>>>>>>>>> Mount media %p\n", __FILE__, __LINE__, (void*)tmp_media);
331                 /* Use callback to check read/write.  */
332                 _ux_host_class_storage_driver_read_write_notify(demo_host_media_read_write_notify);
333                 /* Media must not be associated inside callback. Do it now.  */
334                 storage_media = tmp_media;
335                 _ux_host_class_storage_media_insert(storage_media, 1);
336                 media = _ux_host_class_storage_media_fx_media(storage_media);
337                 return(UX_SUCCESS);
338             }
339             if (status == UX_SUCCESS && tmp_media == storage_media)
340                 return(UX_SUCCESS);
341         }
342 
343         if (status != UX_SUCCESS && storage_media != UX_NULL)
344         {
345             stepinfo("%s:%d >>>>>>>>>>>>>>> Remove media %p\n", __FILE__, __LINE__, (void*)storage_media);
346             _ux_host_class_storage_media_remove(storage_media);
347             storage_media = UX_NULL;
348             media = UX_NULL;
349         }
350 
351     } while(timeout_x10ms > 0);
352 
353     return(UX_ERROR);
354 }
355 
sleep_break_on_error(VOID)356 static UINT sleep_break_on_error(VOID)
357 {
358 
359     if (error_callback_counter >= 3)
360         return error_callback_counter;
361 
362     return UX_SUCCESS;
363 }
364 
sleep_break_on_connect(VOID)365 static UINT sleep_break_on_connect(VOID)
366 {
367     if (host_storage_instance_get(0) == UX_SUCCESS)
368         return(1);
369     if (error_callback_counter >= 3)
370         return(1);
371     return(0);
372 }
373 
sleep_break_on_disconnect(VOID)374 static UINT sleep_break_on_disconnect(VOID)
375 {
376     if (host_storage_instance_get(0) == UX_SUCCESS)
377         return(0);
378     return(1);
379 }
380 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)381 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
382 {
383 
384     set_cfg_counter ++;
385 
386     rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
387 
388     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
389     rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
390     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
391 }
392 
393 
394 /* Define what the initial system looks like.  */
395 
396 #ifdef CTEST
test_application_define(void * first_unused_memory)397 void test_application_define(void *first_unused_memory)
398 #else
399 void    usbx_standalone_host_storage_read_write_test_application_define(void *first_unused_memory)
400 #endif
401 {
402 
403 UINT                            status;
404 CHAR *                          stack_pointer;
405 CHAR *                          memory_pointer;
406 ULONG                           mem_free;
407 ULONG                           test_n;
408 
409 
410     /* Inform user.  */
411     printf("Running STANDALONE Host Storage Read Write Test..................... ");
412 #ifndef UX_HOST_STANDALONE
413     printf("Skip\n");
414     test_control_return(0);
415 #endif
416 
417     stepinfo("\n");
418 
419     /* Initialize FileX.  */
420     fx_system_initialize();
421 
422     /* Reset ram disks memory.  */
423     ux_utility_memory_set(ram_disk_memory1, 0, UX_RAM_DISK_SIZE);
424     ux_utility_memory_set(ram_disk_memory2, 0, UX_RAM_DISK_SIZE);
425 
426     /* Format the ram drive. */
427     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);
428     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);
429     if (status != FX_SUCCESS)
430     {
431 
432         /* Storage basic test error.  */
433         printf("ERROR #8\n");
434         test_control_return(1);
435     }
436 
437     /* Open the ram_disk.  */
438     status =   fx_media_open(&ram_disk1, "RAM DISK1", _fx_ram_driver, ram_disk_memory1, buffer1, 512);
439     status |=  fx_media_open(&ram_disk2, "RAM DISK2", _fx_ram_driver, ram_disk_memory2, buffer2, 512);
440     if (status != FX_SUCCESS)
441     {
442 
443         /* Storage basic test error.  */
444         printf("ERROR %d\n", __LINE__);
445         test_control_return(1);
446     }
447 
448     /* Reset testing counts. */
449     ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
450     ux_test_utility_sim_mem_alloc_count_reset();
451     ux_test_utility_sim_mutex_create_count_reset();
452     ux_test_utility_sim_sem_create_count_reset();
453     ux_test_utility_sim_sem_get_count_reset();
454     /* Reset error generations */
455     ux_test_utility_sim_sem_error_generation_stop();
456     ux_test_utility_sim_mutex_error_generation_stop();
457     ux_test_utility_sim_sem_get_error_generation_stop();
458 
459     /* Initialize the free memory pointer */
460     stack_pointer = (CHAR *) usbx_memory;
461     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
462 
463     /* Initialize USBX. Memory */
464     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
465 
466     /* Check for error.  */
467     if (status != UX_SUCCESS)
468     {
469 
470         printf("ERROR #%d\n", __LINE__);
471         test_control_return(1);
472     }
473 
474     /* Register the error callback. */
475     _ux_utility_error_callback_register(error_callback);
476 
477     /* The code below is required for installing the device portion of USBX.
478        In this demo, DFU is possible and we have a call back for state change. */
479     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
480                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
481                                        string_framework, STRING_FRAMEWORK_LENGTH,
482                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
483     if(status!=UX_SUCCESS)
484     {
485 
486         printf("ERROR #%d\n", __LINE__);
487         test_control_return(1);
488     }
489 
490     /* Store the number of LUN in this device storage instance.  */
491     global_storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;
492 
493     /* Initialize the storage class parameters for reading/writing to the first Flash Disk.  */
494     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
495     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length    =  512;
496     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type            =  0;
497     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag  =  0x80;
498     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read            =  demo_media_read;
499     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write           =  demo_media_write;
500     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status          =  demo_media_status;
501     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_flush           =  demo_media_flush;
502 
503     /* Initialize the storage class parameters for reading/writing to the second Flash Disk.  */
504     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
505     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length    =  512;
506     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type            =  0;
507     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag  =  0x80;
508     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read            =  demo_media_read;
509     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write           =  demo_media_write;
510     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status          =  demo_media_status;
511     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_flush           =  demo_media_flush;
512 
513     /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
514     status =  ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
515                                                 1, 0, (VOID *)&global_storage_parameter);
516     if(status!=UX_SUCCESS)
517     {
518 
519         printf("ERROR #%d\n", __LINE__);
520         test_control_return(1);
521     }
522 
523     /* Initialize the simulated device controller.  */
524     // status =  _ux_dcd_sim_slave_initialize();
525     status =  _ux_test_dcd_sim_slave_initialize();
526 
527     /* Check for error.  */
528     if (status != UX_SUCCESS)
529     {
530 
531         printf("ERROR #%d\n", __LINE__);
532         test_control_return(1);
533     }
534 
535     /* The code below is required for installing the host portion of USBX */
536     status =  ux_host_stack_initialize(ux_test_system_host_change_function);
537     if (status != UX_SUCCESS)
538     {
539 
540         printf("ERROR #%d\n", __LINE__);
541         test_control_return(1);
542     }
543 
544     /* Register storage class.  */
545     status =  ux_host_stack_class_register(_ux_system_host_class_storage_name, ux_host_class_storage_entry);
546     if (status != UX_SUCCESS)
547     {
548 
549         printf("ERROR #%d\n", __LINE__);
550         test_control_return(1);
551     }
552 
553     /* Register all the USB host controllers available in this system */
554     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
555 
556     /* Check for error.  */
557     if (status != UX_SUCCESS)
558     {
559 
560         printf("ERROR #%d\n", __LINE__);
561         test_control_return(1);
562     }
563 
564     /* Create the main device simulation thread.  */
565     status =  tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
566             stack_pointer, UX_DEMO_STACK_SIZE,
567             21, 21, 1, TX_AUTO_START);
568 
569     /* Check for error.  */
570     if (status != TX_SUCCESS)
571     {
572 
573         printf("ERROR #%d\n", __LINE__);
574         test_control_return(1);
575     }
576     stack_pointer += UX_DEMO_STACK_SIZE;
577 
578     /* Create the main host simulation thread.  */
579     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
580             stack_pointer, UX_DEMO_STACK_SIZE,
581             20, 20, 1, TX_AUTO_START);
582 
583     /* Check for error.  */
584     if (status != TX_SUCCESS)
585     {
586 
587         printf("ERROR #%d\n", __LINE__);
588         test_control_return(1);
589     }
590 
591 }
592 
tx_demo_thread_device_simulation_entry(ULONG arg)593 static void tx_demo_thread_device_simulation_entry(ULONG arg)
594 {
595     while(1)
596     {
597 #if defined(UX_DEVICE_STANDALONE)
598         /* Run device tasks.  */
599         ux_system_tasks_run();
600 #endif
601         /* Relinquish to other thread.  */
602         tx_thread_relinquish();
603     }
604 }
605 
_test_dw_minus(ULONG d0,ULONG d1)606 static ULONG _test_dw_minus(ULONG d0, ULONG d1)
607 {
608     if (d0 >= d1)
609         return(d0 - d1);
610     return(d0 + (0xFFFFFFFF - d1));
611 }
612 
_media_driver_read(FX_MEDIA * media,VOID (* _media_driver)(FX_MEDIA *),UCHAR * buffer,ULONG lba,ULONG n_lb)613 static UINT  _media_driver_read(FX_MEDIA *media,
614     VOID (*_media_driver)(FX_MEDIA *),
615     UCHAR *buffer, ULONG lba, ULONG n_lb)
616 {
617 UINT status;
618 
619     if (lba == 0)
620     {
621         media->fx_media_driver_logical_sector = lba;
622         media->fx_media_driver_sectors = n_lb;
623         media->fx_media_driver_request = FX_DRIVER_BOOT_READ;
624         media->fx_media_driver_buffer = buffer;
625         _media_driver(media);
626         *(buffer) =  0xeb;
627         *(buffer+1) =  0x3c;
628         *(buffer+2) =  0x90;
629         *(buffer+21) =  0xF8;
630 
631         *(buffer+24) =  0x01;
632         *(buffer+26) =  0x10;
633         *(buffer+28) =  0x01;
634 
635         *(buffer+510) =  0x55;
636         *(buffer+511) =  0xaa;
637         ux_utility_memory_copy(buffer+0x36,"FAT12",5);
638 
639         if (media->fx_media_driver_status != FX_SUCCESS)
640         {
641             printf("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
642             return(UX_ERROR);
643         }
644 
645         lba++;
646         n_lb --;
647         buffer += 512;
648     }
649     media->fx_media_driver_logical_sector = lba;
650     media->fx_media_driver_sectors = n_lb;
651     media->fx_media_driver_request = FX_DRIVER_READ;
652     media->fx_media_driver_buffer = buffer;
653     _media_driver(media);
654     if (media->fx_media_driver_status != FX_SUCCESS)
655     {
656         stepinfo("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
657         return(UX_ERROR);
658     }
659     return(UX_SUCCESS);
660 }
661 
_media_driver_write(FX_MEDIA * media,VOID (* _media_driver)(FX_MEDIA *),UCHAR * buffer,ULONG lba,ULONG n_lb)662 static UINT  _media_driver_write(FX_MEDIA *media,
663     VOID (*_media_driver)(FX_MEDIA *),
664     UCHAR *buffer, ULONG lba, ULONG n_lb)
665 {
666 UINT status;
667 
668     if (lba == 0)
669     {
670         media -> fx_media_driver_logical_sector = 0;
671         media -> fx_media_driver_sectors = 1;
672         media -> fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
673         media -> fx_media_driver_buffer = buffer;
674         _media_driver(media);
675 
676         if (media->fx_media_driver_status != FX_SUCCESS)
677         {
678             printf("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
679             return(UX_ERROR);
680         }
681 
682         lba ++;
683         n_lb --;
684         buffer += 512;
685     }
686     if (n_lb)
687     {
688         media -> fx_media_driver_logical_sector = lba;
689         media -> fx_media_driver_sectors = n_lb;
690         media -> fx_media_driver_request = FX_DRIVER_WRITE;
691         media -> fx_media_driver_buffer = buffer;
692         _media_driver(media);
693 
694         if (media->fx_media_driver_status != FX_SUCCESS)
695         {
696             stepinfo("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
697             return(UX_ERROR);
698         }
699     }
700     return(UX_SUCCESS);
701 }
702 
703 
_msc_media_read_test(const char * __file__,int __line__)704 static void _msc_media_read_test(const char* __file__, int __line__)
705 {
706 UINT                                        status;
707 ULONG                                       test_n;
708 ULONG                                       test_size[] = {
709     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512,
710     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512,
711     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512 + 1};
712 
713     stepinfo("\n%s:%d:MSC Media Read tests\n", __file__, __line__);
714 
715     if (media == UX_NULL || media -> fx_media_id == 0)
716     {
717         printf("ERROR %d: media error\n", __LINE__);
718         test_control_return(1);
719     }
720 
721     stepinfo(">>>>>>>>>>>> Disk read(1) test\n");
722     {
723         status = fx_media_read(media, 48, buffer);
724         if (status != FX_SUCCESS)
725         {
726             printf("ERROR %d: 0x%x\n", __LINE__, status);
727             test_control_return(1);
728         }
729     }
730 
731     /* Disk read multiple test.  */
732     for (test_n = 0; test_n < sizeof(test_size)/sizeof(test_size[0]); test_n ++)
733     {
734 
735         stepinfo(">>>>>>>>>>>> Disk read(%ld) test\n", test_size[test_n]);
736         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
737                 buffer, 0, test_size[test_n]);
738         if (status != UX_SUCCESS)
739         {
740             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
741             test_control_return(1);
742         }
743     }
744 }
745 
_msc_media_write_read_test(const char * __file__,int __line__)746 static void _msc_media_write_read_test(const char* __file__, int __line__)
747 {
748 UINT                                        status;
749 ULONG                                       test_n;
750 INT                                         i;
751 ULONG                                       test_size[] = {
752     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512,
753     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512,
754     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512 + 1};
755 
756     stepinfo("\n%s:%d:MSC Media Write & Read tests\n", __file__, __line__);
757 
758     /* Check if media still available.  */
759     if (media == UX_NULL || media -> fx_media_id == 0)
760     {
761         printf("ERROR %d: media error\n", __LINE__);
762         test_control_return(1);
763     }
764 
765     stepinfo(">>>>>>>>>>>> Disk write(1)/read(1) test\n");
766     {
767         for(i = 0; i < 512; i ++)
768             buffer[i] = i;
769         status = fx_media_write(media, 48, buffer);
770         if (status != FX_SUCCESS)
771         {
772             printf("ERROR %d: 0x%x\n", __LINE__, status);
773             test_control_return(1);
774         }
775         _ux_utility_memory_set(buffer, 0x00, 512);
776         status = fx_media_read(media, 48, buffer);
777         if (status != FX_SUCCESS)
778         {
779             printf("ERROR %d: 0x%x\n", __LINE__, status);
780             test_control_return(1);
781         }
782         for (i = 0; i < 512; i ++)
783         {
784             if (buffer[i] != (UCHAR)i)
785             {
786                 printf("ERROR %d: %d <> %d\n", __LINE__, i, buffer[i]);
787                 test_control_return(1);
788             }
789         }
790     }
791 
792     /* Disk write/read multiple test.  */
793     for (test_n = 0; test_n < sizeof(test_size)/sizeof(test_size[0]); test_n ++)
794     {
795         stepinfo(">>>>>>>>>>>> Disk write(%ld)/read(%ld) test\n",
796                                         test_size[test_n], test_size[test_n]);
797 
798         for(i = 0; i < test_size[test_n] * 512; i ++)
799             buffer[i] = (UCHAR)(i + (i >> 8));
800         status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
801                 buffer, 48, test_size[test_n]);
802         if (status != FX_SUCCESS)
803         {
804             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
805             test_control_return(1);
806         }
807         _ux_utility_memory_set(buffer, 0x00, test_size[test_n] * 512);
808         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
809                 buffer, 48, test_size[test_n]);
810         if (status != FX_SUCCESS)
811         {
812             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
813             test_control_return(1);
814         }
815         for (i = 0; i < 512; i ++)
816         {
817             if (buffer[i] != (UCHAR)(i + (i >> 8)))
818             {
819                 printf("ERROR %d: %d <> %d\n", __LINE__, i, buffer[i]);
820                 test_control_return(1);
821             }
822         }
823     }
824 }
825 
_msc_enumeration_test(const char * __file__,int __line__,unsigned option)826 static void _msc_enumeration_test(const char* __file__, int __line__, unsigned option)
827 {
828 UINT                                        status;
829 ULONG                                       mem_free;
830 ULONG                                       test_n;
831 
832     stepinfo("\n%s:%d:MSC Enumeration tests\n", __file__, __line__);
833 
834     stepinfo(">>>>>>>>>>>> Enumeration information collection\n");
835     {
836 
837         /* Test disconnect. */
838         ux_test_dcd_sim_slave_disconnect();
839         ux_test_hcd_sim_host_disconnect();
840 
841         /* Check connection. */
842         status = host_storage_instance_get(0);
843         if (status == UX_SUCCESS)
844         {
845 
846             printf("ERROR #%d\n", __LINE__);
847             test_control_return(1);
848         }
849 
850         /* Reset testing counts. */
851         ux_test_utility_sim_mem_alloc_count_reset();
852         ux_test_utility_sim_mutex_create_count_reset();
853         ux_test_utility_sim_sem_create_count_reset();
854         ux_test_utility_sim_sem_get_count_reset();
855         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
856 
857         /* Save free memory usage. */
858         mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
859         ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
860         ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
861 
862         /* Check connection. */
863         status =  host_storage_instance_get(100);
864         if (status != UX_SUCCESS)
865         {
866 
867             printf("ERROR #%d\n", __LINE__);
868             test_control_return(1);
869         }
870 
871         /* Log create counts for further tests. */
872         rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
873         rsc_enum_sem_usage = rsc_sem_on_set_cfg;
874         rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
875         /* Log create counts when instances active for further tests. */
876         rsc_storage_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
877         rsc_storage_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
878         rsc_storage_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
879 
880         /* Lock log base for tests. */
881         ux_test_utility_sim_mem_alloc_log_lock();
882 
883         stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
884         stepinfo("storage mem : %ld\n", rsc_storage_mem_alloc_count);
885         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);
886     }
887 
888     /* Simulate detach and attach for FS enumeration,
889        and check if there is memory error in normal enumeration.
890      */
891     if (option & (1u))
892     {
893         stepinfo(">>>>>>>>>>>> Enumeration test\n");
894         mem_free = (~0);
895         for (test_n = 0; test_n < 3; test_n++)
896         {
897             stepinfo("%4ld / 2\n", test_n);
898 
899             /* Disconnect. */
900             ux_test_dcd_sim_slave_disconnect();
901             ux_test_hcd_sim_host_disconnect();
902 
903             /* Check */
904             if (host_storage_instance_get(0) == UX_SUCCESS)
905             {
906 
907                 printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
908                 test_control_return(1);
909             }
910 
911             /* Update memory free level (disconnect) */
912             if (mem_free == (~0))
913                 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
914             else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
915             {
916 
917                 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);
918                 test_control_return(1);
919             }
920 
921             /* Connect. */
922             error_callback_counter = 0;
923             ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
924             ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
925 
926             /* Wait and break on error. */
927             error_callback_counter = 0;
928             ux_test_breakable_sleep(
929                 (UX_MS_TO_TICK_NON_ZERO(UX_RH_ENUMERATION_RETRY_DELAY) +
930                  UX_MS_TO_TICK_NON_ZERO(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY)) *
931                 50,
932                 sleep_break_on_connect);
933 
934             /* Check */
935             if (host_storage_instance_get(0) != UX_SUCCESS)
936             {
937 
938                 printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
939                 test_control_return(1);
940             }
941         }
942         stepinfo("\n");
943     }
944 
945     /* Simulate detach and attach for FS enumeration,
946        and test possible memory allocation error handlings.
947      */
948     if (option & (2u))
949     {
950         if (rsc_storage_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
951         mem_free = (~0);
952         for (test_n = 0; test_n < rsc_storage_mem_alloc_count; test_n ++)
953         {
954 
955             stepinfo("%4ld / %4ld\n", test_n, rsc_storage_mem_alloc_count - 1);
956 
957             /* Disconnect. */
958             ux_test_dcd_sim_slave_disconnect();
959             ux_test_hcd_sim_host_disconnect();
960 
961             /* Check */
962             if (host_storage_instance_get(0) == UX_SUCCESS)
963             {
964 
965                 stepinfo("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
966                 test_control_return(1);
967             }
968 
969             /* Update memory free level (disconnect) */
970             if (mem_free == (~0))
971                 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
972             else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
973             {
974 
975                 stepinfo("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);
976                 test_control_return(1);
977             }
978 
979             /* Set memory error generation */
980             ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
981 
982             /* Connect. */
983             error_callback_counter = 0;
984             ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
985             ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
986 
987             /* Wait and break on errors. */
988             ux_test_breakable_sleep(100, sleep_break_on_error);
989 
990             /* Check error */
991             if (host_storage_instance_get(0) == UX_SUCCESS)
992             {
993 
994                 /* Could be media errors,
995                    in this case instance is ready,
996                    check error trap. */
997                 if (error_callback_counter == 0)
998                 {
999                     stepinfo("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
1000                     test_control_return(1);
1001                 }
1002             }
1003             stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1004         }
1005         ux_test_utility_sim_mem_alloc_error_generation_stop();
1006         if (rsc_storage_mem_alloc_count) stepinfo("\n");
1007     }
1008 
1009     /* If storage disconnected, re-connect.  */
1010     if (host_storage_instance_get(0) != UX_SUCCESS)
1011     {
1012         ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
1013         ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
1014 
1015         ux_test_breakable_sleep(
1016             (UX_MS_TO_TICK_NON_ZERO(UX_RH_ENUMERATION_RETRY_DELAY) +
1017                 UX_MS_TO_TICK_NON_ZERO(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY)) *
1018             50,
1019             sleep_break_on_connect);
1020 
1021         /* Check */
1022         if (host_storage_instance_get(0) != UX_SUCCESS)
1023         {
1024 
1025             printf("ERROR #%d: Enumeration fail\n", __LINE__);
1026             test_control_return(1);
1027         }
1028     }
1029 }
1030 
_msc_media_write_read_misc_test(const char * __file__,int __line__)1031 static void _msc_media_write_read_misc_test(const char* __file__, int __line__)
1032 {
1033 UINT                                        status;
1034 UINT                                        test_size = UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512;
1035 UINT                                        test_n;
1036 ULONG                                       test_start;
1037 ULONG                                       test_ticks;
1038 INT                                         i;
1039 
1040     stepinfo("\n%s:%d:MSC Media Read tests\n", __file__, __line__);
1041 
1042     if (media == UX_NULL || media -> fx_media_id == 0)
1043     {
1044         printf("ERROR %d.%d: media error\n", __LINE__, __line__);
1045         test_control_return(1);
1046     }
1047 
1048     stepinfo(">>>>>>>>>>>> Disk read(%d) test - tick obtain\n", test_size);
1049     test_start = tx_time_get();
1050     status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
1051             buffer, 0, test_size);
1052     test_ticks = _test_dw_minus(tx_time_get(), test_start);
1053     if (status != UX_SUCCESS)
1054     {
1055         printf("ERROR %d.%d: 0x%x\n", __LINE__, __line__, status);
1056         test_control_return(1);
1057     }
1058     test_ticks /= 3;
1059     stepinfo(" :: Buffer XFR time: %ld ticks\n", test_ticks);
1060 
1061     stepinfo(">>>>>>>>>>>> Disk write/read(%d) test - slow disk write/read\n", test_size);
1062     for(test_n = 0; test_n < 1; test_n ++)
1063     {
1064         stepinfo(">>>>>>>>>>>> Disk write/read(%d) test - disk write/read\n", test_size);
1065         for(i = 0; i < test_size * 512; i ++)
1066             buffer[i] = (UCHAR)(i + (i >> 8));
1067         ram_disk_rw_wait_start = tx_time_get();
1068         status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
1069                 buffer, 48, test_size);
1070         if (status != FX_SUCCESS)
1071         {
1072             printf("ERROR %d.%d.%d: 0x%x\n", __LINE__, __line__, test_n, status);
1073             test_control_return(1);
1074         }
1075         _ux_utility_memory_set(buffer, 0x00, test_size * 512);
1076         ram_disk_rw_wait_start = tx_time_get();
1077         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
1078                 buffer, 48, test_size);
1079         if (status != FX_SUCCESS)
1080         {
1081             printf("ERROR %d.%d.%d: 0x%x\n", __LINE__, __line__, test_n, status);
1082             test_control_return(1);
1083         }
1084         for (i = 0; i < 512; i ++)
1085         {
1086             if (buffer[i] != (UCHAR)(i + (i >> 8)))
1087             {
1088                 printf("ERROR %d.%d.%d: %d <> %d\n", __LINE__, __line__, test_n, i, buffer[i]);
1089                 test_control_return(1);
1090             }
1091         }
1092     }
1093 }
1094 
_msc_media_write_read_disconnect_test(const char * __file__,int __line__)1095 static void _msc_media_write_read_disconnect_test(const char* __file__, int __line__)
1096 {
1097 UINT        status;
1098 ULONG       test_size = 1;
1099 UINT        i;
1100 
1101     stepinfo("\n%s:%d:MSC Device Disconnect on Media Writing & Reading tests\n", __file__, __line__);
1102 
1103     /* Check if media still available.  */
1104     if (media == UX_NULL || media -> fx_media_id == 0)
1105     {
1106         printf("ERROR %d: media error\n", __LINE__);
1107         test_control_return(1);
1108     }
1109 
1110     stepinfo(">>>>>>>>>>>> Device disconnect on writing test\n");
1111     ram_disk_rw_disconnect = 1;
1112     ram_disk_rw_disconnect_count = 0;
1113     for(i = 0; i < test_size * 512; i ++)
1114         buffer[i] = (UCHAR)(i + (i >> 8));
1115     status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
1116             buffer, 48, test_size);
1117     ux_test_breakable_sleep(100, sleep_break_on_error);
1118     if (status == FX_SUCCESS)
1119     {
1120         printf("%s:%d:%d expect write fail\n", __file__, __line__, __LINE__);
1121         test_control_return(1);
1122     }
1123     if (ram_disk_rw_disconnect_count != 1)
1124     {
1125         printf("%s:%d:%d expect write once\n", __file__, __line__, __LINE__);
1126         test_control_return(1);
1127     }
1128     if (host_storage_instance_get(0) == UX_SUCCESS)
1129     {
1130         printf("%s:%d:%d expect device disconnect\n", __file__, __line__, __LINE__);
1131         test_control_return(1);
1132     }
1133 
1134     stepinfo(">>>>>>>>>>>> Device connect after disconnect on writing check\n");
1135     error_callback_counter = 0;
1136     ram_disk_rw_disconnect = 0;
1137     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1138     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1139 
1140     /* Wait and break on errors. */
1141     ux_test_breakable_sleep(1000, sleep_break_on_connect);
1142 
1143     /* Check error */
1144     if (host_storage_instance_get(0) != UX_SUCCESS)
1145     {
1146         printf("%s:%d:%d device re-connect fail\n", __file__, __line__, __LINE__);
1147         test_control_return(1);
1148     }
1149 
1150     stepinfo(">>>>>>>>>>>> Disk disconnect on reading test\n");
1151     ram_disk_rw_disconnect = 1;
1152     ram_disk_rw_disconnect_count = 0;
1153     _ux_utility_memory_set(buffer, 0x00, test_size * 512);
1154     ram_disk_rw_wait_start = tx_time_get();
1155     status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
1156             buffer, 48, test_size);
1157     ux_test_breakable_sleep(100, sleep_break_on_error);
1158     if (status == FX_SUCCESS)
1159     {
1160         printf("%s:%d:%d expect read fail\n", __file__, __line__, __LINE__);
1161         test_control_return(1);
1162     }
1163     if (ram_disk_rw_disconnect_count != 1)
1164     {
1165         printf("%s:%d:%d expect write once\n", __file__, __line__, __LINE__);
1166         test_control_return(1);
1167     }
1168     if (host_storage_instance_get(0) == UX_SUCCESS)
1169     {
1170         printf("%s:%d:%d expect device disconnect\n", __file__, __line__, __LINE__);
1171         test_control_return(1);
1172     }
1173 
1174     stepinfo(">>>>>>>>>>>> Device connect after disconnect on reading check\n");
1175     error_callback_counter = 0;
1176     ram_disk_rw_disconnect = 0;
1177     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1178     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1179 
1180     /* Wait and break on errors. */
1181     ux_test_breakable_sleep(1000, sleep_break_on_connect);
1182 
1183     /* Check error */
1184     if (host_storage_instance_get(0) != UX_SUCCESS)
1185     {
1186         stepinfo("%s:%d:%d device re-connect fail\n", __file__, __line__, __LINE__);
1187         test_control_return(1);
1188     }
1189 }
1190 
_msc_media_insert_eject_test(const char * __file__,int __line__)1191 static void _msc_media_insert_eject_test(const char* __file__, int __line__)
1192 {
1193 UINT test_n;
1194 UINT connected;
1195 UINT status;
1196 
1197     stepinfo("\n%s:%d:MSC Media Insert/Eject tests\n", __file__, __line__);
1198 
1199     if (media == UX_NULL || media -> fx_media_id == 0)
1200     {
1201         printf("ERROR %d.%d: media error\n", __LINE__, __line__);
1202         test_control_return(1);
1203     }
1204 
1205     /* LUN Eject/Insert detection with host stack tasks run and storage media get.  */
1206     connected = UX_TRUE;
1207     error_counter = 0;
1208     for (test_n = 0; test_n < 3; test_n ++)
1209     {
1210 
1211         if (connected)
1212         {
1213             stepinfo(">>>>>>>>>>>> Disk Eject test #%d\n", __LINE__);
1214             ram_disk_status = UX_ERROR;
1215             ram_disk_media_attention = 0;
1216             ram_disk_media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02, 0x3A, 0x00);
1217             ux_test_breakable_sleep(UX_MS_TO_TICK(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME) * 3 / 2,
1218                                     sleep_break_on_disconnect);
1219             connected = host_storage_instance_get(0) == UX_SUCCESS;
1220             if (connected)
1221             {
1222 
1223                 printf("ERROR #%d: LUN eject fail\n", __LINE__);
1224                 error_counter ++;
1225                 continue;
1226             }
1227         }
1228 
1229         if (!connected)
1230         {
1231             stepinfo(">>>>>>>>>>>> Disk Insert test #%d\n", __LINE__);
1232             ram_disk_status = UX_SUCCESS;
1233             ram_disk_media_attention = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x06, 0x28, 0x00);
1234             ram_disk_media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x00, 0x00, 0x00);
1235             error_callback_counter = 0;
1236             ux_test_breakable_sleep(UX_MS_TO_TICK(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME) * 3 / 2,
1237                                     sleep_break_on_connect);
1238             connected = host_storage_instance_get(0) == UX_SUCCESS;
1239             if (!connected)
1240             {
1241 
1242                 printf("ERROR #%d: LUN insert fail\n", __LINE__);
1243                 error_counter ++;
1244                 continue;
1245             }
1246         }
1247     }
1248     if (error_counter > 0)
1249     {
1250         printf("ERROR #%d.%d: LUN change detection fail\n", __LINE__, __line__);
1251         test_control_return(1);
1252     }
1253 
1254     /* LUN Eject/Insert detection with media check (blocking).  */
1255     error_counter = 0;
1256     for (test_n = 0; test_n < 3; test_n ++)
1257     {
1258 
1259         stepinfo(">>>>>>>>>>>> Disk Eject test #%d\n", __LINE__);
1260         ram_disk_status = UX_ERROR;
1261         ram_disk_media_attention = 0;
1262         ram_disk_media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02, 0x3A, 0x00);
1263         status = ux_host_class_storage_media_lock(storage_media, 100);
1264         if (status != UX_SUCCESS)
1265         {
1266             printf("ERROR #%d.%d: LUN lock fail 0x%x\n", __LINE__, __line__, status);
1267             test_control_return(1);
1268         }
1269         status = ux_host_class_storage_media_check(storage_media->ux_host_class_storage_media_storage);
1270         if (status == UX_SUCCESS)
1271         {
1272             printf("ERROR #%d.%d: LUN Eject fail\n", __LINE__, __line__);
1273             test_control_return(1);
1274         }
1275         ux_host_class_storage_media_unlock(storage_media);
1276         /* Unmount media.  */
1277         _ux_host_class_storage_media_remove(storage_media);
1278 
1279         stepinfo(">>>>>>>>>>>> Disk Insert test #%d\n", __LINE__);
1280         ram_disk_status = UX_SUCCESS;
1281         ram_disk_media_attention = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x06, 0x28, 0x00);
1282         ram_disk_media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x00, 0x00, 0x00);
1283         status = ux_host_class_storage_media_lock(storage_media, 100);
1284         if (status != UX_SUCCESS)
1285         {
1286             printf("ERROR #%d.%d: LUN lock fail 0x%x\n", __LINE__, __line__, status);
1287             test_control_return(1);
1288         }
1289         status = ux_host_class_storage_media_check(storage_media->ux_host_class_storage_media_storage);
1290         if (status != UX_SUCCESS)
1291         {
1292             printf("ERROR #%d.%d: LUN Insert fail 0x%x\n", __LINE__, __line__, status);
1293             test_control_return(1);
1294         }
1295         ux_host_class_storage_media_unlock(storage_media);
1296         /* Mount media.  */
1297         _ux_host_class_storage_media_insert(storage_media, 1);
1298         media = _ux_host_class_storage_media_fx_media(storage_media);
1299     }
1300 }
1301 
tx_demo_thread_host_simulation_entry(ULONG arg)1302 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
1303 {
1304 
1305 UINT                                        status;
1306 
1307 
1308     /* Find the storage class. */
1309     status =  host_storage_instance_get(500);
1310     if (status != UX_SUCCESS)
1311     {
1312 
1313         printf("ERROR #%d\n", __LINE__);
1314         test_control_return(1);
1315     }
1316 
1317     stepinfo(">>>>>>>>>>>> MSC Read Write test\n");
1318 
1319     _msc_media_write_read_disconnect_test(__FILE__, __LINE__);
1320     _msc_media_write_read_test(__FILE__, __LINE__);
1321     _msc_media_write_read_misc_test(__FILE__, __LINE__);
1322 
1323     /* Finally disconnect the device. */
1324     ux_device_stack_disconnect();
1325 
1326     /* And deinitialize the class.  */
1327     status =  ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
1328 
1329     /* Deinitialize the device side of usbx.  */
1330     _ux_device_stack_uninitialize();
1331 
1332     /* And finally the usbx system resources.  */
1333     _ux_system_uninitialize();
1334 
1335     /* Successful test.  */
1336     printf("SUCCESS!\n");
1337     test_control_return(0);
1338 }
1339 
1340 
demo_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)1341 static UINT    demo_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
1342 {
1343 
1344 static UCHAR lun_init_done[2] = {0, 0};
1345 UINT         status;
1346 ULONG        mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE;
1347 
1348 
1349     (void)storage;
1350     (void)media_id;
1351 
1352     if (lun == 0 && ram_disk_media_attention)
1353     {
1354         if (media_status)
1355             *media_status = ram_disk_media_attention;
1356         ram_disk_media_attention = 0;
1357         return(UX_ERROR);
1358     }
1359     if (lun == 0 && ram_disk_status)
1360     {
1361         status = ram_disk_status;
1362         if (media_status)
1363             *media_status = ram_disk_media_status;
1364         ram_disk_status_sent = UX_TRUE;
1365         return(status);
1366     }
1367 
1368     if (lun > 1)
1369         status = (UX_ERROR);
1370     else if (lun_init_done[lun] > 0)
1371         status = (UX_SUCCESS);
1372     else
1373     {
1374         lun_init_done[lun] ++;
1375         mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
1376         status = (UX_ERROR);
1377     }
1378 
1379     if (media_status)
1380         *media_status = mstatus;
1381 
1382     return status;
1383 }
1384 
demo_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)1385 static UINT    demo_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
1386 {
1387 
1388 UINT    status =  0;
1389 
1390     if (ram_disk_rw_disconnect)
1391     {
1392         ram_disk_rw_disconnect_count ++;
1393         ux_test_dcd_sim_slave_disconnect();
1394         ux_test_hcd_sim_host_disconnect();
1395         return(UX_ERROR);
1396     }
1397 
1398     status = _media_driver_read(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
1399     if (status != UX_SUCCESS)
1400     {
1401         *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
1402         return(UX_ERROR);
1403     }
1404     return(UX_SUCCESS);
1405 }
1406 
demo_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)1407 static UINT    demo_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
1408 {
1409 
1410 UINT    status =  0;
1411 
1412     if (ram_disk_rw_disconnect)
1413     {
1414         ram_disk_rw_disconnect_count ++;
1415         ux_test_dcd_sim_slave_disconnect();
1416         ux_test_hcd_sim_host_disconnect();
1417         return(UX_ERROR);
1418     }
1419 
1420     status = _media_driver_write(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
1421     if (status != UX_SUCCESS)
1422     {
1423         *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
1424         return(UX_ERROR);
1425     }
1426     return(UX_SUCCESS);
1427 }
1428 
demo_media_flush(VOID * storage,ULONG lun,ULONG number_blocks,ULONG lba,ULONG * media_status)1429 static UINT    demo_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status)
1430 {
1431     (void)storage;
1432     (void)number_blocks;
1433     (void)lba;
1434     (void)media_status;
1435 
1436     if (lun > 1)
1437         return UX_STATE_ERROR;
1438 
1439     ram_disk_flush = UX_TRUE;
1440     return ram_disk_flush_status;
1441 }
1442 
ux_test_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)1443 static UINT ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
1444 {
1445 
1446     switch(event)
1447     {
1448 
1449         case UX_DEVICE_INSERTION:
1450             stepinfo("Function insert: %p, %p\n", (void*)cls, inst);
1451             break;
1452 
1453         case UX_DEVICE_REMOVAL:
1454             stepinfo("Function removal: %p, %p\n", (void*)cls, inst);
1455             break;
1456 
1457         case UX_DEVICE_CONNECTION:
1458             stepinfo("Device connect: %p, %p\n", (void*)cls, inst);
1459             break;
1460 
1461         case UX_DEVICE_DISCONNECTION:
1462             stepinfo("Device disconnect: %p, %p\n", (void*)cls, inst);
1463             break;
1464 
1465         case UX_STORAGE_MEDIA_INSERTION:
1466             stepinfo("Media insert: %p\n", inst);
1467             break;
1468 
1469         case UX_STORAGE_MEDIA_REMOVAL:
1470             stepinfo("Media removal: %p\n", inst);
1471             break;
1472 
1473         case UX_STANDALONE_WAIT_BACKGROUND_TASK:
1474             tx_thread_relinquish();
1475 
1476         default:
1477             break;
1478     }
1479 
1480     return 0;
1481 }
1482 
dump_data(UCHAR * buf,ULONG len)1483 static void dump_data(UCHAR *buf, ULONG len)
1484 {
1485 ULONG l;
1486     for(l = 0; l < len; l ++)
1487     {
1488         if ((l % 32) == 0) printf("\n[%4ld]", l);
1489         printf(" %02X", buf[l]);
1490     }
1491     printf("\n");
1492 }
demo_host_media_read_write_notify(UINT fx_req,UINT fx_rc,UX_HOST_CLASS_STORAGE * storage,ULONG sec_start,ULONG sec_count,UCHAR * buf)1493 static VOID demo_host_media_read_write_notify(UINT fx_req, UINT fx_rc,
1494                                 UX_HOST_CLASS_STORAGE *storage,
1495                                 ULONG sec_start, ULONG sec_count, UCHAR* buf)
1496 {
1497     UX_PARAMETER_NOT_USED(fx_req);
1498     UX_PARAMETER_NOT_USED(fx_rc);
1499     UX_PARAMETER_NOT_USED(storage);
1500     UX_PARAMETER_NOT_USED(sec_start);
1501     UX_PARAMETER_NOT_USED(sec_count);
1502     UX_PARAMETER_NOT_USED(buf);
1503 #if 0
1504     if (fx_req == FX_DRIVER_READ)
1505     {
1506         printf("Read(%ld,%ld) : 0x%x\n", sec_start, sec_count, fx_rc);
1507     }
1508     if (fx_req == FX_DRIVER_WRITE)
1509     {
1510         printf("Write(%ld,%ld) : 0x%x\n", sec_start, sec_count, fx_rc);
1511     }
1512     dump_data(buf, 1 * 512);
1513 
1514     printf("Ref data:");
1515     dump_data(ram_disk_memory1 + sec_start * 512, 1 * 512);
1516 #endif
1517 }
1518