Changeset 8393c73b in mainline for uspace/drv/bus/usb/usbdiag/tests.c
- Timestamp:
- 2018-02-01T16:10:12Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3b5a5e3
- Parents:
- 24c41ba1
- git-author:
- Petr Manek <petr.manek@…> (2018-02-01 16:09:15)
- git-committer:
- Petr Manek <petr.manek@…> (2018-02-01 16:10:12)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbdiag/tests.c
r24c41ba1 r8393c73b 44 44 #define NAME "usbdiag" 45 45 46 static int burst_in_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 46 static const uint32_t test_data_src = 0xDEADBEEF; 47 48 static int test_in(usb_pipe_t *pipe, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 47 49 { 48 50 if (!pipe) 49 51 return EBADMEM; 52 53 bool validate = params->validate_data; 54 size_t size = params->transfer_size; 55 if (!size) 56 size = pipe->desc.max_transfer_size; 57 58 const uint32_t test_data = uint32_host2usb(test_data_src); 59 if (validate && size % sizeof(test_data)) 60 return EINVAL; 50 61 51 62 char *buffer = (char *) malloc(size); … … 55 66 // TODO: Are we sure that no other test is running on this endpoint? 56 67 57 usb_log_info("Performing %s IN burst test.", usb_str_transfer_type(pipe->desc.transfer_type));68 usb_log_info("Performing %s IN test with duration %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), params->min_duration); 58 69 59 70 int rc = EOK; 60 struct timeval start_time; 71 uint32_t transfer_count = 0; 72 73 struct timeval start_time, final_time, stop_time; 61 74 gettimeofday(&start_time, NULL); 62 63 for (int i = 0; i < cycles; ++i) { 75 gettimeofday(&stop_time, NULL); 76 77 tv_add_diff(&stop_time, params->min_duration * 1000); 78 gettimeofday(&final_time, NULL); 79 80 while (!tv_gt(&final_time, &stop_time)) { 81 ++transfer_count; 82 64 83 // Read device's response. 65 84 size_t remaining = size; … … 83 102 if (rc) 84 103 break; 85 } 86 87 struct timeval final_time; 88 gettimeofday(&final_time, NULL); 104 105 if (validate) { 106 for (size_t i = 0; i < size; i += sizeof(test_data)) { 107 if (*(uint32_t *)(buffer + i) != test_data) { 108 usb_log_error("Read of %s IN endpoint returned " 109 "invald data at address %zu.", 110 usb_str_transfer_type(pipe->desc.transfer_type), i); 111 rc = EINVAL; 112 break; 113 } 114 } 115 116 if (rc) 117 break; 118 } 119 120 gettimeofday(&final_time, NULL); 121 } 122 89 123 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 90 124 ((final_time.tv_sec - start_time.tv_sec) * 1000); 91 125 92 usb_log_info("Burst test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 126 usb_log_info("Test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 127 128 results->act_duration = in_duration; 129 results->transfer_count = transfer_count; 130 results->transfer_size = size; 93 131 94 132 free(buffer); 95 if (duration)96 *duration = in_duration;97 133 98 134 return rc; 99 135 } 100 136 101 static int burst_out_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration)137 static int test_out(usb_pipe_t *pipe, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 102 138 { 103 139 if (!pipe) 104 140 return EBADMEM; 141 142 bool validate = params->validate_data; 143 size_t size = params->transfer_size; 144 if (!size) 145 size = pipe->desc.max_transfer_size; 146 147 const uint32_t test_data = uint32_host2usb(test_data_src); 148 149 if (validate && size % sizeof(test_data)) 150 return EINVAL; 105 151 106 152 char *buffer = (char *) malloc(size); … … 108 154 return ENOMEM; 109 155 110 memset(buffer, 42, size); 156 if (validate) { 157 for (size_t i = 0; i < size; i += sizeof(test_data)) { 158 memcpy(buffer + i, &test_data, sizeof(test_data)); 159 } 160 } 111 161 112 162 // TODO: Are we sure that no other test is running on this endpoint? 113 163 114 usb_log_info("Performing %s OUT bursttest.", usb_str_transfer_type(pipe->desc.transfer_type));164 usb_log_info("Performing %s OUT test.", usb_str_transfer_type(pipe->desc.transfer_type)); 115 165 116 166 int rc = EOK; 117 struct timeval start_time; 167 uint32_t transfer_count = 0; 168 169 struct timeval start_time, final_time, stop_time; 118 170 gettimeofday(&start_time, NULL); 119 120 for (int i = 0; i < cycles; ++i) { 171 gettimeofday(&stop_time, NULL); 172 173 tv_add_diff(&stop_time, params->min_duration * 1000); 174 gettimeofday(&final_time, NULL); 175 176 while (!tv_gt(&final_time, &stop_time)) { 177 ++transfer_count; 178 121 179 // Write buffer to device. 122 180 if ((rc = usb_pipe_write(pipe, buffer, size))) { … … 124 182 break; 125 183 } 126 } 127 128 struct timeval final_time;129 gettimeofday(&final_time, NULL); 184 185 gettimeofday(&final_time, NULL); 186 } 187 130 188 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 131 189 ((final_time.tv_sec - start_time.tv_sec) * 1000); 132 190 133 usb_log_info("Burst test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 191 usb_log_info("Test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 192 193 results->act_duration = in_duration; 194 results->transfer_count = transfer_count; 195 results->transfer_size = size; 134 196 135 197 free(buffer); 136 if (duration)137 *duration = in_duration;138 198 139 199 return rc; 140 200 } 141 201 142 static const uint32_t test_data_src = 0xDEADBEEF; 143 144 static int data_in_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 145 { 146 if (!pipe) 147 return EBADMEM; 148 149 const uint32_t test_data = uint32_host2usb(test_data_src); 150 151 if (size % sizeof(test_data)) 152 return EINVAL; 153 154 char *buffer = (char *) malloc(size); 155 if (!buffer) 156 return ENOMEM; 157 158 // TODO: Are we sure that no other test is running on this endpoint? 159 160 usb_log_info("Performing %s IN data test.", usb_str_transfer_type(pipe->desc.transfer_type)); 161 162 int rc = EOK; 163 struct timeval start_time; 164 gettimeofday(&start_time, NULL); 165 166 for (int i = 0; i < cycles; ++i) { 167 // Read device's response. 168 size_t remaining = size; 169 size_t transferred; 170 171 while (remaining > 0) { 172 if ((rc = usb_pipe_read(pipe, buffer + size - remaining, remaining, &transferred))) { 173 usb_log_error("Read of %s IN endpoint failed with error: %s", usb_str_transfer_type(pipe->desc.transfer_type), str_error(rc)); 174 break; 175 } 176 177 if (transferred > remaining) { 178 usb_log_error("Read of %s IN endpoint returned more data than expected.", usb_str_transfer_type(pipe->desc.transfer_type)); 179 rc = EINVAL; 180 break; 181 } 182 183 remaining -= transferred; 184 } 185 186 if (rc) 187 break; 188 189 for (size_t i = 0; i < size; i += sizeof(test_data)) { 190 if (*(uint32_t *)(buffer + i) != test_data) { 191 usb_log_error("Read of %s IN endpoint returned " 192 "invald data at address %zu.", 193 usb_str_transfer_type(pipe->desc.transfer_type), i); 194 rc = EINVAL; 195 break; 196 } 197 } 198 199 if (rc) 200 break; 201 } 202 203 struct timeval final_time; 204 gettimeofday(&final_time, NULL); 205 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 206 ((final_time.tv_sec - start_time.tv_sec) * 1000); 207 208 usb_log_info("Data test on %s IN endpoint completed in %lu ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 209 210 free(buffer); 211 if (duration) 212 *duration = in_duration; 213 214 return rc; 215 } 216 217 static int data_out_test(usb_pipe_t *pipe, int cycles, size_t size, usbdiag_dur_t *duration) 218 { 219 if (!pipe) 220 return EBADMEM; 221 222 const uint32_t test_data = uint32_host2usb(test_data_src); 223 224 if (size % sizeof(test_data)) 225 return EINVAL; 226 227 char *buffer = (char *) malloc(size); 228 if (!buffer) 229 return ENOMEM; 230 231 for (size_t i = 0; i < size; i += sizeof(test_data)) { 232 memcpy(buffer + i, &test_data, sizeof(test_data)); 233 } 234 235 // TODO: Are we sure that no other test is running on this endpoint? 236 237 usb_log_info("Performing %s OUT data test.", usb_str_transfer_type(pipe->desc.transfer_type)); 238 239 int rc = EOK; 240 struct timeval start_time; 241 gettimeofday(&start_time, NULL); 242 243 for (int i = 0; i < cycles; ++i) { 244 // Write buffer to device. 245 if ((rc = usb_pipe_write(pipe, buffer, size))) { 246 usb_log_error("Write to %s OUT endpoint failed with error: %s", usb_str_transfer_type(pipe->desc.transfer_type), str_error(rc)); 247 break; 248 } 249 } 250 251 struct timeval final_time; 252 gettimeofday(&final_time, NULL); 253 usbdiag_dur_t in_duration = ((final_time.tv_usec - start_time.tv_usec) / 1000) + 254 ((final_time.tv_sec - start_time.tv_sec) * 1000); 255 256 usb_log_info("Data test on %s OUT endpoint completed in %ld ms.", usb_str_transfer_type(pipe->desc.transfer_type), in_duration); 257 258 free(buffer); 259 if (duration) 260 *duration = in_duration; 261 262 return rc; 263 } 264 265 int usbdiag_burst_test_intr_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 202 int usbdiag_dev_test_in(ddf_fun_t *fun, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 266 203 { 267 204 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); … … 269 206 return EBADMEM; 270 207 271 return burst_in_test(dev->intr_in, cycles, size, duration); 272 } 273 274 int usbdiag_burst_test_intr_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 208 usb_pipe_t *pipe; 209 210 switch (params->transfer_type) { 211 case USB_TRANSFER_INTERRUPT: 212 pipe = params->validate_data ? dev->data_intr_in : dev->burst_intr_in; 213 break; 214 case USB_TRANSFER_BULK: 215 pipe = params->validate_data ? dev->data_bulk_in : dev->burst_bulk_in; 216 break; 217 case USB_TRANSFER_ISOCHRONOUS: 218 pipe = params->validate_data ? dev->data_isoch_in : dev->burst_isoch_in; 219 break; 220 default: 221 return ENOTSUP; 222 } 223 224 return test_in(pipe, params, results); 225 } 226 227 int usbdiag_dev_test_out(ddf_fun_t *fun, const usbdiag_test_params_t *params, usbdiag_test_results_t *results) 275 228 { 276 229 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); … … 278 231 return EBADMEM; 279 232 280 return burst_out_test(dev->intr_out, cycles, size, duration); 281 } 282 283 int usbdiag_burst_test_bulk_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 284 { 285 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 286 if (!dev) 287 return EBADMEM; 288 289 return burst_in_test(dev->bulk_in, cycles, size, duration); 290 } 291 292 int usbdiag_burst_test_bulk_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 293 { 294 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 295 if (!dev) 296 return EBADMEM; 297 298 return burst_out_test(dev->bulk_out, cycles, size, duration); 299 } 300 301 int usbdiag_burst_test_isoch_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 302 { 303 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 304 if (!dev) 305 return EBADMEM; 306 307 return burst_in_test(dev->isoch_in, cycles, size, duration); 308 } 309 310 int usbdiag_burst_test_isoch_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 311 { 312 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 313 if (!dev) 314 return EBADMEM; 315 316 return burst_out_test(dev->isoch_out, cycles, size, duration); 317 } 318 319 int usbdiag_data_test_intr_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 320 { 321 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 322 if (!dev) 323 return EBADMEM; 324 325 return data_in_test(dev->intr_in, cycles, size, duration); 326 } 327 328 int usbdiag_data_test_intr_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 329 { 330 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 331 if (!dev) 332 return EBADMEM; 333 334 return data_out_test(dev->intr_out, cycles, size, duration); 335 } 336 337 int usbdiag_data_test_bulk_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 338 { 339 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 340 if (!dev) 341 return EBADMEM; 342 343 return data_in_test(dev->bulk_in, cycles, size, duration); 344 } 345 346 int usbdiag_data_test_bulk_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 347 { 348 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 349 if (!dev) 350 return EBADMEM; 351 352 return data_out_test(dev->bulk_out, cycles, size, duration); 353 } 354 355 int usbdiag_data_test_isoch_in(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 356 { 357 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 358 if (!dev) 359 return EBADMEM; 360 361 return data_in_test(dev->isoch_in, cycles, size, duration); 362 } 363 364 int usbdiag_data_test_isoch_out(ddf_fun_t *fun, int cycles, size_t size, usbdiag_dur_t *duration) 365 { 366 usbdiag_dev_t *dev = ddf_fun_to_usbdiag_dev(fun); 367 if (!dev) 368 return EBADMEM; 369 370 return data_out_test(dev->isoch_out, cycles, size, duration); 233 usb_pipe_t *pipe; 234 235 switch (params->transfer_type) { 236 case USB_TRANSFER_INTERRUPT: 237 pipe = params->validate_data ? dev->data_intr_out : dev->burst_intr_out; 238 break; 239 case USB_TRANSFER_BULK: 240 pipe = params->validate_data ? dev->data_bulk_out : dev->burst_bulk_out; 241 break; 242 case USB_TRANSFER_ISOCHRONOUS: 243 pipe = params->validate_data ? dev->data_isoch_out : dev->burst_isoch_out; 244 break; 245 default: 246 return ENOTSUP; 247 } 248 249 return test_out(pipe, params, results); 371 250 } 372 251
Note:
See TracChangeset
for help on using the changeset viewer.