1 #include <stdio.h>
2 #include "tx_api.h"
3 #include "ux_api.h"
4 #include "ux_system.h"
5 #include "ux_utility.h"
6 #include "ux_device_stack.h"
7 #include "ux_host_class_hub.h"
8 #include "ux_test_dcd_sim_slave.h"
9 #include "ux_test_hcd_sim_host.h"
10 #include "ux_test_utility_sim.h"
11 #include "ux_test.h"
12 #include "ux_test_actions.h"
13 #include "ux_device_class_dummy_hub.h"
14 #include "ux_dcd_sim_slave.h"
15 #include "usbx_ux_test_hub.h"
16
17 static ULONG set_addr_counter;
18
19 static ULONG rsc_mem_alloc_cnt_on_set_addr;
20 static ULONG rsc_sem_on_set_addr;
21 static ULONG rsc_sem_get_on_set_addr;
22 static ULONG rsc_mutex_on_set_addr;
23
24 static ULONG rsc_enum_sem_usage;
25 static ULONG rsc_enum_sem_get_count;
26 static ULONG rsc_enum_mutex_usage;
27 static ULONG rsc_enum_mem_alloc_count;
28
29 static ULONG rsc_cdc_sem_usage;
30 static ULONG rsc_cdc_sem_get_count;
31 static ULONG rsc_cdc_mutex_usage;
32 static ULONG rsc_cdc_mem_alloc_count;
33
34 static ULONG error_callback_counter;
35
36 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
ux_test_hcd_entry_set_addr(UX_TEST_ACTION * action,VOID * _params)37 static VOID ux_test_hcd_entry_set_addr(UX_TEST_ACTION *action, VOID *_params)
38 {
39
40 set_addr_counter ++;
41
42 rsc_mem_alloc_cnt_on_set_addr = ux_test_utility_sim_mem_alloc_count();
43
44 rsc_sem_on_set_addr = ux_test_utility_sim_sem_create_count();
45 rsc_sem_get_on_set_addr = ux_test_utility_sim_sem_get_count();
46 rsc_mutex_on_set_addr = ux_test_utility_sim_mutex_create_count();
47 }
48 static UX_TEST_HCD_SIM_ACTION log_on_SetAddr[] = {
49 { .function = UX_HCD_TRANSFER_REQUEST,
50 .req_setup = &_SetAddress,
51 .req_action = UX_TEST_SETUP_MATCH_REQ,
52 .action_func = ux_test_hcd_entry_set_addr,
53 .no_return = UX_TRUE
54 }, /* Invoke callback & continue */
55 { 0 }
56 };
57
count_error_callback(struct UX_TEST_ACTION_STRUCT * action,VOID * params)58 static void count_error_callback(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
59 {
60 UX_TEST_ERROR_CALLBACK_PARAMS *error = (UX_TEST_ERROR_CALLBACK_PARAMS *)params;
61
62 // printf("error trap: 0x%x, 0x%x, 0x%x\n", error->system_level, error->system_context, error->error_code);
63 error_callback_counter ++;
64 }
65
66 static UX_TEST_HCD_SIM_ACTION count_on_error_trap[] = {
67 { .usbx_function = UX_TEST_OVERRIDE_ERROR_CALLBACK,
68 .action_func = count_error_callback,
69 },
70 { 0 }
71 };
72
sleep_break_on_error(VOID)73 static UINT sleep_break_on_error(VOID)
74 {
75
76 if (error_callback_counter >= 3)
77 return error_callback_counter;
78
79 return UX_SUCCESS;
80 }
81
82 /* Define what the initial system looks like. */
83
84 #ifdef CTEST
test_application_define(void * first_unused_memory)85 void test_application_define(void *first_unused_memory)
86 #else
87 void usbx_hub_basic_memory_test_application_define(void *first_unused_memory)
88 #endif
89 {
90
91 CHAR *memory_pointer = first_unused_memory;
92
93 /* Inform user. */
94 printf("Running Hub Basic Memory Functionality Test......................... ");
95
96 stepinfo("\n");
97
98 /* Override error trap. */
99 ux_test_link_hooks_from_array(count_on_error_trap);
100
101 /* Reset testing counts. */
102 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
103 ux_test_utility_sim_mem_alloc_count_reset();
104 ux_test_utility_sim_mutex_create_count_reset();
105 ux_test_utility_sim_sem_create_count_reset();
106 ux_test_utility_sim_sem_get_count_reset();
107 /* Reset error generations */
108 ux_test_utility_sim_sem_error_generation_stop();
109 ux_test_utility_sim_mutex_error_generation_stop();
110 ux_test_utility_sim_sem_get_error_generation_stop();
111
112 initialize_hub(first_unused_memory);
113 }
114
post_init_host()115 static void post_init_host()
116 {
117
118 ULONG mem_free;
119 ULONG test_n;
120
121 /* Test disconnect. */
122 stepinfo(">>>>>>>>>>>>>>>>>>> Test disconnect\n");
123 ux_test_disconnect_slave();
124 ux_test_disconnect_host_wait_for_enum_completion();
125
126 /* Reset testing counts. */
127 ux_test_utility_sim_mem_alloc_count_reset();
128 ux_test_utility_sim_mutex_create_count_reset();
129 ux_test_utility_sim_sem_create_count_reset();
130 ux_test_utility_sim_sem_get_count_reset();
131 ux_test_hcd_sim_host_set_actions(log_on_SetAddr);
132
133 /* Save free memory usage. */
134 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
135
136 stepinfo(">>>>>>>>>>>>>>>>>>> Test connect\n");
137 /* Connect. */
138 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
139 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
140 class_hub_get();
141
142 /* Log create counts for further tests. */
143 rsc_enum_mutex_usage = rsc_mutex_on_set_addr;
144 rsc_enum_sem_usage = rsc_sem_on_set_addr;
145 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_addr;
146 /* Log create counts when instances active for further tests. */
147 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
148 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
149 rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
150
151 /* Lock log base for tests. */
152 ux_test_utility_sim_mem_alloc_log_lock();
153
154 /* Simulate detach and attach for FS enumeration,
155 and check if there is memory error in normal enumeration.
156 */
157 stepinfo(">>>>>>>>>>>>>>>>>>> Enumeration test\n");
158 mem_free = (~0);
159 for (test_n = 0; test_n < 3; test_n++)
160 {
161 stepinfo("%4ld / 2\n", test_n);
162
163 /* Disconnect. */
164 ux_test_dcd_sim_slave_disconnect();
165 ux_test_hcd_sim_host_disconnect();
166
167 /* Update memory free level (disconnect) */
168 if (mem_free == (~0))
169 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
170 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
171 {
172
173 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);
174 test_control_return(1);
175 }
176
177 /* Connect. */
178 error_callback_counter = 0;
179 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
180 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
181
182 /* Wait and break on error. */
183 ux_test_breakable_sleep(200, sleep_break_on_error);
184
185 /* Check */
186 if (g_hub_host_from_system_change_function == UX_NULL)
187 {
188
189 printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
190 test_control_return(1);
191 }
192 }
193
194 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
195 stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
196 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);
197
198 /* Simulate detach and attach for FS enumeration,
199 and test possible memory allocation error handlings.
200 */
201 if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors enumeration test\n");
202 mem_free = (~0);
203 for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
204 {
205
206 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
207
208 /* Disconnect. */
209 ux_test_dcd_sim_slave_disconnect();
210 ux_test_hcd_sim_host_disconnect();
211
212 /* Update memory free level (disconnect) */
213 if (mem_free == (~0))
214 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
215 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
216 {
217
218 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);
219 test_control_return(1);
220 }
221
222 /* Set memory error generation */
223 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
224
225 /* Connect. */
226 error_callback_counter = 0;
227 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
228 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
229
230 /* Wait and break on errors. */
231 ux_test_breakable_sleep(200, sleep_break_on_error);
232
233 /* Check error */
234 if (g_hub_host_from_system_change_function != UX_NULL)
235 {
236
237 printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
238 test_control_return(1);
239 }
240 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
241 }
242 ux_test_utility_sim_mem_alloc_error_generation_stop();
243 if (rsc_cdc_mem_alloc_count) stepinfo("\n");
244 }
245
post_init_device(ULONG input)246 static void post_init_device(ULONG input)
247 {
248 }