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 #define _storage_media_is_mounted() (global_storage_media->ux_host_class_storage_media_status == UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED)
22 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
23 FX_MEDIA    *_ux_host_class_storage_driver_media(INT i);
24 VOID        _ux_host_class_storage_driver_entry(FX_MEDIA *media);
25 VOID        _ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG format_open);
26 VOID        _ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
27 INT         _ux_host_class_storage_media_index(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
28 FX_MEDIA    *_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
29 UCHAR       *_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
30 
31 #endif
32 
33 /* Define constants.  */
34 #define                             UX_DEMO_STACK_SIZE              2048
35 #define                             UX_DEMO_MEMORY_SIZE             (256*1024)
36 #define                             UX_DEMO_BUFFER_SIZE             (UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3)
37 
38 #define                             UX_RAM_DISK_SIZE                (200 * 1024)
39 #define                             UX_RAM_DISK_LAST_LBA            ((UX_RAM_DISK_SIZE / 512) -1)
40 
41 /* Define local/extern function prototypes.  */
42 VOID               _fx_ram_driver(FX_MEDIA *media_ptr);
43 
44 static void        demo_thread_entry(ULONG);
45 static TX_THREAD   tx_demo_thread_host_simulation;
46 static TX_THREAD   tx_demo_thread_device_simulation;
47 static void        tx_demo_thread_host_simulation_entry(ULONG);
48 static void        tx_demo_thread_device_simulation_entry(ULONG);
49 
50 static UINT        ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst);
51 
52 static UINT        demo_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
53 static UINT        demo_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
54 static UINT        demo_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
55 static UINT        demo_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status);
56 
57 static VOID        ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
58 
59 /* Define global data structures.  */
60 
61 static UCHAR                            usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
62 static UCHAR                            buffer[UX_DEMO_BUFFER_SIZE];
63 
64 static ULONG                            error_counter;
65 
66 static UX_HOST_CLASS_STORAGE            *storage;
67 static UX_HOST_CLASS_STORAGE_MEDIA      *storage_media;
68 static FX_MEDIA                         *media;
69 static UX_SLAVE_CLASS_STORAGE_PARAMETER global_storage_parameter;
70 
71 static FX_MEDIA                         ram_disk1;
72 static FX_MEDIA                         ram_disk2;
73 static CHAR                             ram_disk_memory1[UX_RAM_DISK_SIZE];
74 static CHAR                             ram_disk_memory2[UX_RAM_DISK_SIZE];
75 static UCHAR                            buffer1[512];
76 static UCHAR                            buffer2[512];
77 
78 static FX_MEDIA                         *ram_disks[] = {&ram_disk1, &ram_disk2};
79 static UCHAR                            *buffers[] = {buffer1, buffer2};
80 static CHAR                             *ram_disk_memory[] = { ram_disk_memory1, ram_disk_memory2 };
81 
82 static UINT                             ram_disk_status = UX_SUCCESS;
83 static ULONG                            ram_disk_media_status = 0;
84 static CHAR                             ram_disk_status_sent = 0;
85 
86 static ULONG                            ram_disk_rw_fail_mode = 0; /* 1: BulkIN, 2: BulkOUT, 0: DISK. 0x80: once */
87 #define                                 ram_disk_rw_fail_mode_bulk_in()   ((ram_disk_rw_fail_mode & 0x7F) == 1)
88 #define                                 ram_disk_rw_fail_mode_bulk_out()  ((ram_disk_rw_fail_mode & 0x7F) == 2)
89 #define                                 ram_disk_rw_fail_mode_disk()      ((ram_disk_rw_fail_mode & 0x7F) == 0)
90 #define                                 ram_disk_rw_fail_mode_one_shot()  ((ram_disk_rw_fail_mode & 0x80) >  0)
91 static ULONG                            ram_disk_rw_fail_after = 0xFFFFFFFFu;
92 static ULONG                            ram_disk_rw_count = 0;
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 
182 #define STRING_FRAMEWORK_LENGTH 38
183 static UCHAR string_framework[] = {
184 
185     /* Manufacturer string descriptor : Index 1 */
186         0x09, 0x04, 0x01, 0x0c,
187         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
188         0x6f, 0x67, 0x69, 0x63,
189 
190     /* Product string descriptor : Index 2 */
191         0x09, 0x04, 0x02, 0x0a,
192         0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x44, 0x69,
193         0x73, 0x6b,
194 
195     /* Serial Number string descriptor : Index 3 */
196         0x09, 0x04, 0x03, 0x04,
197         0x30, 0x30, 0x30, 0x31
198     };
199 
200 
201     /* Multiple languages are supported on the device, to add
202        a language besides english, the unicode language code must
203        be appended to the language_id_framework array and the length
204        adjusted accordingly. */
205 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
206 static UCHAR language_id_framework[] = {
207 
208     /* English. */
209         0x09, 0x04
210     };
211 
212 
213 /* Setup requests */
214 
215 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
216 
217 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
218 /* function, request to match,
219    port action, port status,
220    request action, request EP, request data, request actual length, request status,
221    status, additional callback,
222    no_return */
223 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
224         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
225         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
226         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
227         UX_TRUE}, /* Invoke callback & continue */
228 {   0   }
229 };
230 
231 
232 static UX_TEST_HCD_SIM_ACTION fail_on_bulkin[] = {
233 /* function, request to match,
234    port action, port status,
235    request action, request EP, request data, request actual length, request status,
236    status, additional callback,
237    no_return */
238 {   UX_DCD_TRANSFER_REQUEST, UX_NULL,
239         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
240         UX_TEST_MATCH_EP, 0x81, UX_NULL, 0, UX_ERROR,
241         UX_STATE_ERROR, UX_NULL,
242         UX_FALSE}, /* Invoke callback & no continue */
243 {   0   }
244 };
245 
246 
247 static UX_TEST_HCD_SIM_ACTION fail_on_bulkout[] = {
248 /* function, request to match,
249    port action, port status,
250    request action, request EP, request data, request actual length, request status,
251    status, additional callback,
252    no_return */
253 {   UX_DCD_TRANSFER_REQUEST, UX_NULL,
254         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
255         UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
256         UX_STATE_ERROR, UX_NULL,
257         UX_FALSE}, /* Invoke callback & no continue */
258 {   0   }
259 };
260 
261 
262 /* Define the ISR dispatch.  */
263 
264 extern VOID    (*test_isr_dispatch)(void);
265 
266 
267 /* Prototype for test control return.  */
268 
269 void  test_control_return(UINT status);
270 
271 
272 /* Define the ISR dispatch routine.  */
273 
test_isr(void)274 static void    test_isr(void)
275 {
276 
277     /* For further expansion of interrupt-level testing.  */
278 }
279 
280 
error_callback(UINT system_level,UINT system_context,UINT error_code)281 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
282 {
283 
284     error_callback_counter ++;
285 
286     if (!error_callback_ignore)
287     {
288         {
289             /* Failed test.  */
290             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
291             test_control_return(1);
292         }
293     }
294 }
295 
host_storage_instance_get(ULONG timeout_x10ms)296 static UINT host_storage_instance_get(ULONG timeout_x10ms)
297 {
298 
299 UINT                status;
300 UX_HOST_CLASS       *class;
301 
302 
303 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
304     storage_media = UX_NULL;
305     media = UX_NULL;
306 #endif
307 
308     /* Find the main storage container */
309     status =  ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
310     if (status != UX_SUCCESS)
311         return(status);
312 
313     /* Get storage instance, wait it to be live and media attached.  */
314     do
315     {
316         if (timeout_x10ms)
317         {
318             tx_thread_sleep(UX_MS_TO_TICK_NON_ZERO(10));
319             if (timeout_x10ms != 0xFFFFFFFF)
320                 timeout_x10ms --;
321         }
322 
323         status =  ux_host_stack_class_instance_get(class, 0, (void **) &storage);
324         if (status == UX_SUCCESS)
325         {
326 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
327             storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *) class -> ux_host_class_media;
328             media = &storage_media -> ux_host_class_storage_media;
329 #endif
330             if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_LIVE &&
331                 class -> ux_host_class_ext != UX_NULL &&
332                 class -> ux_host_class_media != UX_NULL)
333             {
334                 return(UX_SUCCESS);
335             }
336         }
337 
338     } while(timeout_x10ms > 0);
339 
340     return(UX_ERROR);
341 }
342 
sleep_break_on_error(VOID)343 static UINT  sleep_break_on_error(VOID)
344 {
345 
346     if (error_callback_counter >= 3)
347         return error_callback_counter;
348 
349     return UX_SUCCESS;
350 }
351 
sleep_break_on_connect(VOID)352 static UINT sleep_break_on_connect(VOID)
353 {
354     if (host_storage_instance_get(0) == UX_SUCCESS)
355         return(1);
356     if (error_callback_counter >= 3)
357         return(1);
358     return(0);
359 }
360 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)361 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
362 {
363 
364     set_cfg_counter ++;
365 
366     rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
367 
368     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
369     rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
370     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
371 }
372 
373 
374 /* Define what the initial system looks like.  */
375 
376 #ifdef CTEST
test_application_define(void * first_unused_memory)377 void test_application_define(void *first_unused_memory)
378 #else
379 void    usbx_device_storage_basic_standalone_test_application_define(void *first_unused_memory)
380 #endif
381 {
382 
383 UINT                            status;
384 CHAR *                          stack_pointer;
385 CHAR *                          memory_pointer;
386 ULONG                           mem_free;
387 ULONG                           test_n;
388 
389 
390     /* Inform user.  */
391     printf("Running STANDALONE Device Storage Basic Test........................ ");
392 #ifndef UX_DEVICE_STANDALONE
393     printf("Skip\n");
394     test_control_return(0);
395 #endif
396 
397     stepinfo("\n");
398 
399     /* Initialize FileX.  */
400     fx_system_initialize();
401 
402     /* Reset ram disks memory.  */
403     ux_utility_memory_set(ram_disk_memory1, 0, UX_RAM_DISK_SIZE);
404     ux_utility_memory_set(ram_disk_memory2, 0, UX_RAM_DISK_SIZE);
405 
406     /* Format the ram drive. */
407     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);
408     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);
409     if (status != FX_SUCCESS)
410     {
411 
412         /* Storage basic test error.  */
413         printf("ERROR #8\n");
414         test_control_return(1);
415     }
416 
417     /* Open the ram_disk.  */
418     status =   fx_media_open(&ram_disk1, "RAM DISK1", _fx_ram_driver, ram_disk_memory1, buffer1, 512);
419     status |=  fx_media_open(&ram_disk2, "RAM DISK2", _fx_ram_driver, ram_disk_memory2, buffer2, 512);
420     if (status != FX_SUCCESS)
421     {
422 
423         /* Storage basic test error.  */
424         printf("ERROR %d\n", __LINE__);
425         test_control_return(1);
426     }
427 
428     /* Reset testing counts. */
429     ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
430     ux_test_utility_sim_mem_alloc_count_reset();
431     ux_test_utility_sim_mutex_create_count_reset();
432     ux_test_utility_sim_sem_create_count_reset();
433     ux_test_utility_sim_sem_get_count_reset();
434     /* Reset error generations */
435     ux_test_utility_sim_sem_error_generation_stop();
436     ux_test_utility_sim_mutex_error_generation_stop();
437     ux_test_utility_sim_sem_get_error_generation_stop();
438 
439     /* Initialize the free memory pointer */
440     stack_pointer = (CHAR *) usbx_memory;
441     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
442 
443     /* Initialize USBX. Memory */
444     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
445 
446     /* Check for error.  */
447     if (status != UX_SUCCESS)
448     {
449 
450         printf("ERROR #%d\n", __LINE__);
451         test_control_return(1);
452     }
453 
454     /* Register the error callback. */
455     _ux_utility_error_callback_register(error_callback);
456 
457     /* The code below is required for installing the device portion of USBX.
458        In this demo, DFU is possible and we have a call back for state change. */
459     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
460                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
461                                        string_framework, STRING_FRAMEWORK_LENGTH,
462                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
463     if(status!=UX_SUCCESS)
464     {
465 
466         printf("ERROR #%d\n", __LINE__);
467         test_control_return(1);
468     }
469 
470     /* Store the number of LUN in this device storage instance.  */
471     global_storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;
472 
473     /* Initialize the storage class parameters for reading/writing to the first Flash Disk.  */
474     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
475     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length    =  512;
476     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type            =  0;
477     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag  =  0x80;
478     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read            =  demo_media_read;
479     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write           =  demo_media_write;
480     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status          =  demo_media_status;
481     global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_flush           =  demo_media_flush;
482 
483     /* Initialize the storage class parameters for reading/writing to the second Flash Disk.  */
484     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba        =  UX_RAM_DISK_LAST_LBA;
485     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length    =  512;
486     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type            =  0;
487     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag  =  0x80;
488     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read            =  demo_media_read;
489     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write           =  demo_media_write;
490     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status          =  demo_media_status;
491     global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_flush           =  demo_media_flush;
492 
493     /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
494     status =  ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
495                                                 1, 0, (VOID *)&global_storage_parameter);
496     if(status!=UX_SUCCESS)
497     {
498 
499         printf("ERROR #%d\n", __LINE__);
500         test_control_return(1);
501     }
502 
503     /* Initialize the simulated device controller.  */
504     // status =  _ux_dcd_sim_slave_initialize();
505     status =  _ux_test_dcd_sim_slave_initialize();
506 
507     /* Check for error.  */
508     if (status != UX_SUCCESS)
509     {
510 
511         printf("ERROR #%d\n", __LINE__);
512         test_control_return(1);
513     }
514 
515     /* The code below is required for installing the host portion of USBX */
516     status =  ux_host_stack_initialize(ux_test_system_host_change_function);
517     if (status != UX_SUCCESS)
518     {
519 
520         printf("ERROR #%d\n", __LINE__);
521         test_control_return(1);
522     }
523 
524     /* Register storage class.  */
525     status =  ux_host_stack_class_register(_ux_system_host_class_storage_name, ux_host_class_storage_entry);
526     if (status != UX_SUCCESS)
527     {
528 
529         printf("ERROR #%d\n", __LINE__);
530         test_control_return(1);
531     }
532 
533     /* Register all the USB host controllers available in this system */
534     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
535 
536     /* Check for error.  */
537     if (status != UX_SUCCESS)
538     {
539 
540         printf("ERROR #%d\n", __LINE__);
541         test_control_return(1);
542     }
543 
544     /* Create the main device simulation thread.  */
545     status =  tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
546             stack_pointer, UX_DEMO_STACK_SIZE,
547             21, 21, 1, TX_AUTO_START);
548 
549     /* Check for error.  */
550     if (status != TX_SUCCESS)
551     {
552 
553         printf("ERROR #%d\n", __LINE__);
554         test_control_return(1);
555     }
556     stack_pointer += UX_DEMO_STACK_SIZE;
557 
558     /* Create the main host simulation thread.  */
559     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
560             stack_pointer, UX_DEMO_STACK_SIZE,
561             20, 20, 1, TX_AUTO_START);
562 
563     /* Check for error.  */
564     if (status != TX_SUCCESS)
565     {
566 
567         printf("ERROR #%d\n", __LINE__);
568         test_control_return(1);
569     }
570 
571 }
572 
tx_demo_thread_device_simulation_entry(ULONG arg)573 static void tx_demo_thread_device_simulation_entry(ULONG arg)
574 {
575     while(1)
576     {
577 
578         /* Run device tasks.  */
579         ux_system_tasks_run();
580 
581         /* Relinquish to other thread.  */
582         tx_thread_relinquish();
583     }
584 }
585 
_test_dw_minus(ULONG d0,ULONG d1)586 static ULONG _test_dw_minus(ULONG d0, ULONG d1)
587 {
588     if (d0 >= d1)
589         return(d0 - d1);
590     return(d0 + (0xFFFFFFFF - d1));
591 }
592 
_media_driver_read(FX_MEDIA * media,VOID (* _media_driver)(FX_MEDIA *),UCHAR * buffer,ULONG lba,ULONG n_lb)593 static UINT  _media_driver_read(FX_MEDIA *media,
594     VOID (*_media_driver)(FX_MEDIA *),
595     UCHAR *buffer, ULONG lba, ULONG n_lb)
596 {
597 UINT status;
598 
599     if (lba == 0)
600     {
601         media->fx_media_driver_logical_sector = lba;
602         media->fx_media_driver_sectors = n_lb;
603         media->fx_media_driver_request = FX_DRIVER_BOOT_READ;
604         media->fx_media_driver_buffer = buffer;
605         _media_driver(media);
606         *(buffer) =  0xeb;
607         *(buffer+1) =  0x3c;
608         *(buffer+2) =  0x90;
609         *(buffer+21) =  0xF8;
610 
611         *(buffer+24) =  0x01;
612         *(buffer+26) =  0x10;
613         *(buffer+28) =  0x01;
614 
615         *(buffer+510) =  0x55;
616         *(buffer+511) =  0xaa;
617         ux_utility_memory_copy(buffer+0x36,"FAT12",5);
618 
619         if (media->fx_media_driver_status != FX_SUCCESS)
620         {
621             printf("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
622             return(UX_ERROR);
623         }
624 
625         lba++;
626         n_lb --;
627         buffer += 512;
628     }
629     media->fx_media_driver_logical_sector = lba;
630     media->fx_media_driver_sectors = n_lb;
631     media->fx_media_driver_request = FX_DRIVER_READ;
632     media->fx_media_driver_buffer = buffer;
633     _media_driver(media);
634     if (media->fx_media_driver_status != FX_SUCCESS)
635     {
636         stepinfo("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
637         return(UX_ERROR);
638     }
639     return(UX_SUCCESS);
640 }
641 
_media_driver_write(FX_MEDIA * media,VOID (* _media_driver)(FX_MEDIA *),UCHAR * buffer,ULONG lba,ULONG n_lb)642 static UINT  _media_driver_write(FX_MEDIA *media,
643     VOID (*_media_driver)(FX_MEDIA *),
644     UCHAR *buffer, ULONG lba, ULONG n_lb)
645 {
646 UINT status;
647 
648     if (lba == 0)
649     {
650         media -> fx_media_driver_logical_sector = 0;
651         media -> fx_media_driver_sectors = 1;
652         media -> fx_media_driver_request = FX_DRIVER_BOOT_WRITE;
653         media -> fx_media_driver_buffer = buffer;
654         _media_driver(media);
655 
656         if (media->fx_media_driver_status != FX_SUCCESS)
657         {
658             printf("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
659             return(UX_ERROR);
660         }
661 
662         lba ++;
663         n_lb --;
664         buffer += 512;
665     }
666     if (n_lb)
667     {
668         media -> fx_media_driver_logical_sector = lba;
669         media -> fx_media_driver_sectors = n_lb;
670         media -> fx_media_driver_request = FX_DRIVER_WRITE;
671         media -> fx_media_driver_buffer = buffer;
672         _media_driver(media);
673 
674         if (media->fx_media_driver_status != FX_SUCCESS)
675         {
676             printf("%s:%d: FX error 0x%x\n", __FILE__, __LINE__, media->fx_media_driver_status);
677             return(UX_ERROR);
678         }
679     }
680     return(UX_SUCCESS);
681 }
682 
_test_host_class_storage_inquiry(UX_HOST_CLASS_STORAGE * storage,UCHAR flags,ULONG data_length,ULONG cb_length,UCHAR page_code,UCHAR * response,ULONG response_length)683 static UINT _test_host_class_storage_inquiry(UX_HOST_CLASS_STORAGE *storage,
684     UCHAR flags, ULONG data_length, ULONG cb_length,
685     UCHAR page_code, UCHAR *response, ULONG response_length)
686 {
687 UINT            status;
688 UCHAR           *cbw;
689 UINT            command_length;
690 
691     /* Use a pointer for the cbw, easier to manipulate.  */
692     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
693 
694     /* Initialize the CBW for this command.  */
695     _ux_host_class_storage_cbw_initialize(storage, flags, data_length, cb_length);
696 
697     /* Prepare the INQUIRY command block.  */
698     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_HOST_CLASS_STORAGE_INQUIRY_OPERATION) = UX_HOST_CLASS_STORAGE_SCSI_INQUIRY;
699 
700     /* Store the page code.  */
701     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_HOST_CLASS_STORAGE_INQUIRY_PAGE_CODE) = page_code;
702 
703     /* Store the length of the Inquiry Response.  */
704     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_HOST_CLASS_STORAGE_INQUIRY_ALLOCATION_LENGTH) =  (UCHAR)response_length;
705 
706     /* Send the command to transport layer.  */
707     status =  _ux_host_class_storage_transport(storage, response);
708 
709     /* Return completion status.  */
710     return(status);
711 }
test_host_class_storage_inquiry(UX_HOST_CLASS_STORAGE * storage,UCHAR page_code,UCHAR * response,ULONG response_length)712 static UINT test_host_class_storage_inquiry(UX_HOST_CLASS_STORAGE *storage, UCHAR page_code, UCHAR *response, ULONG response_length)
713 {
714     _test_host_class_storage_inquiry(storage,
715         UX_HOST_CLASS_STORAGE_DATA_IN,
716         UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH,
717         UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC,
718         page_code, response, response_length);
719 }
720 
_test_send_cbw_EX(int __line__,ULONG length)721 static UINT _test_send_cbw_EX(int __line__, ULONG length)
722 {
723 
724 UX_TRANSFER     *transfer_request;
725 UINT            status;
726 UCHAR           *cbw;
727 
728     stepinfo(">>>>> %d.%d: CBW\n", __LINE__, __line__);
729     transfer_request =  &storage -> ux_host_class_storage_bulk_out_endpoint -> ux_endpoint_transfer_request;
730     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
731 
732     transfer_request -> ux_transfer_request_data_pointer =      cbw;
733     transfer_request -> ux_transfer_request_requested_length =  length;
734     status =  ux_host_stack_transfer_request(transfer_request);
735 
736     /* There is error, return the error code.  */
737     if (status != UX_SUCCESS)
738         return(status);
739 
740     /* Wait transfer done.  */
741     status =  _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT));
742 
743     /* No error, it's done.  */
744     if (status == UX_SUCCESS)
745         return(transfer_request->ux_transfer_request_completion_code);
746 
747     /* All transfers pending need to abort. There may have been a partial transfer.  */
748     ux_host_stack_transfer_request_abort(transfer_request);
749 
750     /* Set the completion code.  */
751     transfer_request -> ux_transfer_request_completion_code =  UX_TRANSFER_TIMEOUT;
752 
753     /* There was an error, return to the caller.  */
754     return(UX_TRANSFER_TIMEOUT);
755 }
_test_send_cbw(int __line__)756 static UINT _test_send_cbw(int __line__)
757 {
758     _test_send_cbw_EX(__line__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
759 }
760 
_test_transfer_data(int __line__,UCHAR * data,ULONG size,UCHAR do_read)761 static UINT _test_transfer_data(int __line__, UCHAR *data, ULONG size, UCHAR do_read)
762 {
763 
764 UX_TRANSFER     *transfer_request;
765 UINT            status;
766 
767 
768     stepinfo(">>>>> %d.%d: DATA\n", __LINE__, __line__);
769     transfer_request =  do_read ?
770             &storage -> ux_host_class_storage_bulk_in_endpoint -> ux_endpoint_transfer_request :
771             &storage -> ux_host_class_storage_bulk_out_endpoint -> ux_endpoint_transfer_request;
772     transfer_request -> ux_transfer_request_data_pointer = data;
773     transfer_request -> ux_transfer_request_requested_length =  size;
774 
775     status =  ux_host_stack_transfer_request(transfer_request);
776 
777     /* There is error, return the error code.  */
778     if (status != UX_SUCCESS)
779         return(status);
780 
781     /* Wait transfer done.  */
782     status =  _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT));
783 
784     /* No error, it's done.  */
785     if (status == UX_SUCCESS)
786         return(transfer_request->ux_transfer_request_completion_code);
787 
788     /* All transfers pending need to abort. There may have been a partial transfer.  */
789     ux_host_stack_transfer_request_abort(transfer_request);
790 
791     /* Set the completion code.  */
792     transfer_request -> ux_transfer_request_completion_code =  UX_TRANSFER_TIMEOUT;
793 
794     /* There was an error, return to the caller.  */
795     return(UX_TRANSFER_TIMEOUT);
796 }
797 
_test_wait_csw_EX(int __line__)798 static UINT _test_wait_csw_EX(int __line__)
799 {
800 
801 UX_TRANSFER     *transfer_request;
802 UINT            status;
803 
804 
805     stepinfo(">>>>> %d.%d: CSW_Ex\n", __LINE__, __line__);
806 
807     /* Get the pointer to the transfer request, on the bulk in endpoint.  */
808     transfer_request =  &storage -> ux_host_class_storage_bulk_in_endpoint -> ux_endpoint_transfer_request;
809 
810     /* Fill in the transfer_request parameters.  */
811     transfer_request -> ux_transfer_request_data_pointer =      (UCHAR *) &storage -> ux_host_class_storage_csw;
812     transfer_request -> ux_transfer_request_requested_length =  UX_HOST_CLASS_STORAGE_CSW_LENGTH;
813 
814     /* Get the CSW on the bulk in endpoint.  */
815     status =  ux_host_stack_transfer_request(transfer_request);
816     if (status != UX_SUCCESS)
817         return(status);
818 
819     /* Wait for the completion of the transfer request.  */
820     status =  _ux_host_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT));
821 
822     /* If OK, we are done.  */
823     if (status == UX_SUCCESS)
824         return(transfer_request->ux_transfer_request_completion_code);
825 
826     /* All transfers pending need to abort. There may have been a partial transfer.  */
827     ux_host_stack_transfer_request_abort(transfer_request);
828 
829     /* Set the completion code.  */
830     transfer_request -> ux_transfer_request_completion_code =  UX_TRANSFER_TIMEOUT;
831 
832     /* There was an error, return to the caller.  */
833     return(UX_TRANSFER_TIMEOUT);
834 }
835 
_test_clear_stall(UCHAR clear_read_stall)836 static VOID _test_clear_stall(UCHAR clear_read_stall)
837 {
838 
839 UX_ENDPOINT     *endpoint;
840 
841 
842     endpoint =  clear_read_stall ?
843             storage -> ux_host_class_storage_bulk_in_endpoint :
844             storage -> ux_host_class_storage_bulk_out_endpoint;
845     _ux_host_stack_endpoint_reset(endpoint);
846 }
847 
_test_wait_csw(int __line__)848 static UINT _test_wait_csw(int __line__)
849 {
850 UINT   status;
851 
852     stepinfo(">>>>> %d.%d: CSW\n", __LINE__, __line__);
853     status = _test_wait_csw_EX(__LINE__);
854     if (status == UX_TRANSFER_STALLED)
855     {
856         _test_clear_stall(UX_TRUE);
857         status = _test_wait_csw_EX(__LINE__);
858     }
859     return(status);
860 }
861 
_test_request_sense(void)862 static UINT _test_request_sense(void)
863 {
864 
865 UINT            status;
866 UX_TRANSFER     *transfer_request;
867 UCHAR           *cbw;
868 UCHAR           *request_sense_response;
869 ULONG           sense_code;
870 UINT            command_length = UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC;
871 
872 
873     transfer_request =  &storage -> ux_host_class_storage_bulk_out_endpoint -> ux_endpoint_transfer_request;
874     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
875 
876     _ux_utility_memory_copy(storage -> ux_host_class_storage_saved_cbw, storage -> ux_host_class_storage_cbw, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
877     _ux_host_class_storage_cbw_initialize(storage, UX_HOST_CLASS_STORAGE_DATA_IN, UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH, command_length);
878     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_HOST_CLASS_STORAGE_REQUEST_SENSE_OPERATION) =  UX_HOST_CLASS_STORAGE_SCSI_REQUEST_SENSE;
879     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_HOST_CLASS_STORAGE_REQUEST_SENSE_ALLOCATION_LENGTH) =  UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH;
880     request_sense_response =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH);
881     if (request_sense_response == UX_NULL)
882         return(UX_MEMORY_INSUFFICIENT);
883     status = _test_send_cbw(__LINE__);
884     if (status == UX_SUCCESS)
885     {
886         status = _test_transfer_data(__LINE__, request_sense_response, UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH, UX_TRUE);
887         if (status == UX_SUCCESS)
888         {
889             status = _test_wait_csw(__LINE__);
890             if (status == UX_SUCCESS)
891             {
892 
893                 sense_code =  (((ULONG) *(request_sense_response + UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_SENSE_KEY)) & 0x0f) << 16;
894                 sense_code |=  ((ULONG) *(request_sense_response + UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE)) << 8;
895                 sense_code |=  (ULONG)  *(request_sense_response + UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE_QUALIFIER);
896 
897                 storage -> ux_host_class_storage_sense_code =  sense_code;
898             }
899         }
900     }
901     _ux_utility_memory_free(request_sense_response);
902     _ux_utility_memory_copy(storage -> ux_host_class_storage_cbw, storage -> ux_host_class_storage_saved_cbw, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
903     return(status);
904 }
905 
906 typedef struct cbw_read_struct
907 {
908     UCHAR flags_pos;
909     UCHAR lba_pos;
910     UCHAR lba_size;
911     UCHAR len_pos;
912     UCHAR len_size;
913 } cbw_read_struct_t;
914 static cbw_read_struct_t cbw_READ_info[] =
915 {
916     { 1,  2, 2,  4, 1},
917     { 1,  2, 4,  7, 2},
918     { 1,  2, 4,  6, 4},
919     { 1,  2, 8, 10, 4},
920     {10, 12, 8, 28, 4}
921 };
_read_op(UCHAR op_code)922 static UCHAR _read_op(UCHAR op_code)
923 {
924     switch(op_code)
925     {
926     case 0x28: return 1;
927     case 0xA8: return 2;
928     case 0x88: return 3;
929     case 0x7F: return 4;
930     case 0x08: return 0;
931     default:   return 0xFF;
932     }
933 }
_test_init_cbw_READ_EX(UCHAR flags,ULONG data_length,UCHAR op6_10_12_16_32,ULONG lba,ULONG len)934 static void  _test_init_cbw_READ_EX(
935     UCHAR flags, ULONG data_length,
936     UCHAR op6_10_12_16_32, ULONG lba, ULONG len)
937 {
938 UCHAR               *cbw;
939 UINT                command_length;
940 UCHAR               op = _read_op(op6_10_12_16_32);
941 UINT                i;
942 
943 
944     if (op >= 5)
945         return;
946 
947     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
948     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
949     _ux_host_class_storage_cbw_initialize(storage, flags, data_length, command_length);
950     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0)                                = op6_10_12_16_32;
951     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + cbw_READ_info[op].flags_pos)      = 0;
952     for (i = cbw_READ_info[op].lba_pos + cbw_READ_info[op].lba_size - 1; i >= cbw_READ_info[op].lba_pos; i --)
953     {
954         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + i) = (UCHAR)lba;
955         lba >>= 8;
956     }
957     for (i = cbw_READ_info[op].len_pos + cbw_READ_info[op].len_size - 1; i >= cbw_READ_info[op].len_size; i --)
958     {
959         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + i) = (UCHAR)len;
960         len >>= 8;
961     }
962 }
_test_init_cbw_READ(UCHAR op6_10_12_16_32,ULONG lba,ULONG len)963 static void  _test_init_cbw_READ(UCHAR op6_10_12_16_32, ULONG lba, ULONG len)
964 {
965     _test_init_cbw_READ_EX(0x80, len * 512, op6_10_12_16_32, lba, len);
966 }
967 
968 typedef struct cbw_write_struct
969 {
970     UCHAR flags_pos;
971     UCHAR lba_pos;
972     UCHAR lba_size;
973     UCHAR len_pos;
974     UCHAR len_size;
975 } cbw_write_struct_t;
976 static cbw_write_struct_t cbw_WRITE_info[] =
977 {
978     { 1,  2, 2,  4, 1},
979     { 1,  2, 4,  7, 2},
980     { 1,  2, 4,  6, 4},
981     { 1,  2, 8, 10, 4},
982     {10, 12, 8, 28, 4}
983 };
_write_op(UCHAR op_code)984 static UCHAR _write_op(UCHAR op_code)
985 {
986     switch(op_code)
987     {
988     case 0x2A: return 1;
989     case 0xAA: return 2;
990     case 0x8A: return 3;
991     case 0x7F: return 4;
992     case 0x0A: return 0;
993     default:   return 0xFF;
994     }
995 }
_test_init_cbw_WRITE_EX(UCHAR flags,ULONG data_length,UCHAR op6_10_12_16_32,ULONG lba,ULONG len)996 static void  _test_init_cbw_WRITE_EX(UCHAR flags, ULONG data_length,
997     UCHAR op6_10_12_16_32, ULONG lba, ULONG len)
998 {
999 
1000 UCHAR               *cbw;
1001 UINT                command_length;
1002 UCHAR               op = _write_op(op6_10_12_16_32);
1003 UINT                i;
1004 
1005 
1006     if (op >= 5)
1007         return;
1008 
1009     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1010     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1011     _ux_host_class_storage_cbw_initialize(storage, flags, data_length, command_length);
1012     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0)                                = op6_10_12_16_32;
1013     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + cbw_WRITE_info[op].flags_pos)      = 0;
1014     for (i = cbw_WRITE_info[op].lba_pos + cbw_WRITE_info[op].lba_size - 1; i >= cbw_WRITE_info[op].lba_pos; i --)
1015     {
1016         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + i) = (UCHAR)lba;
1017         lba >>= 8;
1018     }
1019     for (i = cbw_WRITE_info[op].len_pos + cbw_WRITE_info[op].len_size - 1; i >= cbw_WRITE_info[op].len_size; i --)
1020     {
1021         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + i) = (UCHAR)len;
1022         len >>= 8;
1023     }
1024 }
_test_init_cbw_WRITE(UCHAR op6_10_12_16_32,ULONG lba,ULONG len)1025 static void  _test_init_cbw_WRITE(UCHAR op6_10_12_16_32, ULONG lba, ULONG len)
1026 {
1027     _test_init_cbw_WRITE_EX(0x00, len * 512, op6_10_12_16_32, lba, len);
1028 }
1029 
_test_init_cbw_REQUEST_SENSE(ULONG data_length)1030 static void  _test_init_cbw_REQUEST_SENSE(ULONG data_length)
1031 {
1032 
1033 UCHAR           *cbw;
1034 UINT            command_length;
1035 
1036 
1037     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1038     command_length =  UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC;
1039     _ux_host_class_storage_cbw_initialize(storage, 0x80, data_length, command_length);
1040     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_REQUEST_SENSE;
1041 }
1042 
_test_init_cbw_TEST_READY(ULONG data_length)1043 static void  _test_init_cbw_TEST_READY(ULONG data_length)
1044 {
1045 
1046 UCHAR           *cbw;
1047 UINT            command_length;
1048 
1049 
1050     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1051     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1052     _ux_host_class_storage_cbw_initialize(storage, 0x00, data_length, command_length);
1053     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_TEST_READY;
1054 }
1055 
_test_init_cbw_FORMAT_UNIT(void)1056 static void  _test_init_cbw_FORMAT_UNIT(void)
1057 {
1058 
1059 UCHAR           *cbw;
1060 UINT            command_length;
1061 
1062 
1063     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1064     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1065     _ux_host_class_storage_cbw_initialize(storage, 0, 0, command_length);
1066     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_FORMAT;
1067 }
1068 
_test_init_cbw_START_STOP(void)1069 static void  _test_init_cbw_START_STOP(void)
1070 {
1071 
1072 UCHAR           *cbw;
1073 UINT            command_length;
1074 
1075 
1076     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1077     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1078     _ux_host_class_storage_cbw_initialize(storage, 0, 0, command_length);
1079     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_START_STOP;
1080 }
1081 
_test_init_cbw_VERIFY(void)1082 static void  _test_init_cbw_VERIFY(void)
1083 {
1084 
1085 UCHAR           *cbw;
1086 UINT            command_length;
1087 
1088 
1089     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1090     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1091     _ux_host_class_storage_cbw_initialize(storage, 0, 0, command_length);
1092     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_VERIFY;
1093 }
1094 
_test_init_cbw_MODE_SELECT(ULONG data_length)1095 static void  _test_init_cbw_MODE_SELECT(ULONG data_length)
1096 {
1097 
1098 UCHAR           *cbw;
1099 UINT            command_length;
1100 
1101 
1102     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1103     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1104     _ux_host_class_storage_cbw_initialize(storage, 0, data_length, command_length);
1105     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SELECT;
1106 }
1107 
_test_init_cbw_MODE_SENSE(UCHAR op6,UCHAR page_code,ULONG buffer_length)1108 static void  _test_init_cbw_MODE_SENSE(UCHAR op6, UCHAR page_code, ULONG buffer_length)
1109 {
1110 
1111 UCHAR           *cbw;
1112 UINT            command_length;
1113 
1114 
1115     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1116     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1117     _ux_host_class_storage_cbw_initialize(storage, 0x80, buffer_length, command_length);
1118     if (op6)
1119     {
1120         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT;
1121         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_6) =  (UCHAR)buffer_length;
1122     }
1123     else
1124     {
1125         *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE;
1126         _ux_utility_short_put_big_endian(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_10, (USHORT)buffer_length);
1127     }
1128     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PC_PAGE_CODE) = page_code;
1129 }
1130 
_test_init_cbw_SYNCHRONIZE_CACHE(UCHAR op16,UCHAR immed,ULONG lba,ULONG nb_blocks)1131 static void  _test_init_cbw_SYNCHRONIZE_CACHE(UCHAR op16, UCHAR immed, ULONG lba, ULONG nb_blocks)
1132 {
1133 
1134 UCHAR           *cbw;
1135 UINT            command_length;
1136 
1137 
1138     (void)op16;
1139 
1140     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1141     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1142     _ux_host_class_storage_cbw_initialize(storage, 0, 0, command_length);
1143     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) = UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE;
1144     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS) = immed ? UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS_IMMED : 0;
1145     _ux_utility_long_put_big_endian(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_LBA, lba);
1146     _ux_utility_short_put_big_endian(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_NUMBER_OF_BLOCKS, (USHORT)nb_blocks);
1147 }
1148 
_test_init_cbw_PREVENT_ALLOW_MEDIA_REMOVAL(void)1149 static void  _test_init_cbw_PREVENT_ALLOW_MEDIA_REMOVAL(void)
1150 {
1151 
1152 UCHAR           *cbw;
1153 UINT            command_length;
1154 
1155 
1156     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1157     command_length =  UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC;
1158     _ux_host_class_storage_cbw_initialize(storage, 0, 0, command_length);
1159     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) =  UX_SLAVE_CLASS_STORAGE_SCSI_PREVENT_ALLOW_MEDIA_REMOVAL;
1160 }
1161 
1162 
_msc_cbw_fail_cases_test(const char * __file__,int __line__)1163 static void _msc_cbw_fail_cases_test(const char* __file__, int __line__)
1164 {
1165 UINT            status;
1166 UCHAR           *cbw;
1167 
1168     cbw =  (UCHAR *) storage -> ux_host_class_storage_cbw;
1169 
1170     stepinfo("\n%s:%d:MSC CBW fail tests\n", __file__, __line__);
1171 
1172     stepinfo(">>>>>>>>>>>>>>>> Test VERIFY CBW length error\n");
1173     _test_init_cbw_VERIFY();
1174     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH - 1);
1175     if (status != UX_SUCCESS)
1176     {
1177         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1178         test_control_return(1);
1179     }
1180     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1181     if (status != UX_TRANSFER_STALLED)
1182     {
1183         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1184         test_control_return(1);
1185     }
1186     status = _test_transfer_data(__LINE__, buffer, 128, UX_FALSE);
1187     if (status != UX_TRANSFER_STALLED)
1188     {
1189         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1190         test_control_return(1);
1191     }
1192     _ux_host_class_storage_device_reset(storage);
1193 
1194     stepinfo(">>>>>>>>>>>>>>>> Test VERIFY CBW LUN error\n");
1195     _test_init_cbw_VERIFY();
1196     *(cbw + UX_HOST_CLASS_STORAGE_CBW_LUN + 0) = 0xFF;
1197     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
1198     if (status != UX_SUCCESS)
1199     {
1200         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1201         test_control_return(1);
1202     }
1203     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1204     if (status != UX_TRANSFER_STALLED)
1205     {
1206         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1207         test_control_return(1);
1208     }
1209     status = _test_transfer_data(__LINE__, buffer, 128, UX_FALSE);
1210     if (status != UX_TRANSFER_STALLED)
1211     {
1212         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1213         test_control_return(1);
1214     }
1215     _ux_host_class_storage_device_reset(storage);
1216 
1217     stepinfo(">>>>>>>>>>>>>>>> Test VERIFY CBW Signature error\n");
1218     _test_init_cbw_VERIFY();
1219     *(cbw + UX_HOST_CLASS_STORAGE_CBW_SIGNATURE + 0) = 0xFF;
1220     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
1221     if (status != UX_SUCCESS)
1222     {
1223         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1224         test_control_return(1);
1225     }
1226     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1227     if (status != UX_TRANSFER_STALLED)
1228     {
1229         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1230         test_control_return(1);
1231     }
1232     status = _test_transfer_data(__LINE__, buffer, 128, UX_FALSE);
1233     if (status != UX_TRANSFER_STALLED)
1234     {
1235         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1236         test_control_return(1);
1237     }
1238     _ux_host_class_storage_device_reset(storage);
1239 
1240     stepinfo(">>>>>>>>>>>>>>>> Test VERIFY CBW CBW_CB length error\n");
1241     _test_init_cbw_VERIFY();
1242     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB_LENGTH + 0) = 0;
1243     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
1244     if (status != UX_SUCCESS)
1245     {
1246         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1247         test_control_return(1);
1248     }
1249     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1250     if (status != UX_TRANSFER_STALLED)
1251     {
1252         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1253         test_control_return(1);
1254     }
1255     status = _test_transfer_data(__LINE__, buffer, 128, UX_FALSE);
1256     if (status != UX_TRANSFER_STALLED)
1257     {
1258         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1259         test_control_return(1);
1260     }
1261     _test_clear_stall(UX_FALSE);
1262     _test_clear_stall(UX_TRUE);
1263     _test_init_cbw_VERIFY();
1264     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
1265     if (status != UX_TRANSFER_STALLED)
1266     {
1267         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1268         test_control_return(1);
1269     }
1270     _ux_host_class_storage_device_reset(storage);
1271 
1272     stepinfo(">>>>>>>>>>>>>>>> Test CBW CMD unknown error\n");
1273     _test_init_cbw_VERIFY();
1274     *(cbw + UX_HOST_CLASS_STORAGE_CBW_CB + 0) = 0xFF;
1275     status = _test_send_cbw_EX(__LINE__, UX_HOST_CLASS_STORAGE_CBW_LENGTH);
1276     if (status != UX_SUCCESS)
1277     {
1278         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1279         test_control_return(1);
1280     }
1281     status = _test_wait_csw(__LINE__);
1282     if (status != UX_SUCCESS)
1283     {
1284         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1285         test_control_return(1);
1286     }
1287     _ux_host_class_storage_device_reset(storage);
1288 }
1289 
1290 
_msc_get_max_lun_cases_test(const char * __file__,int __line__)1291 static void  _msc_get_max_lun_cases_test(const char* __file__, int __line__)
1292 {
1293 UINT                                        status;
1294 UX_DEVICE                                   *device;
1295 UX_ENDPOINT                                 *control_endpoint;
1296 UX_TRANSFER                                 *transfer_request;
1297 
1298     stepinfo("\n%s:%d:MSC GET_MAX_LUN tests\n", __file__, __line__);
1299 
1300     status = ux_host_stack_device_get(0, &device);
1301     if (status != UX_SUCCESS)
1302     {
1303         printf("ERROR #%d.%d: device_get fail\n", __LINE__, __line__);
1304         test_control_return(1);
1305     }
1306     control_endpoint = &device->ux_device_control_endpoint;
1307     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
1308 
1309     /* Send transfer request - GetMaxLun. */
1310     transfer_request -> ux_transfer_request_data_pointer =      UX_NULL;
1311     transfer_request -> ux_transfer_request_requested_length =  0;
1312     transfer_request -> ux_transfer_request_function =          UX_SLAVE_CLASS_STORAGE_GET_MAX_LUN;
1313     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
1314     transfer_request -> ux_transfer_request_value =             0;
1315     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber;
1316     status =  ux_host_stack_transfer_request(transfer_request);
1317     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1318     {
1319         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1320         test_control_return(1);
1321     }
1322 
1323     /* Invalid wValue.  */
1324     transfer_request -> ux_transfer_request_value =             1;
1325     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber;
1326     status =  ux_host_stack_transfer_request(transfer_request);
1327     if (status != UX_TRANSFER_STALLED)
1328     {
1329         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1330         test_control_return(1);
1331     }
1332 
1333     /* Invalid wIndex.  */
1334     transfer_request -> ux_transfer_request_value =             0;
1335     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber + 1;
1336     status =  ux_host_stack_transfer_request(transfer_request);
1337     if (status != UX_TRANSFER_STALLED)
1338     {
1339         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1340         test_control_return(1);
1341     }
1342 
1343     /* Send transfer request - UX_SLAVE_CLASS_STORAGE_RESET.  */
1344     transfer_request -> ux_transfer_request_function =          UX_SLAVE_CLASS_STORAGE_RESET;
1345 
1346     /* Invalid wValue.  */
1347     transfer_request -> ux_transfer_request_value =             1;
1348     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber;
1349     status =  ux_host_stack_transfer_request(transfer_request);
1350     if (status != UX_TRANSFER_STALLED)
1351     {
1352         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1353         test_control_return(1);
1354     }
1355 
1356     /* Invalid wIndex.  */
1357     transfer_request -> ux_transfer_request_value =             0;
1358     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber + 1;
1359     status =  ux_host_stack_transfer_request(transfer_request);
1360     if (status != UX_TRANSFER_STALLED)
1361     {
1362         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1363         test_control_return(1);
1364     }
1365 
1366     /* Invalid wLength.  */
1367     transfer_request -> ux_transfer_request_data_pointer =      (UCHAR*)&status;
1368     transfer_request -> ux_transfer_request_value =             0;
1369     transfer_request -> ux_transfer_request_index =             storage -> ux_host_class_storage_interface -> ux_interface_descriptor.bInterfaceNumber;
1370     transfer_request -> ux_transfer_request_requested_length =  1;
1371     status =  ux_host_stack_transfer_request(transfer_request);
1372     if (status != UX_TRANSFER_STALLED)
1373     {
1374         printf("ERROR #%d: 0x%x\n", __LINE__, status);
1375         test_control_return(1);
1376     }
1377 }
1378 
_msc_inquiry_cases_test(const char * __file__,int __line__)1379 static void _msc_inquiry_cases_test(const char* __file__, int __line__)
1380 {
1381 UINT                                        status;
1382 UX_SLAVE_DEVICE                             *slave_device;
1383 UX_SLAVE_CLASS                              *slave_class;
1384 UX_SLAVE_CLASS_STORAGE                      *slave_storage;
1385 
1386     stepinfo("\n%s:%d:MSC INQUIRY tests\n", __file__, __line__);
1387 
1388     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(standard)\n");
1389     status = test_host_class_storage_inquiry(storage, 0x00, buffer, 64);
1390     if (status != UX_SUCCESS)
1391     {
1392         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1393         test_control_return(1);
1394     }
1395 
1396     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(standard, UX_SLAVE_CLASS_STORAGE_MEDIA_CDROM)\n");
1397     slave_device =  &_ux_system_slave->ux_system_slave_device;
1398     slave_class = _ux_system_slave->ux_system_slave_interface_class_array[0];
1399     slave_storage = (UX_SLAVE_CLASS_STORAGE *)slave_class->ux_slave_class_instance;
1400     slave_storage -> ux_slave_class_storage_lun[0].ux_slave_class_storage_media_type = UX_SLAVE_CLASS_STORAGE_MEDIA_CDROM;
1401     status = test_host_class_storage_inquiry(storage, 0x00, buffer, 64);
1402     if (status != UX_SUCCESS)
1403     {
1404 
1405         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1406         test_control_return(1);
1407     }
1408 
1409     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(unknown page code)\n");
1410     status = test_host_class_storage_inquiry(storage, 0xEF, buffer, 64);
1411     if (status != UX_SUCCESS)
1412     {
1413 
1414         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1415         test_control_return(1);
1416     }
1417 
1418     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(big buffer)\n");
1419     status = _test_host_class_storage_inquiry(storage, 0x80,
1420         64,
1421         UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC,
1422         0x00, buffer, 64);
1423     if (status != UX_SUCCESS)
1424     {
1425 
1426         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1427         test_control_return(1);
1428     }
1429 
1430     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(Hi <> Do)\n");
1431     status = _test_host_class_storage_inquiry(storage, 0x00,
1432         UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH,
1433         UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC,
1434         0x00, buffer, UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH);
1435     if (status != UX_SUCCESS)
1436     {
1437 
1438         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1439         test_control_return(1);
1440     }
1441 
1442     stepinfo(">>>>>>>>>>>>>>>> Test INQUIRY(Hi <> Do)\n");
1443     status = _test_host_class_storage_inquiry(storage, 0x00,
1444         0,
1445         UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC,
1446         0x00, buffer, UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH);
1447     if (status != UX_SUCCESS)
1448     {
1449 
1450         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1451         test_control_return(1);
1452     }
1453 }
1454 
_msc_read_cases_test(const char * __file__,int __line__)1455 static void _msc_read_cases_test(const char* __file__, int __line__)
1456 {
1457 UINT                                        status;
1458 
1459     stepinfo("\n%s:%d:MSC READ tests\n", __file__, __line__);
1460 
1461     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ32 - success\n");
1462     _test_init_cbw_READ(UX_SLAVE_CLASS_STORAGE_SCSI_READ32, 0, 1);
1463     status = _test_send_cbw(__LINE__);
1464     if (status != UX_SUCCESS)
1465     {
1466         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1467         test_control_return(1);
1468     }
1469     status = _test_transfer_data(__LINE__, buffer, 512, UX_TRUE);
1470     if (status != UX_SUCCESS)
1471     {
1472         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1473         test_control_return(1);
1474     }
1475     status = _test_wait_csw(__LINE__);
1476     if (status != UX_SUCCESS)
1477     {
1478         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1479         test_control_return(1);
1480     }
1481 
1482     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ16 - status fail\n");
1483     ram_disk_status = UX_ERROR;
1484     _test_init_cbw_READ(UX_SLAVE_CLASS_STORAGE_SCSI_READ16, 0, 1);
1485     status = _test_send_cbw(__LINE__);
1486     if (status != UX_SUCCESS)
1487     {
1488         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1489         test_control_return(1);
1490     }
1491     status = _test_transfer_data(__LINE__, buffer, 512, UX_TRUE);
1492     if (status != UX_TRANSFER_STALLED)
1493     {
1494         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1495         test_control_return(1);
1496     }
1497     ram_disk_status = UX_SUCCESS;
1498     _test_clear_stall(UX_TRUE);
1499     status = _test_wait_csw(__LINE__);
1500     if (status != UX_SUCCESS)
1501     {
1502         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1503         test_control_return(1);
1504     }
1505 
1506     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ16 - transfer fail\n");
1507     _test_init_cbw_READ(UX_SLAVE_CLASS_STORAGE_SCSI_READ16, 0, 1);
1508     status = _test_send_cbw(__LINE__);
1509     if (status != UX_SUCCESS)
1510     {
1511         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1512         test_control_return(1);
1513     }
1514     ux_test_dcd_sim_slave_set_actions(fail_on_bulkin);
1515     status = _test_transfer_data(__LINE__, buffer, 512, UX_TRUE);
1516     if (status != UX_TRANSFER_STALLED)
1517     {
1518         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1519         test_control_return(1);
1520     }
1521     _test_clear_stall(UX_TRUE);
1522     status = _test_wait_csw(__LINE__);
1523     if (status != UX_SUCCESS)
1524     {
1525         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1526         test_control_return(1);
1527     }
1528 
1529     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ16 - Case(7) Hi < Di\n");
1530     _test_init_cbw_READ_EX(0x80, 0, UX_SLAVE_CLASS_STORAGE_SCSI_READ16, 0, 1);
1531     status = _test_send_cbw(__LINE__);
1532     if (status != UX_SUCCESS)
1533     {
1534         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1535         test_control_return(1);
1536     }
1537     status = _test_transfer_data(__LINE__, buffer, 512, UX_TRUE);
1538     if (status != UX_TRANSFER_STALLED)
1539     {
1540         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1541         test_control_return(1);
1542     }
1543     _test_clear_stall(UX_TRUE);
1544     status = _test_wait_csw(__LINE__);
1545     if (status != UX_SUCCESS)
1546     {
1547         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1548         test_control_return(1);
1549     }
1550     _ux_host_class_storage_device_reset(storage);
1551 
1552     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ16 - Case(8) Hi <> Do\n");
1553     _test_init_cbw_READ_EX(0x00, 512, UX_SLAVE_CLASS_STORAGE_SCSI_READ16, 0, 1);
1554     status = _test_send_cbw(__LINE__);
1555     if (status != UX_SUCCESS)
1556     {
1557         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1558         test_control_return(1);
1559     }
1560     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1561     if (status != UX_TRANSFER_STALLED)
1562     {
1563         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1564         test_control_return(1);
1565     }
1566     _test_clear_stall(UX_FALSE);
1567     status = _test_wait_csw(__LINE__);
1568     if (status != UX_SUCCESS)
1569     {
1570         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1571         test_control_return(1);
1572     }
1573     _ux_host_class_storage_device_reset(storage);
1574 
1575     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_READ16 - Case(5) Hi > Di\n");
1576     _test_init_cbw_READ_EX(0x80, 1024, UX_SLAVE_CLASS_STORAGE_SCSI_READ16, 0, 1);
1577     status = _test_send_cbw(__LINE__);
1578     if (status != UX_SUCCESS)
1579     {
1580         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1581         test_control_return(1);
1582     }
1583     status = _test_transfer_data(__LINE__, buffer, 1024, UX_TRUE);
1584     if (status != UX_TRANSFER_STALLED)
1585     {
1586         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1587         test_control_return(1);
1588     }
1589     _test_clear_stall(UX_TRUE);
1590     status = _test_wait_csw(__LINE__);
1591     if (status != UX_SUCCESS)
1592     {
1593         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1594         test_control_return(1);
1595     }
1596     _ux_host_class_storage_device_reset(storage);
1597 }
1598 
_msc_write_cases_test(const char * __file__,int __line__)1599 static void _msc_write_cases_test(const char* __file__, int __line__)
1600 {
1601 UINT                                        status;
1602 UX_SLAVE_DEVICE                             *slave_device;
1603 UX_SLAVE_CLASS                              *slave_class;
1604 UX_SLAVE_CLASS_STORAGE                      *slave_storage;
1605 
1606     stepinfo("\n%s:%d:MSC WRITE tests\n", __file__, __line__);
1607 
1608     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32 - success\n");
1609     _test_init_cbw_WRITE(UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32, 0, 1);
1610     status = _test_send_cbw(__LINE__);
1611     if (status != UX_SUCCESS)
1612     {
1613         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1614         test_control_return(1);
1615     }
1616     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1617     if (status != UX_SUCCESS)
1618     {
1619         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1620         test_control_return(1);
1621     }
1622     status = _test_wait_csw(__LINE__);
1623     if (status != UX_SUCCESS)
1624     {
1625         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1626         test_control_return(1);
1627     }
1628 
1629     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - status fail\n");
1630     ram_disk_status = UX_ERROR;
1631     _test_init_cbw_WRITE(UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1632     status = _test_send_cbw(__LINE__);
1633     if (status != UX_SUCCESS)
1634     {
1635         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1636         test_control_return(1);
1637     }
1638     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1639     if (status != UX_TRANSFER_STALLED)
1640     {
1641         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1642         test_control_return(1);
1643     }
1644     ram_disk_status = UX_SUCCESS;
1645     _test_clear_stall(UX_FALSE);
1646     status = _test_wait_csw(__LINE__);
1647     if (status != UX_SUCCESS)
1648     {
1649         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1650         test_control_return(1);
1651     }
1652 
1653     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - transfer fail\n");
1654     _test_init_cbw_WRITE(UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1655     status = _test_send_cbw(__LINE__);
1656     if (status != UX_SUCCESS)
1657     {
1658         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1659         test_control_return(1);
1660     }
1661     ux_test_dcd_sim_slave_set_actions(fail_on_bulkout);
1662     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1663     if (status != UX_TRANSFER_STALLED)
1664     {
1665         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1666         test_control_return(1);
1667     }
1668     _test_clear_stall(UX_FALSE);
1669     status = _test_wait_csw(__LINE__);
1670     if (status != UX_SUCCESS)
1671     {
1672         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1673         test_control_return(1);
1674     }
1675 
1676     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - WP fail\n");
1677     slave_device =  &_ux_system_slave->ux_system_slave_device;
1678     slave_class = _ux_system_slave->ux_system_slave_interface_class_array[0];
1679     slave_storage = (UX_SLAVE_CLASS_STORAGE *)slave_class->ux_slave_class_instance;
1680     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_read_only_flag = UX_TRUE;
1681     _test_init_cbw_WRITE(UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1682     status = _test_send_cbw(__LINE__);
1683     if (status != UX_SUCCESS)
1684     {
1685         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1686         test_control_return(1);
1687     }
1688     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1689     if (status != UX_TRANSFER_STALLED)
1690     {
1691         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1692         test_control_return(1);
1693     }
1694     _test_clear_stall(UX_FALSE);
1695     status = _test_wait_csw(__LINE__);
1696     if (status != UX_SUCCESS)
1697     {
1698         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1699         test_control_return(1);
1700     }
1701     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_read_only_flag = UX_FALSE;
1702 
1703     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - Case (3) Hn < Do\n");
1704     _test_init_cbw_WRITE_EX(0x00, 0, UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1705     status = _test_send_cbw(__LINE__);
1706     if (status != UX_SUCCESS)
1707     {
1708         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1709         test_control_return(1);
1710     }
1711     #if 0 /* Host expect no data.  */
1712     status = _test_transfer_data(__LINE__, buffer, 512, UX_FALSE);
1713     if (status != UX_TRANSFER_STALLED)
1714     {
1715         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1716         test_control_return(1);
1717     }
1718     _test_clear_stall(UX_FALSE);
1719     #endif
1720     status = _test_wait_csw(__LINE__);
1721     if (status != UX_SUCCESS)
1722     {
1723         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1724         test_control_return(1);
1725     }
1726     _ux_host_class_storage_device_reset(storage);
1727 
1728     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - Case (8) Hi <> Do\n");
1729     _test_init_cbw_WRITE_EX(0x80, 512, UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1730     status = _test_send_cbw(__LINE__);
1731     if (status != UX_SUCCESS)
1732     {
1733         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1734         test_control_return(1);
1735     }
1736     status = _test_transfer_data(__LINE__, buffer, 512, UX_TRUE);
1737     if (status != UX_TRANSFER_STALLED)
1738     {
1739         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1740         test_control_return(1);
1741     }
1742     _test_clear_stall(UX_TRUE);
1743     status = _test_wait_csw(__LINE__);
1744     if (status != UX_SUCCESS)
1745     {
1746         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1747         test_control_return(1);
1748     }
1749     _ux_host_class_storage_device_reset(storage);
1750 
1751     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 - Case (9) Ho > Do\n");
1752     _test_init_cbw_WRITE_EX(0x00, 1024, UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16, 0, 1);
1753     status = _test_send_cbw(__LINE__);
1754     if (status != UX_SUCCESS)
1755     {
1756         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1757         test_control_return(1);
1758     }
1759     status = _test_transfer_data(__LINE__, buffer, 1024, UX_FALSE);
1760     if (status != UX_TRANSFER_STALLED)
1761     {
1762         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1763         test_control_return(1);
1764     }
1765     _test_clear_stall(UX_FALSE);
1766     status = _test_wait_csw(__LINE__);
1767     if (status != UX_SUCCESS)
1768     {
1769         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1770         test_control_return(1);
1771     }
1772     _ux_host_class_storage_device_reset(storage);
1773 }
1774 
_msc_request_sense_cases_test(const char * __file__,int __line__)1775 static void _msc_request_sense_cases_test(const char* __file__, int __line__)
1776 {
1777 UINT            status;
1778 
1779     stepinfo("\n%s:%d:MSC REQUEST_SENSE tests\n", __file__, __line__);
1780 
1781     _test_init_cbw_REQUEST_SENSE(64);
1782     status = _test_send_cbw(__LINE__);
1783     if (status != UX_SUCCESS)
1784     {
1785         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1786         test_control_return(1);
1787     }
1788     status = _test_transfer_data(__LINE__, buffer, 64, UX_TRUE);
1789     if (status != UX_SUCCESS)
1790     {
1791         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1792         test_control_return(1);
1793     }
1794     _test_clear_stall(UX_TRUE);
1795     status = _test_wait_csw(__LINE__);
1796     if (status != UX_SUCCESS)
1797     {
1798         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1799         test_control_return(1);
1800     }
1801     _ux_host_class_storage_device_reset(storage);
1802 }
1803 
_msc_test_ready_cases_test(const char * __file__,int __line__)1804 static void _msc_test_ready_cases_test(const char* __file__, int __line__)
1805 {
1806 UINT status;
1807 
1808     stepinfo("\n%s:%d:MSC UNIT_READY tests\n", __file__, __line__);
1809 
1810     _test_init_cbw_TEST_READY(64);
1811     status = _test_send_cbw(__LINE__);
1812     if (status != UX_SUCCESS)
1813     {
1814         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1815         test_control_return(1);
1816     }
1817     status = _test_transfer_data(__LINE__, buffer, 64, UX_FALSE);
1818     if (status != UX_TRANSFER_STALLED)
1819     {
1820         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1821         test_control_return(1);
1822     }
1823     _test_clear_stall(UX_FALSE);
1824     status = _test_wait_csw(__LINE__);
1825     if (status != UX_SUCCESS)
1826     {
1827         printf("ERROR #%d.%d: code 0x%x\n", __LINE__, __line__, status);
1828         test_control_return(1);
1829     }
1830     _ux_host_class_storage_device_reset(storage);
1831 }
1832 
_msc_format_unit_cases_test(const char * __file__,int __line__)1833 static void _msc_format_unit_cases_test(const char* __file__, int __line__)
1834 {
1835 UINT status;
1836 
1837     stepinfo("\n%s:%d:MSC FORMAT_UNIT tests\n", __file__, __line__);
1838 
1839     _test_init_cbw_FORMAT_UNIT();
1840     status = _test_send_cbw(__LINE__);
1841     if (status != UX_SUCCESS)
1842     {
1843         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1844         test_control_return(1);
1845     }
1846     #if 0 /* Host expects no data.  */
1847     status = _test_transfer_data(__LINE__, "test dead beef", 15, UX_FALSE);
1848     if (status != UX_TRANSFER_STALLED)
1849     {
1850         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1851         test_control_return(1);
1852     }
1853     _test_clear_stall(UX_FALSE);
1854     #endif
1855     status = _test_wait_csw(__LINE__);
1856     if (status != UX_SUCCESS)
1857     {
1858         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1859         test_control_return(1);
1860     }
1861     status = _test_request_sense();
1862     if (status != UX_SUCCESS)
1863     {
1864         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1865         test_control_return(1);
1866     }
1867 }
1868 
_msc_start_stop_cases_test(const char * __file__,int __line__)1869 static void _msc_start_stop_cases_test(const char* __file__, int __line__)
1870 {
1871 UINT status;
1872 
1873     stepinfo("\n%s:%d:MSC START_STOP tests\n", __file__, __line__);
1874 
1875     _test_init_cbw_START_STOP();
1876     status = _test_send_cbw(__LINE__);
1877     if (status != UX_SUCCESS)
1878     {
1879         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1880         test_control_return(1);
1881     }
1882     status = _test_wait_csw(__LINE__);
1883     if (status != UX_SUCCESS)
1884     {
1885         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1886         test_control_return(1);
1887     }
1888 }
1889 
_msc_verify_cases_test(const char * __file__,int __line__)1890 static void _msc_verify_cases_test(const char* __file__, int __line__)
1891 {
1892 UINT status;
1893 
1894     stepinfo("\n%s:%d:MSC VERIFY tests\n", __file__, __line__);
1895 
1896     _test_init_cbw_VERIFY();
1897     status = _test_send_cbw(__LINE__);
1898     if (status != UX_SUCCESS)
1899     {
1900         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1901         test_control_return(1);
1902     }
1903     status = _test_wait_csw(__LINE__);
1904     if (status != UX_SUCCESS)
1905     {
1906         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1907         test_control_return(1);
1908     }
1909 }
1910 
_msc_mode_sense_cases_test(const char * __file__,int __line__)1911 static void _msc_mode_sense_cases_test(const char* __file__, int __line__)
1912 {
1913 UINT                                        status;
1914 UX_SLAVE_DEVICE                             *slave_device;
1915 UX_SLAVE_CLASS                              *slave_class;
1916 UX_SLAVE_CLASS_STORAGE                      *slave_storage;
1917 
1918     stepinfo("\n%s:%d:MSC MODE_SENSE tests\n", __file__, __line__);
1919 
1920     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CDROM):\n");
1921 
1922     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CDROM) - 128B\n");
1923     _test_init_cbw_MODE_SENSE(UX_FALSE, UX_SLAVE_CLASS_STORAGE_MMC2_PAGE_CODE_CDROM, 128);
1924     status = _test_send_cbw(__LINE__);
1925     if (status != UX_SUCCESS)
1926     {
1927         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1928         test_control_return(1);
1929     }
1930     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1931     if (status != UX_SUCCESS)
1932     {
1933         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1934         test_control_return(1);
1935     }
1936     status = _test_wait_csw(__LINE__);
1937     if (status != UX_SUCCESS)
1938     {
1939         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1940         test_control_return(1);
1941     }
1942 
1943     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CDROM) - 74B\n");
1944     _test_init_cbw_MODE_SENSE(UX_TRUE, UX_SLAVE_CLASS_STORAGE_MMC2_PAGE_CODE_CDROM, 74);
1945     status = _test_send_cbw(__LINE__);
1946     if (status != UX_SUCCESS)
1947     {
1948         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1949         test_control_return(1);
1950     }
1951     status = _test_transfer_data(__LINE__, buffer, 74, UX_TRUE);
1952     if (status != UX_SUCCESS)
1953     {
1954         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1955         test_control_return(1);
1956     }
1957     status = _test_wait_csw(__LINE__);
1958     if (status != UX_SUCCESS)
1959     {
1960         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1961         test_control_return(1);
1962     }
1963 
1964     /* Change read_only_flag */
1965     slave_device =  &_ux_system_slave->ux_system_slave_device;
1966     slave_class = _ux_system_slave->ux_system_slave_interface_class_array[0];
1967     slave_storage = (UX_SLAVE_CLASS_STORAGE *)slave_class->ux_slave_class_instance;
1968     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_read_only_flag = UX_TRUE;
1969 
1970     /************ UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE ****************/
1971     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CACHE):\n");
1972 
1973     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CACHE) - 128B\n");
1974     _test_init_cbw_MODE_SENSE(UX_FALSE, UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE, 128);
1975     status = _test_send_cbw(__LINE__);
1976     if (status != UX_SUCCESS)
1977     {
1978         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1979         test_control_return(1);
1980     }
1981     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
1982     if (status != UX_SUCCESS)
1983     {
1984         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1985         test_control_return(1);
1986     }
1987     status = _test_wait_csw(__LINE__);
1988     if (status != UX_SUCCESS)
1989     {
1990         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1991         test_control_return(1);
1992     }
1993 
1994     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CACHE) - 24B\n");
1995     _test_init_cbw_MODE_SENSE(UX_TRUE, UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE, 24);
1996     status = _test_send_cbw(__LINE__);
1997     if (status != UX_SUCCESS)
1998     {
1999         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2000         test_control_return(1);
2001     }
2002     status = _test_transfer_data(__LINE__, buffer, 24, UX_TRUE);
2003     if (status != UX_SUCCESS)
2004     {
2005         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2006         test_control_return(1);
2007     }
2008     status = _test_wait_csw(__LINE__);
2009     if (status != UX_SUCCESS)
2010     {
2011         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2012         test_control_return(1);
2013     }
2014 
2015     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_CACHE) - 24B\n");
2016     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_flush = demo_media_flush;
2017     _test_init_cbw_MODE_SENSE(UX_TRUE, UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE, 24);
2018     status = _test_send_cbw(__LINE__);
2019     if (status != UX_SUCCESS)
2020     {
2021         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2022         test_control_return(1);
2023     }
2024     status = _test_transfer_data(__LINE__, buffer, 24, UX_TRUE);
2025     if (status != UX_SUCCESS)
2026     {
2027         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2028         test_control_return(1);
2029     }
2030     status = _test_wait_csw(__LINE__);
2031     if (status != UX_SUCCESS)
2032     {
2033         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2034         test_control_return(1);
2035     }
2036 
2037     /************ UX_SLAVE_CLASS_STORAGE_PAGE_CODE_IEC ****************/
2038 
2039     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_IEC) - 128B\n");
2040     _test_init_cbw_MODE_SENSE(UX_FALSE, UX_SLAVE_CLASS_STORAGE_PAGE_CODE_IEC, 128);
2041     status = _test_send_cbw(__LINE__);
2042     if (status != UX_SUCCESS)
2043     {
2044         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2045         test_control_return(1);
2046     }
2047     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
2048     if (status != UX_SUCCESS)
2049     {
2050         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2051         test_control_return(1);
2052     }
2053     status = _test_wait_csw(__LINE__);
2054     if (status != UX_SUCCESS)
2055     {
2056         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2057         test_control_return(1);
2058     }
2059 
2060     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(PAGE_CODE_IEC) - 16B\n");
2061     _test_init_cbw_MODE_SENSE(UX_TRUE, UX_SLAVE_CLASS_STORAGE_PAGE_CODE_IEC, 16);
2062     status = _test_send_cbw(__LINE__);
2063     if (status != UX_SUCCESS)
2064     {
2065         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2066         test_control_return(1);
2067     }
2068     status = _test_transfer_data(__LINE__, buffer, 16, UX_TRUE);
2069     if (status != UX_SUCCESS)
2070     {
2071         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2072         test_control_return(1);
2073     }
2074     status = _test_wait_csw(__LINE__);
2075     if (status != UX_SUCCESS)
2076     {
2077         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2078         test_control_return(1);
2079     }
2080 
2081     /************ 0x3F ****************/
2082 
2083     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(0x3F) - 128B\n");
2084     _test_init_cbw_MODE_SENSE(UX_FALSE, 0x3F, 128);
2085     status = _test_send_cbw(__LINE__);
2086     if (status != UX_SUCCESS)
2087     {
2088         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2089         test_control_return(1);
2090     }
2091     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
2092     if (status != UX_SUCCESS)
2093     {
2094         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2095         test_control_return(1);
2096     }
2097     status = _test_wait_csw(__LINE__);
2098     if (status != UX_SUCCESS)
2099     {
2100         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2101         test_control_return(1);
2102     }
2103 
2104     /************ 0x3F ****************/
2105 
2106     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE(0x3F) - %dB\n",
2107         UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE + 8);
2108     _test_init_cbw_MODE_SENSE(UX_FALSE, 0x3F, UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE + 8);
2109     status = _test_send_cbw(__LINE__);
2110     if (status != UX_SUCCESS)
2111     {
2112         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2113         test_control_return(1);
2114     }
2115     status = _test_transfer_data(__LINE__, buffer, 128, UX_TRUE);
2116     if (status != UX_SUCCESS)
2117     {
2118         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2119         test_control_return(1);
2120     }
2121     status = _test_wait_csw(__LINE__);
2122     if (status != UX_SUCCESS)
2123     {
2124         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2125         test_control_return(1);
2126     }
2127 }
2128 
_msc_mode_select_cases_test(const char * __file__,int __line__)2129 static void _msc_mode_select_cases_test(const char* __file__, int __line__)
2130 {
2131 UINT status;
2132 
2133     stepinfo("\n%s:%d:MSC MODE_SELECT tests\n", __file__, __line__);
2134 
2135     _test_init_cbw_MODE_SELECT(15);
2136     status = _test_send_cbw(__LINE__);
2137     if (status != UX_SUCCESS)
2138     {
2139         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2140         test_control_return(1);
2141     }
2142     status = _test_transfer_data(__LINE__, "test dead beef", 15, UX_FALSE);
2143     if (status != UX_TRANSFER_STALLED)
2144     {
2145         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2146         test_control_return(1);
2147     }
2148     _test_clear_stall(UX_FALSE);
2149     status = _test_wait_csw(__LINE__);
2150     if (status != UX_SUCCESS)
2151     {
2152         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2153         test_control_return(1);
2154     }
2155     status = _test_request_sense();
2156     if (status != UX_SUCCESS)
2157     {
2158         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2159         test_control_return(1);
2160     }
2161 }
2162 
_msc_synchronous_cache_cases_test(const char * __file__,int __line__)2163 static void _msc_synchronous_cache_cases_test(const char* __file__, int __line__)
2164 {
2165 UINT                                        status;
2166 UX_SLAVE_DEVICE                             *slave_device;
2167 UX_SLAVE_CLASS                              *slave_class;
2168 UX_SLAVE_CLASS_STORAGE                      *slave_storage;
2169 
2170     stepinfo("\n%s:%d:MSC SYNCHRONOUS_CACHE tests\n", __file__, __line__);
2171 
2172     slave_device =  &_ux_system_slave->ux_system_slave_device;
2173     slave_class = _ux_system_slave->ux_system_slave_interface_class_array[0];
2174     slave_storage = (UX_SLAVE_CLASS_STORAGE *)slave_class->ux_slave_class_instance;
2175 
2176     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE no CB - success\n");
2177     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_flush = UX_NULL;
2178     slave_storage->ux_slave_class_storage_lun[1].ux_slave_class_storage_media_flush = UX_NULL;
2179     _test_init_cbw_SYNCHRONIZE_CACHE(UX_FALSE, UX_FALSE, 0, 1);
2180     status = _test_send_cbw(__LINE__);
2181     if (status != UX_SUCCESS)
2182     {
2183         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2184         test_control_return(1);
2185     }
2186     status = _test_wait_csw(__LINE__);
2187     if (status != UX_SUCCESS)
2188     {
2189         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2190         test_control_return(1);
2191     }
2192 
2193     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE - success\n");
2194     slave_storage->ux_slave_class_storage_lun[0].ux_slave_class_storage_media_flush = demo_media_flush;
2195     slave_storage->ux_slave_class_storage_lun[1].ux_slave_class_storage_media_flush = demo_media_flush;
2196     _test_init_cbw_SYNCHRONIZE_CACHE(UX_FALSE, UX_FALSE, 0, 1);
2197     status = _test_send_cbw(__LINE__);
2198     if (status != UX_SUCCESS)
2199     {
2200         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2201         test_control_return(1);
2202     }
2203     status = _test_wait_csw(__LINE__);
2204     if (status != UX_SUCCESS)
2205     {
2206         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2207         test_control_return(1);
2208     }
2209 
2210     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE - status fail\n");
2211     _test_init_cbw_SYNCHRONIZE_CACHE(UX_FALSE, UX_FALSE, 0, 1);
2212     ram_disk_status = UX_ERROR;
2213     status = _test_send_cbw(__LINE__);
2214     if (status != UX_SUCCESS)
2215     {
2216         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2217         test_control_return(1);
2218     }
2219     status = _test_wait_csw_EX(__LINE__);
2220     if (status != UX_TRANSFER_STALLED)
2221     {
2222         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2223         test_control_return(1);
2224     }
2225     _test_clear_stall(UX_TRUE);
2226     status = _test_wait_csw_EX(__LINE__);
2227     if (status != UX_SUCCESS)
2228     {
2229         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2230         test_control_return(1);
2231     }
2232     status = _test_request_sense();
2233     if (status != UX_SUCCESS)
2234     {
2235         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2236         test_control_return(1);
2237     }
2238     ram_disk_status = UX_SUCCESS;
2239 
2240     stepinfo(">>>>>>>>>>>>>>> UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE - flush fail\n");
2241     _test_init_cbw_SYNCHRONIZE_CACHE(UX_FALSE, UX_FALSE, 0, 1);
2242     ram_disk_flush_status = UX_STATE_ERROR;
2243     status = _test_send_cbw(__LINE__);
2244     if (status != UX_SUCCESS)
2245     {
2246         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2247         test_control_return(1);
2248     }
2249     status = _test_wait_csw_EX(__LINE__);
2250     if (status != UX_TRANSFER_STALLED)
2251     {
2252         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2253         test_control_return(1);
2254     }
2255     _test_clear_stall(UX_TRUE);
2256     status = _test_wait_csw_EX(__LINE__);
2257     if (status != UX_SUCCESS)
2258     {
2259         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2260         test_control_return(1);
2261     }
2262     ram_disk_flush_status = UX_STATE_NEXT;
2263 }
2264 
_msc_prevent_allow_removal_cases_test(const char * __file__,int __line__)2265 static void _msc_prevent_allow_removal_cases_test(const char* __file__, int __line__)
2266 {
2267 UINT status;
2268 
2269     stepinfo("\n%s:%d:MSC PREVENT_ALLOW_MEDIA_REMOVAL tests\n", __file__, __line__);
2270 
2271     _test_init_cbw_PREVENT_ALLOW_MEDIA_REMOVAL();
2272     status = _test_send_cbw(__LINE__);
2273     if (status != UX_SUCCESS)
2274     {
2275         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2276         test_control_return(1);
2277     }
2278     status = _test_wait_csw(__LINE__);
2279     if (status != UX_SUCCESS)
2280     {
2281         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
2282         test_control_return(1);
2283     }
2284 }
2285 
2286 
_msc_media_read_test(const char * __file__,int __line__)2287 static void _msc_media_read_test(const char* __file__, int __line__)
2288 {
2289 UINT                                        status;
2290 ULONG                                       test_n;
2291 ULONG                                       test_size[] = {
2292     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512,
2293     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512,
2294     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512 + 1};
2295 
2296     stepinfo("\n%s:%d:MSC Media Read tests\n", __file__, __line__);
2297 
2298     if (media == UX_NULL || media -> fx_media_id == 0)
2299     {
2300         printf("ERROR %d: media error\n", __LINE__);
2301         test_control_return(1);
2302     }
2303 
2304     stepinfo(">>>>>>>>>>>> Disk read(1) test\n");
2305     {
2306         status = fx_media_read(media, 48, buffer);
2307         if (status != FX_SUCCESS)
2308         {
2309             printf("ERROR %d: 0x%x\n", __LINE__, status);
2310             test_control_return(1);
2311         }
2312     }
2313 
2314     /* Disk read multiple test.  */
2315     for (test_n = 0; test_n < sizeof(test_size)/sizeof(test_size[0]); test_n ++)
2316     {
2317 
2318         stepinfo(">>>>>>>>>>>> Disk read(%d) test\n", test_size[test_n]);
2319         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
2320                 buffer, 0, test_size[test_n]);
2321         if (status != UX_SUCCESS)
2322         {
2323             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
2324             test_control_return(1);
2325         }
2326     }
2327 }
2328 
_msc_media_write_read_test(const char * __file__,int __line__)2329 static void _msc_media_write_read_test(const char* __file__, int __line__)
2330 {
2331 UINT                                        status;
2332 ULONG                                       test_n;
2333 INT                                         i;
2334 ULONG                                       test_size[] = {
2335     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512,
2336     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512,
2337     UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 2 / 512 + 1};
2338 
2339     stepinfo("\n%s:%d:MSC Media Write & Read tests\n", __file__, __line__);
2340 
2341     /* Check if media still available.  */
2342     if (media == UX_NULL || media -> fx_media_id == 0)
2343     {
2344         printf("ERROR %d: media error\n", __LINE__);
2345         test_control_return(1);
2346     }
2347 
2348     stepinfo(">>>>>>>>>>>> Disk write(1)/read(1) test\n");
2349     {
2350         for(i = 0; i < 512; i ++)
2351             buffer[i] = i;
2352         status = fx_media_write(media, 48, buffer);
2353         if (status != FX_SUCCESS)
2354         {
2355             printf("ERROR %d: 0x%x\n", __LINE__, status);
2356             test_control_return(1);
2357         }
2358         _ux_utility_memory_set(buffer, 0x00, 512);
2359         status = fx_media_read(media, 48, buffer);
2360         if (status != FX_SUCCESS)
2361         {
2362             printf("ERROR %d: 0x%x\n", __LINE__, status);
2363             test_control_return(1);
2364         }
2365         for (i = 0; i < 512; i ++)
2366         {
2367             if (buffer[i] != (UCHAR)i)
2368             {
2369                 printf("ERROR %d: %d <> %d\n", __LINE__, i, buffer[i]);
2370                 test_control_return(1);
2371             }
2372         }
2373     }
2374 
2375     /* Disk write/read multiple test.  */
2376     for (test_n = 0; test_n < sizeof(test_size)/sizeof(test_size[0]); test_n ++)
2377     {
2378         stepinfo(">>>>>>>>>>>> Disk write(%ld)/read(%ld) test\n",
2379                                         test_size[test_n], test_size[test_n]);
2380 
2381         for(i = 0; i < test_size[test_n] * 512; i ++)
2382             buffer[i] = (UCHAR)(i + (i >> 8));
2383         status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
2384                 buffer, 48, test_size[test_n]);
2385         if (status != FX_SUCCESS)
2386         {
2387             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
2388             test_control_return(1);
2389         }
2390         _ux_utility_memory_set(buffer, 0x00, test_size[test_n] * 512);
2391         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
2392                 buffer, 48, test_size[test_n]);
2393         if (status != FX_SUCCESS)
2394         {
2395             printf("ERROR %d.%ld: 0x%x\n", __LINE__, test_n, status);
2396             test_control_return(1);
2397         }
2398         for (i = 0; i < 512; i ++)
2399         {
2400             if (buffer[i] != (UCHAR)(i + (i >> 8)))
2401             {
2402                 printf("ERROR %d: %d <> %d\n", __LINE__, i, buffer[i]);
2403                 test_control_return(1);
2404             }
2405         }
2406     }
2407 }
2408 
_msc_enumeration_test(const char * __file__,int __line__,unsigned option)2409 static void _msc_enumeration_test(const char* __file__, int __line__, unsigned option)
2410 {
2411 UINT                                        status;
2412 ULONG                                       mem_free;
2413 ULONG                                       test_n;
2414 
2415     stepinfo("\n%s:%d:MSC Enumeration tests\n", __file__, __line__);
2416 
2417     stepinfo(">>>>>>>>>>>> Enumeration information collection\n");
2418     {
2419 
2420         /* Test disconnect. */
2421         ux_test_dcd_sim_slave_disconnect();
2422         ux_test_hcd_sim_host_disconnect();
2423 
2424         /* Check connection. */
2425         status = host_storage_instance_get(0);
2426         if (status == UX_SUCCESS)
2427         {
2428 
2429             printf("ERROR #%d\n", __LINE__);
2430             test_control_return(1);
2431         }
2432 
2433         /* Reset testing counts. */
2434         ux_test_utility_sim_mem_alloc_count_reset();
2435         ux_test_utility_sim_mutex_create_count_reset();
2436         ux_test_utility_sim_sem_create_count_reset();
2437         ux_test_utility_sim_sem_get_count_reset();
2438         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
2439 
2440         /* Save free memory usage. */
2441         mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
2442         ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2443         ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2444 
2445         /* Check connection. */
2446         status =  host_storage_instance_get(50);
2447         if (status != UX_SUCCESS)
2448         {
2449 
2450             printf("ERROR #%d\n", __LINE__);
2451             test_control_return(1);
2452         }
2453 
2454         /* Log create counts for further tests. */
2455         rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
2456         rsc_enum_sem_usage = rsc_sem_on_set_cfg;
2457         rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
2458         /* Log create counts when instances active for further tests. */
2459         rsc_storage_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
2460         rsc_storage_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
2461         rsc_storage_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
2462 
2463         /* Lock log base for tests. */
2464         ux_test_utility_sim_mem_alloc_log_lock();
2465 
2466         stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
2467         stepinfo("storage mem : %ld\n", rsc_storage_mem_alloc_count);
2468         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);
2469     }
2470 
2471     /* Simulate detach and attach for FS enumeration,
2472        and check if there is memory error in normal enumeration.
2473      */
2474     if (option & (1u))
2475     {
2476         stepinfo(">>>>>>>>>>>> Enumeration test\n");
2477         mem_free = (~0);
2478         for (test_n = 0; test_n < 3; test_n++)
2479         {
2480             stepinfo("%4ld / 2\n", test_n);
2481 
2482             /* Disconnect. */
2483             ux_test_dcd_sim_slave_disconnect();
2484             ux_test_hcd_sim_host_disconnect();
2485 
2486             /* Check */
2487             if (host_storage_instance_get(0) == UX_SUCCESS)
2488             {
2489 
2490                 printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
2491                 test_control_return(1);
2492             }
2493 
2494             /* Update memory free level (disconnect) */
2495             if (mem_free == (~0))
2496                 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
2497             else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
2498             {
2499 
2500                 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);
2501                 test_control_return(1);
2502             }
2503 
2504             /* Connect. */
2505             error_callback_counter = 0;
2506             ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2507             ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2508 
2509             /* Wait and break on error. */
2510             error_callback_counter = 0;
2511             ux_test_breakable_sleep(
2512                 (UX_MS_TO_TICK_NON_ZERO(UX_RH_ENUMERATION_RETRY_DELAY) +
2513                  UX_MS_TO_TICK_NON_ZERO(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY)) *
2514                 3,
2515                 sleep_break_on_connect);
2516 
2517             /* Check */
2518             if (host_storage_instance_get(0) != UX_SUCCESS)
2519             {
2520 
2521                 printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
2522                 test_control_return(1);
2523             }
2524         }
2525         stepinfo("\n");
2526     }
2527 
2528     /* Simulate detach and attach for FS enumeration,
2529        and test possible memory allocation error handlings.
2530      */
2531     if (option & (2u))
2532     {
2533         if (rsc_storage_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
2534         mem_free = (~0);
2535         for (test_n = 0; test_n < rsc_storage_mem_alloc_count; test_n ++)
2536         {
2537 
2538             stepinfo("%4ld / %4ld\n", test_n, rsc_storage_mem_alloc_count - 1);
2539 
2540             /* Disconnect. */
2541             ux_test_dcd_sim_slave_disconnect();
2542             ux_test_hcd_sim_host_disconnect();
2543 
2544             /* Check */
2545             if (host_storage_instance_get(0) == UX_SUCCESS)
2546             {
2547 
2548                 printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
2549                 test_control_return(1);
2550             }
2551 
2552             /* Update memory free level (disconnect) */
2553             if (mem_free == (~0))
2554                 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
2555             else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
2556             {
2557 
2558                 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);
2559                 test_control_return(1);
2560             }
2561 
2562             /* Set memory error generation */
2563             ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
2564 
2565             /* Connect. */
2566             error_callback_counter = 0;
2567             ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2568             ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2569 
2570             /* Wait and break on errors. */
2571             ux_test_breakable_sleep(100, sleep_break_on_error);
2572 
2573             /* Check error */
2574             if (host_storage_instance_get(0) == UX_SUCCESS)
2575             {
2576 
2577                 /* Could be media errors,
2578                 in this case instance is ready,
2579                 check error trap. */
2580                 if (error_callback_counter == 0)
2581                 {
2582                     printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
2583                     test_control_return(1);
2584                 }
2585             }
2586             stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
2587         }
2588         ux_test_utility_sim_mem_alloc_error_generation_stop();
2589         if (rsc_storage_mem_alloc_count) stepinfo("\n");
2590     }
2591 }
2592 
_msc_media_write_read_misc_test(const char * __file__,int __line__)2593 static void _msc_media_write_read_misc_test(const char* __file__, int __line__)
2594 {
2595 UINT                                        status;
2596 UINT                                        test_size = UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE * 3 / 512;
2597 UINT                                        test_n;
2598 ULONG                                       test_start;
2599 ULONG                                       test_ticks;
2600 INT                                         i;
2601 
2602     stepinfo("\n%s:%d:MSC Media Read tests\n", __file__, __line__);
2603 
2604     if (media == UX_NULL || media -> fx_media_id == 0)
2605     {
2606         printf("ERROR %d.%d: media error\n", __LINE__, __line__);
2607         test_control_return(1);
2608     }
2609 
2610     stepinfo(">>>>>>>>>>>> Disk read(%d) test - tick obtain\n", test_size);
2611     test_start = tx_time_get();
2612     status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
2613             buffer, 0, test_size);
2614     test_ticks = _test_dw_minus(tx_time_get(), test_start);
2615     if (status != UX_SUCCESS)
2616     {
2617         printf("ERROR %d.%d: 0x%x\n", __LINE__, __line__, status);
2618         test_control_return(1);
2619     }
2620     test_ticks /= 3;
2621     stepinfo(" :: Buffer XFR time: %ld ticks\n", test_ticks);
2622 
2623     stepinfo(">>>>>>>>>>>> Disk write/read(%d) test - slow disk write/read\n", test_size);
2624     ram_disk_rw_wait_delay = ((test_ticks + 1) >> 1) + 1;
2625     for(test_n = 0; test_n < 4; test_n ++)
2626     {
2627         stepinfo(">>>>>>>>>>>> Disk write/read(%d) test - disk write/read wait %ld\n",
2628                                             test_size, ram_disk_rw_wait_delay);
2629         for(i = 0; i < test_size * 512; i ++)
2630             buffer[i] = (UCHAR)(i + (i >> 8));
2631         ram_disk_rw_wait_start = tx_time_get();
2632         status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
2633                 buffer, 48, test_size);
2634         if (status != FX_SUCCESS)
2635         {
2636             printf("ERROR %d.%d.%d: 0x%x\n", __LINE__, __line__, test_n, status);
2637             test_control_return(1);
2638         }
2639         _ux_utility_memory_set(buffer, 0x00, test_size * 512);
2640         ram_disk_rw_wait_start = tx_time_get();
2641         status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
2642                 buffer, 48, test_size);
2643         if (status != FX_SUCCESS)
2644         {
2645             printf("ERROR %d.%d.%d: 0x%x\n", __LINE__, __line__, test_n, status);
2646             test_control_return(1);
2647         }
2648         for (i = 0; i < 512; i ++)
2649         {
2650             if (buffer[i] != (UCHAR)(i + (i >> 8)))
2651             {
2652                 printf("ERROR %d.%d.%d: %d <> %d\n", __LINE__, __line__, test_n, i, buffer[i]);
2653                 test_control_return(1);
2654             }
2655         }
2656         ram_disk_rw_wait_delay <<= 1;
2657     }
2658 
2659     stepinfo(">>>>>>>>>>>> Disk read(%d) test - USB fail while disk waiting\n", test_size);
2660     ram_disk_rw_wait_start = tx_time_get();
2661     ram_disk_rw_count = 0;
2662     ram_disk_rw_fail_mode = 0x81;
2663     ram_disk_rw_fail_after = 1;
2664     status = _media_driver_read(media, _ux_host_class_storage_driver_entry,
2665             buffer, 48, test_size);
2666     if (status == UX_SUCCESS)
2667     {
2668         printf("ERROR %d.%d: 0x%x\n", __LINE__, __line__, status);
2669         test_control_return(1);
2670     }
2671 
2672     stepinfo(">>>>>>>>>>>> Disk write(%d) test - USB fail while disk waiting\n", test_size);
2673     ram_disk_rw_wait_start = tx_time_get();
2674     ram_disk_rw_count = 0;
2675     ram_disk_rw_fail_mode = 0x82;
2676     ram_disk_rw_fail_after = 0;
2677     status = _media_driver_write(media, _ux_host_class_storage_driver_entry,
2678             buffer, 48, test_size);
2679     if (0 /*status == UX_SUCCESS*/)
2680     {
2681         printf("ERROR %d.%d: 0x%x\n", __LINE__, __line__, status);
2682         test_control_return(1);
2683     }
2684 
2685     /* Restore: no disk wait delay.  */
2686     ram_disk_rw_fail_after = 0xFFFFFFFF;
2687     ram_disk_rw_wait_delay = 0;
2688 }
2689 
2690 
tx_demo_thread_host_simulation_entry(ULONG arg)2691 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
2692 {
2693 
2694 UINT                                        status;
2695 
2696 
2697     /* Find the storage class. */
2698     status =  host_storage_instance_get(800);
2699     if (status != UX_SUCCESS)
2700     {
2701 
2702         printf("ERROR #%d\n", __LINE__);
2703         test_control_return(1);
2704     }
2705 
2706     stepinfo(">>>>>>>>>>>> MSC Basic test\n");
2707 
2708     _msc_media_read_test(__FILE__, __LINE__);
2709     _msc_enumeration_test(__FILE__, __LINE__, 3);
2710 #if 0 /* Moved to read write test.  */
2711     _msc_media_write_read_test(__FILE__, __LINE__);
2712     _msc_media_write_read_misc_test(__FILE__, __LINE__);
2713 #endif
2714 #if 0 /* Moved to CV test.  */
2715     stepinfo(">>>>>>>>>>>> MSC Error & CV cases test\n");
2716 
2717 #ifndef UX_STANDALONE
2718     /* Pause the class driver thread.  */
2719     _ux_utility_thread_suspend(&((UX_HOST_CLASS_STORAGE_EXT*)storage->ux_host_class_storage_class->ux_host_class_ext)->ux_host_class_thread);
2720 #endif
2721 
2722     _msc_cbw_fail_cases_test(__FILE__, __LINE__);
2723 
2724     _msc_get_max_lun_cases_test(__FILE__, __LINE__);
2725     _msc_inquiry_cases_test(__FILE__, __LINE__);
2726     _msc_read_cases_test(__FILE__, __LINE__);
2727     _msc_write_cases_test(__FILE__, __LINE__);
2728     _msc_request_sense_cases_test(__FILE__, __LINE__);
2729     _msc_test_ready_cases_test(__FILE__, __LINE__);
2730     _msc_format_unit_cases_test(__FILE__, __LINE__);
2731     _msc_start_stop_cases_test(__FILE__, __LINE__);
2732     _msc_verify_cases_test(__FILE__, __LINE__);
2733     _msc_mode_sense_cases_test(__FILE__, __LINE__);
2734     _msc_mode_select_cases_test(__FILE__, __LINE__);
2735     _msc_synchronous_cache_cases_test(__FILE__, __LINE__);
2736     _msc_prevent_allow_removal_cases_test(__FILE__, __LINE__);
2737 
2738 #ifndef UX_STANDALONE
2739     /* Resume the class driver thread.  */
2740     _ux_utility_thread_resume(&((UX_HOST_CLASS_STORAGE_EXT*)storage->ux_host_class_storage_class->ux_host_class_ext)->ux_host_class_thread);
2741 #endif
2742 #endif
2743 
2744     /* Finally disconnect the device. */
2745     ux_device_stack_disconnect();
2746 
2747     /* And deinitialize the class.  */
2748     status =  ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
2749 
2750     /* Deinitialize the device side of usbx.  */
2751     _ux_device_stack_uninitialize();
2752 
2753     /* And finally the usbx system resources.  */
2754     _ux_system_uninitialize();
2755 
2756     /* Successful test.  */
2757     printf("SUCCESS!\n");
2758     test_control_return(0);
2759 }
2760 
2761 
demo_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)2762 static UINT    demo_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
2763 {
2764 
2765 static UCHAR lun_init_done[2] = {0, 0};
2766 UINT         status;
2767 ULONG        mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE;
2768 
2769 
2770     (void)storage;
2771     (void)media_id;
2772 
2773     if (ram_disk_status)
2774     {
2775         status = ram_disk_status;
2776         if (media_status)
2777             *media_status = ram_disk_media_status;
2778         ram_disk_status = UX_SUCCESS;
2779         ram_disk_status_sent = UX_TRUE;
2780         return(status);
2781     }
2782 
2783     if (lun > 1)
2784         status = (UX_ERROR);
2785     else if (lun_init_done[lun] > 0)
2786         status = (UX_SUCCESS);
2787     else
2788     {
2789         lun_init_done[lun] ++;
2790         mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
2791         status = (UX_ERROR);
2792     }
2793 
2794     if (media_status)
2795         *media_status = mstatus;
2796 
2797     return status;
2798 }
2799 
demo_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)2800 static UINT    demo_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
2801 {
2802 
2803 UINT    status =  0;
2804 
2805     /* Abort.  */
2806     if (data_pointer == UX_NULL)
2807     {
2808         ram_disk_rw_wait_state = 0;
2809         return(UX_STATE_NEXT);
2810     }
2811 
2812     /* Media RW fail simulation.  */
2813     if (ram_disk_rw_fail_after < 0xFFFFFFFF)
2814     {
2815         ram_disk_rw_count ++;
2816         if (ram_disk_rw_count >= ram_disk_rw_fail_after)
2817         {
2818             if (ram_disk_rw_fail_mode_one_shot())
2819             {
2820                 ram_disk_rw_fail_after = 0xFFFFFFFF;
2821                 ram_disk_rw_count = 0;
2822             }
2823             if (ram_disk_rw_fail_mode_bulk_in())
2824                 ux_test_dcd_sim_slave_set_actions(fail_on_bulkin);
2825             else if (ram_disk_rw_fail_mode_bulk_out())
2826                 ux_test_dcd_sim_slave_set_actions(fail_on_bulkout);
2827             else if (ram_disk_rw_fail_mode_disk())
2828             {
2829                 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2830                 return(UX_STATE_ERROR);
2831             }
2832         }
2833     }
2834 
2835     /* Media RW wait simulation.  */
2836     if (ram_disk_rw_wait_delay)
2837     {
2838         if (_test_dw_minus(tx_time_get(), ram_disk_rw_wait_start) < ram_disk_rw_wait_delay)
2839         {
2840             ram_disk_rw_wait_state = 1;
2841             return(UX_STATE_WAIT);
2842         }
2843         ram_disk_rw_wait_state = 0;
2844         ram_disk_rw_wait_start = tx_time_get();
2845     }
2846 
2847     status = _media_driver_read(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
2848     if (status != UX_SUCCESS)
2849     {
2850         *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2851         return(UX_STATE_ERROR);
2852     }
2853     return(UX_STATE_NEXT);
2854 }
2855 
demo_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)2856 static UINT    demo_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
2857 {
2858 
2859 UINT    status =  0;
2860 
2861     /* Abort.  */
2862     if (data_pointer == UX_NULL)
2863     {
2864         ram_disk_rw_wait_state = 0;
2865         return(UX_STATE_NEXT);
2866     }
2867 
2868     /* Media RW fail simulation.  */
2869     if (ram_disk_rw_fail_after < 0xFFFFFFFF)
2870     {
2871         ram_disk_rw_count ++;
2872         if (ram_disk_rw_count >= ram_disk_rw_fail_after)
2873         {
2874             if (ram_disk_rw_fail_mode_one_shot())
2875             {
2876                 ram_disk_rw_fail_after = 0xFFFFFFFF;
2877                 ram_disk_rw_count = 0;
2878             }
2879             if (ram_disk_rw_fail_mode_bulk_in())
2880                 ux_test_dcd_sim_slave_set_actions(fail_on_bulkin);
2881             else if (ram_disk_rw_fail_mode_bulk_out())
2882                 ux_test_dcd_sim_slave_set_actions(fail_on_bulkout);
2883             else if (ram_disk_rw_fail_mode_disk())
2884             {
2885                 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2886                 return(UX_STATE_ERROR);
2887             }
2888         }
2889     }
2890     /* Media RW wait simulation.  */
2891     if (ram_disk_rw_wait_delay)
2892     {
2893         if (_test_dw_minus(tx_time_get(), ram_disk_rw_wait_start) < ram_disk_rw_wait_delay)
2894         {
2895             ram_disk_rw_wait_state = 1;
2896             return(UX_STATE_WAIT);
2897         }
2898         ram_disk_rw_wait_state = 0;
2899         ram_disk_rw_wait_start = tx_time_get();
2900     }
2901 
2902     status = _media_driver_write(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
2903     if (status != UX_SUCCESS)
2904     {
2905         *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2906         return(UX_STATE_ERROR);
2907     }
2908     return(UX_STATE_NEXT);
2909 }
2910 
demo_media_flush(VOID * storage,ULONG lun,ULONG number_blocks,ULONG lba,ULONG * media_status)2911 static UINT    demo_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status)
2912 {
2913     (void)storage;
2914     (void)number_blocks;
2915     (void)lba;
2916     (void)media_status;
2917 
2918     if (lun > 1)
2919         return UX_STATE_ERROR;
2920 
2921     ram_disk_flush = UX_TRUE;
2922     return ram_disk_flush_status;
2923 }
2924 
ux_test_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)2925 static UINT ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
2926 {
2927 
2928     switch(event)
2929     {
2930 
2931         case UX_DEVICE_INSERTION:
2932             break;
2933 
2934         case UX_DEVICE_REMOVAL:
2935             break;
2936 
2937 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
2938         case UX_STORAGE_MEDIA_INSERTION:
2939             /* keep using first media.  */
2940             if (_ux_host_class_storage_media_index((UX_HOST_CLASS_STORAGE_MEDIA*)inst) == 0)
2941             {
2942                 _ux_host_class_storage_media_insert((UX_HOST_CLASS_STORAGE_MEDIA*)inst, 1);
2943                 storage_media = (UX_HOST_CLASS_STORAGE_MEDIA*)inst;
2944                 media = _ux_host_class_storage_media_fx_media((UX_HOST_CLASS_STORAGE_MEDIA*)inst);
2945             }
2946             break;
2947 
2948         case UX_STORAGE_MEDIA_REMOVAL:
2949             if (_ux_host_class_storage_media_index((UX_HOST_CLASS_STORAGE_MEDIA*)inst) == 0)
2950             {
2951                 _ux_host_class_storage_media_remove((UX_HOST_CLASS_STORAGE_MEDIA*)inst);
2952                 storage_media = UX_NULL;
2953                 media = UX_NULL;
2954             }
2955             break;
2956 #endif
2957 
2958         default:
2959             break;
2960     }
2961 
2962     return 0;
2963 }
2964 
2965