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_standalone_device_storage_error_cv_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 ERROR & CV 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 printf(">>>>>>>>>>>>>>> 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 Error & CV cases test\n");
2707
2708 #ifndef UX_STANDALONE
2709 /* Pause the class driver thread. */
2710 _ux_utility_thread_suspend(&((UX_HOST_CLASS_STORAGE_EXT*)storage->ux_host_class_storage_class->ux_host_class_ext)->ux_host_class_thread);
2711 #endif
2712
2713 /* All tests are on LUN 0. */
2714 storage->ux_host_class_storage_lun = 0;
2715
2716 _msc_cbw_fail_cases_test(__FILE__, __LINE__);
2717
2718 _msc_get_max_lun_cases_test(__FILE__, __LINE__);
2719 _msc_inquiry_cases_test(__FILE__, __LINE__);
2720 _msc_read_cases_test(__FILE__, __LINE__);
2721 _msc_write_cases_test(__FILE__, __LINE__);
2722 _msc_request_sense_cases_test(__FILE__, __LINE__);
2723 _msc_test_ready_cases_test(__FILE__, __LINE__);
2724 _msc_format_unit_cases_test(__FILE__, __LINE__);
2725 _msc_start_stop_cases_test(__FILE__, __LINE__);
2726 _msc_verify_cases_test(__FILE__, __LINE__);
2727 _msc_mode_sense_cases_test(__FILE__, __LINE__);
2728 _msc_mode_select_cases_test(__FILE__, __LINE__);
2729 _msc_synchronous_cache_cases_test(__FILE__, __LINE__);
2730 _msc_prevent_allow_removal_cases_test(__FILE__, __LINE__);
2731
2732 #ifndef UX_STANDALONE
2733 /* Resume the class driver thread. */
2734 _ux_utility_thread_resume(&((UX_HOST_CLASS_STORAGE_EXT*)storage->ux_host_class_storage_class->ux_host_class_ext)->ux_host_class_thread);
2735 #endif
2736
2737 /* Finally disconnect the device. */
2738 ux_device_stack_disconnect();
2739
2740 /* And deinitialize the class. */
2741 status = ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
2742
2743 /* Deinitialize the device side of usbx. */
2744 _ux_device_stack_uninitialize();
2745
2746 /* And finally the usbx system resources. */
2747 _ux_system_uninitialize();
2748
2749 /* Successful test. */
2750 printf("SUCCESS!\n");
2751 test_control_return(0);
2752 }
2753
2754
demo_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)2755 static UINT demo_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
2756 {
2757
2758 static UCHAR lun_init_done[2] = {0, 0};
2759 UINT status;
2760 ULONG mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE;
2761
2762
2763 (void)storage;
2764 (void)media_id;
2765
2766 if (ram_disk_status)
2767 {
2768 status = ram_disk_status;
2769 if (media_status)
2770 *media_status = ram_disk_media_status;
2771 ram_disk_status = UX_SUCCESS;
2772 ram_disk_status_sent = UX_TRUE;
2773 return(status);
2774 }
2775
2776 if (lun > 1)
2777 status = (UX_ERROR);
2778 else if (lun_init_done[lun] > 0)
2779 status = (UX_SUCCESS);
2780 else
2781 {
2782 lun_init_done[lun] ++;
2783 mstatus = UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8);
2784 status = (UX_ERROR);
2785 }
2786
2787 if (media_status)
2788 *media_status = mstatus;
2789
2790 return status;
2791 }
2792
demo_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)2793 static UINT demo_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
2794 {
2795
2796 UINT status = 0;
2797
2798 /* Abort. */
2799 if (data_pointer == UX_NULL)
2800 {
2801 ram_disk_rw_wait_state = 0;
2802 return(UX_STATE_NEXT);
2803 }
2804
2805 /* Media RW fail simulation. */
2806 if (ram_disk_rw_fail_after < 0xFFFFFFFF)
2807 {
2808 ram_disk_rw_count ++;
2809 if (ram_disk_rw_count >= ram_disk_rw_fail_after)
2810 {
2811 if (ram_disk_rw_fail_mode_one_shot())
2812 {
2813 ram_disk_rw_fail_after = 0xFFFFFFFF;
2814 ram_disk_rw_count = 0;
2815 }
2816 if (ram_disk_rw_fail_mode_bulk_in())
2817 ux_test_dcd_sim_slave_set_actions(fail_on_bulkin);
2818 else if (ram_disk_rw_fail_mode_bulk_out())
2819 ux_test_dcd_sim_slave_set_actions(fail_on_bulkout);
2820 else if (ram_disk_rw_fail_mode_disk())
2821 {
2822 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2823 return(UX_STATE_ERROR);
2824 }
2825 }
2826 }
2827
2828 /* Media RW wait simulation. */
2829 if (ram_disk_rw_wait_delay)
2830 {
2831 if (_test_dw_minus(tx_time_get(), ram_disk_rw_wait_start) < ram_disk_rw_wait_delay)
2832 {
2833 ram_disk_rw_wait_state = 1;
2834 return(UX_STATE_WAIT);
2835 }
2836 ram_disk_rw_wait_state = 0;
2837 ram_disk_rw_wait_start = tx_time_get();
2838 }
2839
2840 status = _media_driver_read(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
2841 if (status != UX_SUCCESS)
2842 {
2843 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2844 return(UX_STATE_ERROR);
2845 }
2846 return(UX_STATE_NEXT);
2847 }
2848
demo_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)2849 static UINT demo_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
2850 {
2851
2852 UINT status = 0;
2853
2854 /* Abort. */
2855 if (data_pointer == UX_NULL)
2856 {
2857 ram_disk_rw_wait_state = 0;
2858 return(UX_STATE_NEXT);
2859 }
2860
2861 /* Media RW fail simulation. */
2862 if (ram_disk_rw_fail_after < 0xFFFFFFFF)
2863 {
2864 ram_disk_rw_count ++;
2865 if (ram_disk_rw_count >= ram_disk_rw_fail_after)
2866 {
2867 if (ram_disk_rw_fail_mode_one_shot())
2868 {
2869 ram_disk_rw_fail_after = 0xFFFFFFFF;
2870 ram_disk_rw_count = 0;
2871 }
2872 if (ram_disk_rw_fail_mode_bulk_in())
2873 ux_test_dcd_sim_slave_set_actions(fail_on_bulkin);
2874 else if (ram_disk_rw_fail_mode_bulk_out())
2875 ux_test_dcd_sim_slave_set_actions(fail_on_bulkout);
2876 else if (ram_disk_rw_fail_mode_disk())
2877 {
2878 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2879 return(UX_STATE_ERROR);
2880 }
2881 }
2882 }
2883 /* Media RW wait simulation. */
2884 if (ram_disk_rw_wait_delay)
2885 {
2886 if (_test_dw_minus(tx_time_get(), ram_disk_rw_wait_start) < ram_disk_rw_wait_delay)
2887 {
2888 ram_disk_rw_wait_state = 1;
2889 return(UX_STATE_WAIT);
2890 }
2891 ram_disk_rw_wait_state = 0;
2892 ram_disk_rw_wait_start = tx_time_get();
2893 }
2894
2895 status = _media_driver_write(ram_disks[lun], _fx_ram_driver, data_pointer, lba, number_blocks);
2896 if (status != UX_SUCCESS)
2897 {
2898 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(0x02,0x54,0x00);
2899 return(UX_STATE_ERROR);
2900 }
2901 return(UX_STATE_NEXT);
2902 }
2903
demo_media_flush(VOID * storage,ULONG lun,ULONG number_blocks,ULONG lba,ULONG * media_status)2904 static UINT demo_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status)
2905 {
2906 (void)storage;
2907 (void)number_blocks;
2908 (void)lba;
2909 (void)media_status;
2910
2911 if (lun > 1)
2912 return UX_STATE_ERROR;
2913
2914 ram_disk_flush = UX_TRUE;
2915 return ram_disk_flush_status;
2916 }
2917
ux_test_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)2918 static UINT ux_test_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
2919 {
2920
2921 switch(event)
2922 {
2923
2924 case UX_DEVICE_INSERTION:
2925 break;
2926
2927 case UX_DEVICE_REMOVAL:
2928 break;
2929
2930 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
2931 case UX_STORAGE_MEDIA_INSERTION:
2932 /* keep using first media. */
2933 if (_ux_host_class_storage_media_index((UX_HOST_CLASS_STORAGE_MEDIA*)inst) == 0)
2934 {
2935 _ux_host_class_storage_media_insert((UX_HOST_CLASS_STORAGE_MEDIA*)inst, 1);
2936 storage_media = (UX_HOST_CLASS_STORAGE_MEDIA*)inst;
2937 media = _ux_host_class_storage_media_fx_media((UX_HOST_CLASS_STORAGE_MEDIA*)inst);
2938 }
2939 break;
2940
2941 case UX_STORAGE_MEDIA_REMOVAL:
2942 if (_ux_host_class_storage_media_index((UX_HOST_CLASS_STORAGE_MEDIA*)inst) == 0)
2943 {
2944 _ux_host_class_storage_media_remove((UX_HOST_CLASS_STORAGE_MEDIA*)inst);
2945 storage_media = UX_NULL;
2946 media = UX_NULL;
2947 }
2948 break;
2949 #endif
2950
2951 default:
2952 break;
2953 }
2954
2955 return 0;
2956 }
2957
2958