1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_class_storage.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_stack.h"
14 #include "ux_host_class_storage.h"
15 
16 #include "ux_test_dcd_sim_slave.h"
17 #include "ux_test_hcd_sim_host.h"
18 #include "ux_test_utility_sim.h"
19 
20 /* Define constants.  */
21 #define                             UX_DEMO_STACK_SIZE              2048
22 #define                             UX_DEMO_MEMORY_SIZE             (256*1024)
23 #define                             UX_DEMO_BUFFER_SIZE             2048
24 
25 #define                             UX_RAM_DISK_SIZE                (200 * 1024)
26 #define                             UX_RAM_DISK_LAST_LBA            ((UX_RAM_DISK_SIZE / 512) -1)
27 
28 /* Define local/extern function prototypes.  */
29 
30 VOID _fx_ram_driver(FX_MEDIA *media_ptr);
31 void _fx_ram_drive_format(ULONG disk_size, UINT sector_size, UINT sectors_per_cluster,
32                                                 UINT fat_entries, UINT root_directory_entries);
33 
34 static void        demo_thread_entry(ULONG);
35 static TX_THREAD   tx_demo_thread_host_simulation;
36 static TX_THREAD   tx_demo_thread_slave_simulation;
37 static void        tx_demo_thread_host_simulation_entry(ULONG);
38 
39 static UINT        demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
40 static UINT        demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
41 static UINT        demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
42 static UINT        demo_thread_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status);
43 
44 /* Define global data structures.  */
45 
46 static UCHAR                        usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
47 static UCHAR                        buffer[UX_DEMO_BUFFER_SIZE];
48 
49 static ULONG                        error_counter;
50 
51 static TX_THREAD                    demo_thread;
52 
53 static UX_HOST_CLASS_STORAGE                *storage;
54 static UX_SLAVE_CLASS_STORAGE_PARAMETER     global_storage_parameter;
55 
56 static FX_MEDIA                     ram_disk_media1;
57 static FX_MEDIA                     ram_disk_media2;
58 static CHAR                         ram_disk_buffer1[512];
59 static CHAR                         ram_disk_buffer2[512];
60 static CHAR                         ram_disk_memory1[UX_RAM_DISK_SIZE];
61 static CHAR                         ram_disk_memory2[UX_RAM_DISK_SIZE];
62 static CHAR                         *ram_disk_memory[] =
63 {
64     ram_disk_memory1, ram_disk_memory2
65 };
66 static UINT                         ram_disk_status = UX_SUCCESS;
67 static ULONG                        ram_disk_media_status = 0;
68 static ULONG                        ram_disk_status_loop = 0;
69 static ULONG                        ram_disk_status_sent = 0;
70 
71 static UINT                         ram_disk_read_status = UX_SUCCESS;
72 static ULONG                        ram_disk_read_media_status = 0;
73 static CHAR                         ram_disk_read_sent = 0;
74 
75 static CHAR                         ram_disk_flush = 0;
76 static UINT                         ram_disk_flush_status = UX_SUCCESS;
77 
78 static ULONG                               set_cfg_counter;
79 
80 static ULONG                               rsc_mem_alloc_cnt_on_set_cfg;
81 static ULONG                               rsc_sem_on_set_cfg;
82 static ULONG                               rsc_sem_get_on_set_cfg;
83 static ULONG                               rsc_mutex_on_set_cfg;
84 
85 static ULONG                               rsc_enum_sem_usage;
86 static ULONG                               rsc_enum_sem_get_count;
87 static ULONG                               rsc_enum_mutex_usage;
88 static ULONG                               rsc_enum_mem_alloc_count;
89 
90 static ULONG                               rsc_storage_sem_usage;
91 static ULONG                               rsc_storage_sem_get_count;
92 static ULONG                               rsc_storage_mutex_usage;
93 static ULONG                               rsc_storage_mem_alloc_count;
94 
95 static ULONG                               interaction_count;
96 
97 static UCHAR                               error_callback_ignore = UX_TRUE;
98 static ULONG                               error_callback_counter;
99 
100 static ULONG                               semaphore_error_start;
101 static ULONG                               semaphore_counter;
102 
103 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
104 static UCHAR device_framework_full_speed[] = {
105 
106     /* Device descriptor */
107         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
108         0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
109         0x03, 0x01,
110 
111     /* Configuration descriptor */
112         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
113         0x32,
114 
115     /* Interface descriptor */
116         0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
117         0x00,
118 
119     /* Endpoint descriptor (Bulk Out) */
120         0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
121 
122     /* Endpoint descriptor (Bulk In) */
123         0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
124 
125     };
126 
127 
128 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
129 static UCHAR device_framework_high_speed[] = {
130 
131     /* Device descriptor */
132         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
133         0x81, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
134         0x03, 0x01,
135 
136     /* Device qualifier descriptor */
137         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
138         0x01, 0x00,
139 
140     /* Configuration descriptor */
141         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
142         0x32,
143 
144     /* Interface descriptor */
145         0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
146         0x00,
147 
148     /* Endpoint descriptor (Bulk Out) */
149         0x07, 0x05, 0x02, 0x02, 0x00, 0x01, 0x00,
150 
151     /* Endpoint descriptor (Bulk In) */
152         0x07, 0x05, 0x81, 0x02, 0x00, 0x01, 0x00,
153 
154     };
155 
156 
157     /* String Device Framework :
158      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
159      Byte 2       : Byte containing the index of the descriptor
160      Byte 3       : Byte containing the length of the descriptor string
161     */
162 
163 #define STRING_FRAMEWORK_LENGTH 38
164 static UCHAR string_framework[] = {
165 
166     /* Manufacturer string descriptor : Index 1 */
167         0x09, 0x04, 0x01, 0x0c,
168         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
169         0x6f, 0x67, 0x69, 0x63,
170 
171     /* Product string descriptor : Index 2 */
172         0x09, 0x04, 0x02, 0x0a,
173         0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x44, 0x69,
174         0x73, 0x6b,
175 
176     /* Serial Number string descriptor : Index 3 */
177         0x09, 0x04, 0x03, 0x04,
178         0x30, 0x30, 0x30, 0x31
179     };
180 
181 
182     /* Multiple languages are supported on the device, to add
183        a language besides english, the unicode language code must
184        be appended to the language_id_framework array and the length
185        adjusted accordingly. */
186 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
187 static UCHAR language_id_framework[] = {
188 
189     /* English. */
190         0x09, 0x04
191     };
192 
193 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
194 FX_MEDIA    *_ux_host_class_storage_driver_media(INT i);
195 VOID        _ux_host_class_storage_driver_entry(FX_MEDIA *media);
196 VOID        _ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG format_open);
197 VOID        _ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
198 FX_MEDIA    *_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
199 UCHAR       *_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
200 
ux_test_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)201 static UINT ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
202 {
203 
204     switch(event)
205     {
206 
207         case UX_STORAGE_MEDIA_INSERTION:
208             _ux_host_class_storage_media_insert((UX_HOST_CLASS_STORAGE_MEDIA*)inst, 1);
209             break;
210 
211         case UX_STORAGE_MEDIA_REMOVAL:
212             _ux_host_class_storage_media_remove((UX_HOST_CLASS_STORAGE_MEDIA*)inst);
213             _ux_host_class_storage_media_fx_media((UX_HOST_CLASS_STORAGE_MEDIA*)inst) -> fx_media_id = 0;/* Testing code is checking ID to detect removal.  */
214             break;
215 
216         default:
217             break;
218     }
219 
220     return 0;
221 }
222 #else
223 #define ux_test_system_host_change_function UX_NULL
224 #endif
225 
226 static UX_TEST_SETUP _GetMaxLun = UX_TEST_SETUP_STORAGE_GetMaxLun;
227 
228 static UX_TEST_HCD_SIM_ACTION stall_GetMaxLun[] = {
229 /* function, request to match,
230    port action, port status,
231    request action, request EP, request data, request actual length, request status,
232    status, additional callback,
233    no_return */
234 {   UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
235         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
236         UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 1, UX_TRANSFER_STALLED,
237         UX_TRANSFER_STALLED, UX_NULL},
238 {   0   }
239 };
240 
241 static UX_TEST_HCD_SIM_ACTION length_error_GetMaxLun[] = {
242 /* function, request to match,
243    port action, port status,
244    request action, request EP, request data, request actual length, request status,
245    status, additional callback,
246    no_return */
247 {   UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
248         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
249         UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 2, UX_SUCCESS,
250         UX_SUCCESS, UX_NULL},
251 {   0   }
252 };
253 
254 static UX_TEST_HCD_SIM_ACTION replaced_GetMaxLun[] = {
255 /* function, request to match,
256    port action, port status,
257    request action, request EP, request data, request actual length, request status,
258    status, additional callback,
259    no_return */
260 {   UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
261         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
262         UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 1, UX_SUCCESS,
263         UX_SUCCESS, UX_NULL},
264 {   0   }
265 };
266 
267 static UX_TEST_HCD_SIM_ACTION fail_bulk_out[] = {
268 /* function, request to match,
269    port action, port status,
270    request action, request EP, request data, request actual length, request status,
271    status, additional callback,
272    no_return */
273 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
274         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
275         UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
276         UX_ERROR, UX_NULL},
277 {   0   }
278 };
279 
280 static UX_TEST_HCD_SIM_ACTION fail_2nd_bulk_out[] = {
281 /* function, request to match,
282    port action, port status,
283    request action, request EP, request data, request actual length, request status,
284    status, additional callback,
285    no_return */
286 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
287         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
288         UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_SUCCESS,
289         UX_SUCCESS, UX_NULL,
290         UX_TRUE},
291 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
292         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
293         UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
294         UX_ERROR, UX_NULL},
295 {   0   }
296 };
297 
ux_host_class_storage_semaphore_callback(UX_TEST_ACTION * action,VOID * params)298 static void ux_host_class_storage_semaphore_callback(UX_TEST_ACTION *action, VOID *params)
299 {
300 
301 UX_TEST_OVERRIDE_TX_SEMAPHORE_GET_PARAMS *semaphore_get_param = params;
302 
303     // printf("semaphore_call:%p\n", semaphore_get_param->semaphore_ptr);
304     if (semaphore_error_start == 0xFFFFFFFF)
305         return;
306 
307     semaphore_counter ++;
308     if (semaphore_counter > semaphore_error_start)
309     {
310         // printf("!! Semaphore del: %p\n", semaphore_get_param->semaphore_ptr);
311         _ux_utility_semaphore_delete(semaphore_get_param->semaphore_ptr);
312     }
313 }
314 
315 static UX_TEST_ACTION ux_host_class_storage_semaphore_get_hook[] =
316 {
317     {
318         .usbx_function = UX_TEST_OVERRIDE_TX_SEMAPHORE_GET,
319         .semaphore_ptr = UX_NULL,
320         .wait_option = TX_WAIT_FOREVER,
321         .do_after = UX_FALSE,
322         .action_func = ux_host_class_storage_semaphore_callback,
323     },
324 { 0 },
325 };
326 
327 /* Define the ISR dispatch.  */
328 
329 extern VOID    (*test_isr_dispatch)(void);
330 
331 
332 /* Prototype for test control return.  */
333 
334 void  test_control_return(UINT status);
335 
336 
337 /* Define the ISR dispatch routine.  */
338 
test_isr(void)339 static void    test_isr(void)
340 {
341 
342     /* For further expansion of interrupt-level testing.  */
343 }
344 
345 
error_callback(UINT system_level,UINT system_context,UINT error_code)346 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
347 {
348 
349     error_callback_counter ++;
350 
351     if (!error_callback_ignore)
352     {
353         {
354             /* Failed test.  */
355             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
356             test_control_return(1);
357         }
358     }
359 }
360 
host_storage_instance_get(ULONG timeout_x10ms)361 static UINT host_storage_instance_get(ULONG timeout_x10ms)
362 {
363 
364 UINT                status;
365 UX_HOST_CLASS       *class;
366 
367 
368     /* Find the main storage container */
369     status =  ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
370     if (status != UX_SUCCESS)
371         return(status);
372 
373     /* Get storage instance, wait it to be live and media attached.  */
374     do
375     {
376         if (timeout_x10ms)
377         {
378             ux_utility_delay_ms(10);
379             if (timeout_x10ms != 0xFFFFFFFF)
380                 timeout_x10ms --;
381         }
382 
383         status =  ux_host_stack_class_instance_get(class, 0, (void **) &storage);
384         if (status == UX_SUCCESS)
385         {
386             if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_LIVE &&
387                 class -> ux_host_class_media != UX_NULL)
388                 return(UX_SUCCESS);
389         }
390 
391     } while(timeout_x10ms > 0);
392 
393     return(UX_ERROR);
394 }
395 
sleep_break_on_error(VOID)396 static UINT  sleep_break_on_error(VOID)
397 {
398 
399     if (error_callback_counter >= 3)
400         return error_callback_counter;
401 
402     return UX_SUCCESS;
403 }
404 
405 
406 /* Define what the initial system looks like.  */
407 
408 #ifdef CTEST
test_application_define(void * first_unused_memory)409 void test_application_define(void *first_unused_memory)
410 #else
411 void    usbx_ux_host_class_storage_thread_entry_test_application_define(void *first_unused_memory)
412 #endif
413 {
414 
415 UINT                            status;
416 CHAR *                          stack_pointer;
417 CHAR *                          memory_pointer;
418 
419 
420     /* Inform user.  */
421     printf("Running ux_host_class_storage_thread_entry Test..................... ");
422     stepinfo("\n");
423 
424     /* Initialize the free memory pointer */
425     stack_pointer = (CHAR *) usbx_memory;
426     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
427 
428     /* Initialize USBX. Memory */
429     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
430 
431     /* Check for error.  */
432     if (status != UX_SUCCESS)
433     {
434 
435         printf("ERROR #%d\n", __LINE__);
436         test_control_return(1);
437     }
438 
439     /* Register the error callback. */
440     _ux_utility_error_callback_register(error_callback);
441 
442     /* Reset ram disks memory.  */
443     ux_utility_memory_set(ram_disk_memory1, 0, UX_RAM_DISK_SIZE);
444     ux_utility_memory_set(ram_disk_memory2, 0, UX_RAM_DISK_SIZE);
445 
446     /* Initialize FileX.  */
447     fx_system_initialize();
448 
449     /* Change the ram drive values. */
450     fx_media_format(&ram_disk_media1, _fx_ram_driver, ram_disk_memory1, ram_disk_buffer1, 512, "RAM DISK1", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
451     fx_media_format(&ram_disk_media2, _fx_ram_driver, ram_disk_memory2, ram_disk_buffer2, 512, "RAM DISK2", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
452 
453     /* The code below is required for installing the device portion of USBX.
454        In this demo, DFU is possible and we have a call back for state change. */
455     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
456                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
457                                        string_framework, STRING_FRAMEWORK_LENGTH,
458                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
459     if(status!=UX_SUCCESS)
460     {
461 
462         printf("ERROR #%d\n", __LINE__);
463         test_control_return(1);
464     }
465 
466     /* Store the number of LUN in this device storage instance.  */
467     global_storage_parameter.ux_slave_class_storage_parameter_number_lun = 1;
468 
469     /* Initialize the storage class parameters for reading/writing to the first Flash Disk.  */
470     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
471     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length    =  512;
472     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type            =  0;
473     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag  =  0x80;
474     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read            =  demo_thread_media_read;
475     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write           =  demo_thread_media_write;
476     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status          =  demo_thread_media_status;
477     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_flush           =  demo_thread_media_flush;
478 
479     /* Initialize the storage class parameters for reading/writing to the second Flash Disk.  */
480     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
481     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length    =  512;
482     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type            =  0;
483     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag  =  0x80;
484     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read            =  demo_thread_media_read;
485     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write           =  demo_thread_media_write;
486     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status          =  demo_thread_media_status;
487     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_flush           =  demo_thread_media_flush;
488 
489     /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
490     status =  ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
491                                                 1, 0, (VOID *)&global_storage_parameter);
492     if(status!=UX_SUCCESS)
493     {
494 
495         printf("ERROR #%d\n", __LINE__);
496         test_control_return(1);
497     }
498 
499     /* Initialize the simulated device controller.  */
500     // status =  _ux_test_dcd_sim_slave_initialize();
501     status =  ux_dcd_sim_slave_initialize();
502 
503     /* Check for error.  */
504     if (status != UX_SUCCESS)
505     {
506 
507         printf("ERROR #%d\n", __LINE__);
508         test_control_return(1);
509     }
510 
511     /* The code below is required for installing the host portion of USBX */
512     status =  ux_host_stack_initialize(ux_test_system_host_change_function);
513     if (status != UX_SUCCESS)
514     {
515 
516         printf("ERROR #%d\n", __LINE__);
517         test_control_return(1);
518     }
519 
520     /* Register storage class.  */
521     status =  ux_host_stack_class_register(_ux_system_host_class_storage_name, ux_host_class_storage_entry);
522     if (status != UX_SUCCESS)
523     {
524 
525         printf("ERROR #%d\n", __LINE__);
526         test_control_return(1);
527     }
528 
529     /* Register all the USB host controllers available in this system */
530     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
531     // status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
532 
533     /* Check for error.  */
534     if (status != UX_SUCCESS)
535     {
536 
537         printf("ERROR #%d\n", __LINE__);
538         test_control_return(1);
539     }
540 
541     /* Create the main host simulation thread.  */
542     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
543             stack_pointer, UX_DEMO_STACK_SIZE,
544             20, 20, 1, TX_AUTO_START);
545 
546     /* Check for error.  */
547     if (status != TX_SUCCESS)
548     {
549 
550         printf("ERROR #%d\n", __LINE__);
551         test_control_return(1);
552     }
553 
554 }
555 
storage_media_status_wait(UX_HOST_CLASS_STORAGE_MEDIA * storage_media,ULONG status,ULONG timeout)556 static UINT storage_media_status_wait(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG status, ULONG timeout)
557 {
558 
559     while(1)
560     {
561 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
562         if (storage_media->ux_host_class_storage_media_status == status)
563             return UX_SUCCESS;
564 #else
565         if ((status == UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED &&
566             storage_media->ux_host_class_storage_media_storage != UX_NULL) ||
567             (status == UX_HOST_CLASS_STORAGE_MEDIA_UNMOUNTED &&
568             storage_media->ux_host_class_storage_media_storage == UX_NULL))
569             return(UX_SUCCESS);
570 #endif
571         if (timeout == 0)
572             break;
573         if (timeout != 0xFFFFFFFF)
574             timeout --;
575         _ux_utility_delay_ms(10);
576     }
577     return UX_ERROR;
578 }
579 
580 
tx_demo_thread_host_simulation_entry(ULONG arg)581 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
582 {
583 
584 UINT                                        status;
585 UX_HOST_CLASS                               *class;
586 UX_HOST_CLASS_STORAGE_MEDIA                 *storage_media;
587 FX_MEDIA                                    *media;
588 FX_MEDIA                                    *media1;
589 UX_ENDPOINT                                 *control_endpoint;
590 UX_TRANSFER                                 *transfer_request;
591 UX_DEVICE                                   *device;
592 UX_CONFIGURATION                            *configuration;
593 UX_INTERFACE                                *interface;
594 ULONG                                       temp;
595 ULONG                                       rfree, cfree;
596 TX_SEMAPHORE                                *semaphore_ptr;
597 
598 
599     /* Find the storage class. */
600     status =  host_storage_instance_get(100);
601     if (status != UX_SUCCESS)
602     {
603         printf("ERROR #%d, code 0x%x\n", __LINE__, status);
604         test_control_return(1);
605     }
606 
607     status = ux_host_stack_device_get(0, &device);
608     if (status != UX_SUCCESS)
609     {
610 
611         printf("ERROR #%d: device_get fail\n", __LINE__);
612         test_control_return(1);
613     }
614     control_endpoint = &device->ux_device_control_endpoint;
615     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
616 
617     /* Wait enough time for media mounting.  */
618     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY);
619 
620     class = storage->ux_host_class_storage_class;
621     storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *)class->ux_host_class_media;
622 
623     /* Confirm media enum done ().  */
624     status = storage_media_status_wait(storage_media, UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED, 100);
625     if (status != UX_SUCCESS)
626     {
627         printf("ERROR #%d, code 0x%x\n", __LINE__, status);
628         test_control_return(1);
629     }
630 
631 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
632     media  = &storage_media[0].ux_host_class_storage_media;
633     media1 = &storage_media[1].ux_host_class_storage_media;
634 #else
635     media  = _ux_host_class_storage_driver_media(0);
636     media1 = _ux_host_class_storage_driver_media(1);
637 #endif
638     // printf("media: %lx, %lx\n", media->fx_media_id, media1->fx_media_id);
639 
640     /* Pause the class driver thread.  */
641     // _ux_utility_thread_suspend(&((UX_HOST_CLASS_STORAGE_EXT*)class->ux_host_class_ext)->ux_host_class_thread);
642 
643     configuration = device -> ux_device_first_configuration;
644     interface = configuration -> ux_configuration_first_interface;
645 
646     rfree = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
647     cfree = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available;
648 
649     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - ux_host_class_storage_semaphore FAIL\n");
650     _ux_utility_semaphore_delete(&storage -> ux_host_class_storage_semaphore);
651     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*2);
652     _ux_utility_semaphore_create(&storage -> ux_host_class_storage_semaphore, "ux_host_class_storage_semaphore", 1);
653 
654     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - ux_host_class_storage_lun_types invalid\n");
655     storage -> ux_host_class_storage_lun_types[0] = 0xEE;
656     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*2);
657 
658     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - ux_host_class_storage_lun_types UX_HOST_CLASS_STORAGE_MEDIA_OPTICAL_DISK\n");
659     storage -> ux_host_class_storage_lun_types[0] = UX_HOST_CLASS_STORAGE_MEDIA_OPTICAL_DISK;
660     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*2);
661 
662     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - ux_host_class_storage_lun_types UX_HOST_CLASS_STORAGE_MEDIA_IOMEGA_CLICK\n");
663     storage -> ux_host_class_storage_lun_types[0] = UX_HOST_CLASS_STORAGE_MEDIA_IOMEGA_CLICK;
664     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*2);
665 
666     media->fx_media_driver_info = UX_NULL;
667     ram_disk_status = UX_ERROR;
668 
669     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - _SENSE_KEY_NOT_READY - media driver info error\n");
670     ram_disk_media_status = 0x003A02;
671     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*4);
672 
673     // printf("media: %lx, %lx\n", media->fx_media_id, media1->fx_media_id);
674 
675     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - _SENSE_KEY_UNIT_ATTENTION - media driver info error\n");
676     ram_disk_status_sent = 0;
677     ram_disk_status_loop = 3;
678     ram_disk_media_status = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
679     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
680 
681     media->fx_media_driver_info = (VOID *)storage;
682 
683     // if (media1->fx_media_id != 0)
684     // {
685     //     printf("ERROR #%d\n", __LINE__);
686     // }
687     // printf("media: %lx, %lx\n", media->fx_media_id, media1->fx_media_id);
688 
689     // printf(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - re-plug\n");
690     // ux_test_hcd_sim_host_disconnect();
691     // ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
692     // _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY*2);
693 
694     // printf("media: %lx, %lx\n", media->fx_media_id, media1->fx_media_id);
695 
696     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - ux_host_class_storage_semaphore FAIL\n");
697     semaphore_ptr = &storage -> ux_host_class_storage_semaphore;
698     // printf("storage:%p, semaphore: %p\n", storage, semaphore_ptr);
699     ux_host_class_storage_semaphore_get_hook[0].semaphore_ptr = semaphore_ptr;
700     ux_test_link_hooks_from_array(ux_host_class_storage_semaphore_get_hook);
701 
702     for(temp = 0; temp < 8; temp ++)
703     {
704 
705 
706         stepinfo("%ld --- ready0\n", temp);
707         /* Attention & ready */
708         semaphore_error_start = 0xFFFFFFFF;
709         semaphore_counter = 0;
710 
711         ram_disk_status_sent = 0;
712         ram_disk_status_loop = 0xFFFFFFFF;
713         ram_disk_status = UX_ERROR;
714         ram_disk_media_status = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
715 
716         _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
717 
718 
719         stepinfo("%ld --- not ready\n", temp);
720         /* Not ready.  */
721         semaphore_error_start = temp;
722         semaphore_counter = 0;
723 
724         ram_disk_status_sent = 0;
725         ram_disk_status_loop = 0xFFFFFFFF;
726         ram_disk_status = UX_ERROR;
727         ram_disk_media_status = 0x003A02;
728 
729         _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
730         if (semaphore_ptr->tx_semaphore_id != 0)
731         {
732             printf("ERROR #%d: semaphore not deleted\n", __LINE__);
733             test_control_return(1);
734         }
735         _ux_utility_semaphore_create(&storage -> ux_host_class_storage_semaphore, "ux_host_class_storage_semaphore", 1);
736 
737 
738         stepinfo("%ld --- ready1\n", temp);
739         /* Attention & ready */
740         semaphore_error_start = 0xFFFFFFFF;
741         semaphore_counter = 0;
742 
743         ram_disk_status_sent = 0;
744         ram_disk_status_loop = 0xFFFFFFFF;
745         ram_disk_status = UX_ERROR;
746         ram_disk_media_status = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
747 
748         _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
749 
750 
751         stepinfo("%ld --- attention!\n", temp);
752         /* Attention! */
753         semaphore_error_start = temp;
754         semaphore_counter = 0;
755 
756         ram_disk_status_sent = 0;
757         ram_disk_status_loop = 1;
758         ram_disk_status = UX_ERROR;
759         ram_disk_media_status = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
760 
761         _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
762         if (semaphore_ptr->tx_semaphore_id != 0)
763         {
764             printf("ERROR #%d: semaphore not deleted\n", __LINE__);
765             test_control_return(1);
766         }
767         _ux_utility_semaphore_create(&storage -> ux_host_class_storage_semaphore, "ux_host_class_storage_semaphore", 1);
768 
769     }
770 
771     ux_test_remove_hooks_from_array(ux_host_class_storage_semaphore_get_hook);
772 
773 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
774     stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_thread_entry - _SENSE_KEY_UNIT_ATTENTION - no host callback\n");
775     _ux_system_host -> ux_system_host_change_function = UX_NULL;
776     ram_disk_status = UX_ERROR;
777     ram_disk_status_sent = 0;
778     ram_disk_status_loop = 2;
779     ram_disk_media_status = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
780     _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME*6);
781     _ux_system_host -> ux_system_host_change_function = ux_test_system_host_change_function;
782 #endif
783 
784     /* Wait a while so the thread goes.  */
785     _ux_utility_delay_ms(10);
786 
787     _ux_utility_thread_delete(&((UX_HOST_CLASS_STORAGE_EXT*)class->ux_host_class_ext)->ux_host_class_thread);
788 
789     /* Finally disconnect the device. */
790     ux_device_stack_disconnect();
791 
792     /* And deinitialize the class.  */
793     status =  ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
794 
795     /* Deinitialize the device side of usbx.  */
796     _ux_device_stack_uninitialize();
797 
798     /* And finally the usbx system resources.  */
799     _ux_system_uninitialize();
800 
801     /* Successful test.  */
802     printf("SUCCESS!\n");
803     test_control_return(0);
804 }
805 
806 
demo_thread_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)807 static UINT    demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
808 {
809 
810 UINT  status = ram_disk_status;
811 
812 
813     (void)storage;
814     (void)media_id;
815 
816     if (media_status)
817         *media_status = ram_disk_media_status;
818 
819     ram_disk_status_sent ++;
820 
821     if (ram_disk_status_loop == 0xFFFFFFFF || ram_disk_status_sent >= ram_disk_status_loop)
822     {
823 
824         /* If there is attention, it must be changed to ready after reported.  */
825         if (ram_disk_media_status == (UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8)))
826         {
827             ram_disk_status = UX_SUCCESS;
828             ram_disk_media_status = 0;
829         }
830     }
831 
832     return status;
833 }
834 
demo_thread_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)835 static UINT    demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
836 {
837     (void)storage;
838 
839     if (lun > 1)
840         return UX_ERROR;
841 
842     ram_disk_read_sent = UX_TRUE;
843 
844     if (ram_disk_read_status != UX_SUCCESS)
845     {
846         if (media_status != UX_NULL)
847             *media_status = ram_disk_read_media_status;
848 
849         return ram_disk_read_status;
850     }
851 
852     ux_utility_memory_copy(data_pointer, &ram_disk_memory[lun][lba * 512], number_blocks * 512);
853 
854     return UX_SUCCESS;
855 }
856 
demo_thread_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)857 static UINT    demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
858 {
859     (void)storage;
860     (void)media_status;
861 
862     if (lun > 1)
863         return UX_ERROR;
864 
865     ux_utility_memory_copy(&ram_disk_memory[lun][lba * 512], data_pointer, number_blocks * 512);
866 
867     return UX_SUCCESS;
868 }
869 
demo_thread_media_flush(VOID * storage,ULONG lun,ULONG number_blocks,ULONG lba,ULONG * media_status)870 static UINT demo_thread_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status)
871 {
872     (void)storage;
873     (void)number_blocks;
874     (void)lba;
875     (void)media_status;
876 
877     if (lun > 1)
878         return UX_ERROR;
879 
880     ram_disk_flush = UX_TRUE;
881     return ram_disk_flush_status;
882 }