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