Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: sparc64: char: Selftest for privileged ADI driver

Add a selftest for the sparc64 privileged ADI driver. These
tests verify the read(), pread(), write(), pwrite(), and seek()
functionality of the driver. The tests also report simple
performance statistics:

Syscall Call AvgTime AvgSize
Count (ticks) (bytes)
-------------------------------
read 3 119638 8133
pread 4 118164 6741
write 3 339442 8133
pwrite 4 280134 6741
seek 10 2919 0
Pass 8 Fail 0 Xfail 0 Xpass 0 Skip 0 Error 0

Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
Reviewed-by: Allen Pais <allen.pais@oracle.com>
Reviewed-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Tom Hromatka and committed by
David S. Miller
3c545084 873c38a4

+817
+1
tools/testing/selftests/Makefile
··· 31 31 TARGETS += seccomp 32 32 TARGETS += sigaltstack 33 33 TARGETS += size 34 + TARGETS += sparc64 34 35 TARGETS += splice 35 36 TARGETS += static_keys 36 37 TARGETS += sync
+46
tools/testing/selftests/sparc64/Makefile
··· 1 + SUBDIRS := drivers 2 + 3 + TEST_PROGS := run.sh 4 + 5 + .PHONY: all clean 6 + 7 + include ../lib.mk 8 + 9 + all: 10 + @for DIR in $(SUBDIRS); do \ 11 + BUILD_TARGET=$(OUTPUT)/$$DIR; \ 12 + mkdir $$BUILD_TARGET -p; \ 13 + make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ 14 + #SUBDIR test prog name should be in the form: SUBDIR_test.sh \ 15 + TEST=$$DIR"_test.sh"; \ 16 + if [ -e $$DIR/$$TEST ]; then \ 17 + rsync -a $$DIR/$$TEST $$BUILD_TARGET/; \ 18 + fi \ 19 + done 20 + 21 + override define RUN_TESTS 22 + @cd $(OUTPUT); ./run.sh 23 + endef 24 + 25 + override define INSTALL_RULE 26 + mkdir -p $(INSTALL_PATH) 27 + install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) 28 + 29 + @for SUBDIR in $(SUBDIRS); do \ 30 + BUILD_TARGET=$(OUTPUT)/$$SUBDIR; \ 31 + mkdir $$BUILD_TARGET -p; \ 32 + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$SUBDIR INSTALL_PATH=$(INSTALL_PATH)/$$SUBDIR install; \ 33 + done; 34 + endef 35 + 36 + override define EMIT_TESTS 37 + echo "./run.sh" 38 + endef 39 + 40 + override define CLEAN 41 + @for DIR in $(SUBDIRS); do \ 42 + BUILD_TARGET=$(OUTPUT)/$$DIR; \ 43 + mkdir $$BUILD_TARGET -p; \ 44 + make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ 45 + done 46 + endef
+1
tools/testing/selftests/sparc64/drivers/.gitignore
··· 1 + adi-test
+15
tools/testing/selftests/sparc64/drivers/Makefile
··· 1 + 2 + INCLUDEDIR := -I. 3 + CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g 4 + 5 + TEST_GEN_FILES := adi-test 6 + 7 + all: $(TEST_GEN_FILES) 8 + 9 + $(TEST_GEN_FILES): adi-test.c 10 + 11 + TEST_PROGS := drivers_test.sh 12 + 13 + include ../../lib.mk 14 + 15 + $(OUTPUT)/adi-test: adi-test.c
+721
tools/testing/selftests/sparc64/drivers/adi-test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * selftest for sparc64's privileged ADI driver 4 + * 5 + * Author: Tom Hromatka <tom.hromatka@oracle.com> 6 + */ 7 + #include <linux/kernel.h> 8 + #include <errno.h> 9 + #include <fcntl.h> 10 + #include <stdarg.h> 11 + #include <stdio.h> 12 + #include <stdlib.h> 13 + #include <string.h> 14 + #include <sys/syscall.h> 15 + #include <sys/types.h> 16 + #include <sys/stat.h> 17 + #include <unistd.h> 18 + 19 + #include "../../kselftest.h" 20 + 21 + #define DEBUG_LEVEL_1_BIT (0x0001) 22 + #define DEBUG_LEVEL_2_BIT (0x0002) 23 + #define DEBUG_LEVEL_3_BIT (0x0004) 24 + #define DEBUG_LEVEL_4_BIT (0x0008) 25 + #define DEBUG_TIMING_BIT (0x1000) 26 + 27 + #ifndef ARRAY_SIZE 28 + # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 29 + #endif 30 + 31 + /* bit mask of enabled bits to print */ 32 + #define DEBUG 0x0001 33 + 34 + #define DEBUG_PRINT_L1(...) debug_print(DEBUG_LEVEL_1_BIT, __VA_ARGS__) 35 + #define DEBUG_PRINT_L2(...) debug_print(DEBUG_LEVEL_2_BIT, __VA_ARGS__) 36 + #define DEBUG_PRINT_L3(...) debug_print(DEBUG_LEVEL_3_BIT, __VA_ARGS__) 37 + #define DEBUG_PRINT_L4(...) debug_print(DEBUG_LEVEL_4_BIT, __VA_ARGS__) 38 + #define DEBUG_PRINT_T(...) debug_print(DEBUG_TIMING_BIT, __VA_ARGS__) 39 + 40 + static void debug_print(int level, const char *s, ...) 41 + { 42 + va_list args; 43 + 44 + va_start(args, s); 45 + 46 + if (DEBUG & level) 47 + vfprintf(stdout, s, args); 48 + va_end(args); 49 + } 50 + 51 + #ifndef min 52 + #define min(x, y) ((x) < (y) ? x : y) 53 + #endif 54 + 55 + #define RETURN_FROM_TEST(_ret) \ 56 + do { \ 57 + DEBUG_PRINT_L1( \ 58 + "\tTest %s returned %d\n", __func__, _ret); \ 59 + return _ret; \ 60 + } while (0) 61 + 62 + #define ADI_BLKSZ 64 63 + #define ADI_MAX_VERSION 15 64 + 65 + #define TEST_STEP_FAILURE(_ret) \ 66 + do { \ 67 + fprintf(stderr, "\tTest step failure: %d at %s:%d\n", \ 68 + _ret, __func__, __LINE__); \ 69 + goto out; \ 70 + } while (0) 71 + 72 + #define RDTICK(_x) \ 73 + asm volatile(" rd %%tick, %0\n" : "=r" (_x)) 74 + 75 + static int random_version(void) 76 + { 77 + long tick; 78 + 79 + RDTICK(tick); 80 + 81 + return tick % (ADI_MAX_VERSION + 1); 82 + } 83 + 84 + #define MAX_RANGES_SUPPORTED 5 85 + static const char system_ram_str[] = "System RAM\n"; 86 + static int range_count; 87 + static unsigned long long int start_addr[MAX_RANGES_SUPPORTED]; 88 + static unsigned long long int end_addr[MAX_RANGES_SUPPORTED]; 89 + 90 + struct stats { 91 + char name[16]; 92 + unsigned long total; 93 + unsigned long count; 94 + unsigned long bytes; 95 + }; 96 + 97 + static struct stats read_stats = { 98 + .name = "read", .total = 0, .count = 0, .bytes = 0}; 99 + static struct stats pread_stats = { 100 + .name = "pread", .total = 0, .count = 0, .bytes = 0}; 101 + static struct stats write_stats = { 102 + .name = "write", .total = 0, .count = 0, .bytes = 0}; 103 + static struct stats pwrite_stats = { 104 + .name = "pwrite", .total = 0, .count = 0, .bytes = 0}; 105 + static struct stats seek_stats = { 106 + .name = "seek", .total = 0, .count = 0, .bytes = 0}; 107 + 108 + static void update_stats(struct stats * const ustats, 109 + unsigned long measurement, unsigned long bytes) 110 + { 111 + ustats->total += measurement; 112 + ustats->bytes += bytes; 113 + ustats->count++; 114 + } 115 + 116 + static void print_ustats(const struct stats * const ustats) 117 + { 118 + DEBUG_PRINT_L1("%s\t%7d\t%7.0f\t%7.0f\n", 119 + ustats->name, ustats->count, 120 + (float)ustats->total / (float)ustats->count, 121 + (float)ustats->bytes / (float)ustats->count); 122 + } 123 + 124 + static void print_stats(void) 125 + { 126 + DEBUG_PRINT_L1("\nSyscall\tCall\tAvgTime\tAvgSize\n" 127 + "\tCount\t(ticks)\t(bytes)\n" 128 + "-------------------------------\n"); 129 + 130 + print_ustats(&read_stats); 131 + print_ustats(&pread_stats); 132 + print_ustats(&write_stats); 133 + print_ustats(&pwrite_stats); 134 + print_ustats(&seek_stats); 135 + } 136 + 137 + static int build_memory_map(void) 138 + { 139 + char line[256]; 140 + FILE *fp; 141 + int i; 142 + 143 + range_count = 0; 144 + 145 + fp = fopen("/proc/iomem", "r"); 146 + if (!fp) { 147 + fprintf(stderr, "/proc/iomem: error %d: %s\n", 148 + errno, strerror(errno)); 149 + return -errno; 150 + } 151 + 152 + while (fgets(line, sizeof(line), fp) != 0) { 153 + if (strstr(line, system_ram_str)) { 154 + char *dash, *end_ptr; 155 + 156 + /* Given a line like this: 157 + * d0400000-10ffaffff : System RAM 158 + * replace the "-" with a space 159 + */ 160 + dash = strstr(line, "-"); 161 + dash[0] = 0x20; 162 + 163 + start_addr[range_count] = strtoull(line, &end_ptr, 16); 164 + end_addr[range_count] = strtoull(end_ptr, NULL, 16); 165 + range_count++; 166 + } 167 + } 168 + 169 + fclose(fp); 170 + 171 + DEBUG_PRINT_L1("RAM Ranges\n"); 172 + for (i = 0; i < range_count; i++) 173 + DEBUG_PRINT_L1("\trange %d: 0x%llx\t- 0x%llx\n", 174 + i, start_addr[i], end_addr[i]); 175 + 176 + if (range_count == 0) { 177 + fprintf(stderr, "No valid address ranges found. Error.\n"); 178 + return -1; 179 + } 180 + 181 + return 0; 182 + } 183 + 184 + static int read_adi(int fd, unsigned char *buf, int buf_sz) 185 + { 186 + int ret, bytes_read = 0; 187 + long start, end, elapsed_time = 0; 188 + 189 + do { 190 + RDTICK(start); 191 + ret = read(fd, buf + bytes_read, buf_sz - bytes_read); 192 + RDTICK(end); 193 + if (ret < 0) 194 + return -errno; 195 + 196 + elapsed_time += end - start; 197 + update_stats(&read_stats, elapsed_time, buf_sz); 198 + bytes_read += ret; 199 + 200 + } while (bytes_read < buf_sz); 201 + 202 + DEBUG_PRINT_T("\tread elapsed timed = %ld\n", elapsed_time); 203 + DEBUG_PRINT_L3("\tRead %d bytes\n", bytes_read); 204 + 205 + return bytes_read; 206 + } 207 + 208 + static int pread_adi(int fd, unsigned char *buf, 209 + int buf_sz, unsigned long offset) 210 + { 211 + int ret, i, bytes_read = 0; 212 + unsigned long cur_offset; 213 + long start, end, elapsed_time = 0; 214 + 215 + cur_offset = offset; 216 + do { 217 + RDTICK(start); 218 + ret = pread(fd, buf + bytes_read, buf_sz - bytes_read, 219 + cur_offset); 220 + RDTICK(end); 221 + if (ret < 0) 222 + return -errno; 223 + 224 + elapsed_time += end - start; 225 + update_stats(&pread_stats, elapsed_time, buf_sz); 226 + bytes_read += ret; 227 + cur_offset += ret; 228 + 229 + } while (bytes_read < buf_sz); 230 + 231 + DEBUG_PRINT_T("\tpread elapsed timed = %ld\n", elapsed_time); 232 + DEBUG_PRINT_L3("\tRead %d bytes starting at offset 0x%lx\n", 233 + bytes_read, offset); 234 + for (i = 0; i < bytes_read; i++) 235 + DEBUG_PRINT_L4("\t\t0x%lx\t%d\n", offset + i, buf[i]); 236 + 237 + return bytes_read; 238 + } 239 + 240 + static int write_adi(int fd, const unsigned char * const buf, int buf_sz) 241 + { 242 + int ret, bytes_written = 0; 243 + long start, end, elapsed_time = 0; 244 + 245 + do { 246 + RDTICK(start); 247 + ret = write(fd, buf + bytes_written, buf_sz - bytes_written); 248 + RDTICK(end); 249 + if (ret < 0) 250 + return -errno; 251 + 252 + elapsed_time += (end - start); 253 + update_stats(&write_stats, elapsed_time, buf_sz); 254 + bytes_written += ret; 255 + } while (bytes_written < buf_sz); 256 + 257 + DEBUG_PRINT_T("\twrite elapsed timed = %ld\n", elapsed_time); 258 + DEBUG_PRINT_L3("\tWrote %d of %d bytes\n", bytes_written, buf_sz); 259 + 260 + return bytes_written; 261 + } 262 + 263 + static int pwrite_adi(int fd, const unsigned char * const buf, 264 + int buf_sz, unsigned long offset) 265 + { 266 + int ret, bytes_written = 0; 267 + unsigned long cur_offset; 268 + long start, end, elapsed_time = 0; 269 + 270 + cur_offset = offset; 271 + 272 + do { 273 + RDTICK(start); 274 + ret = pwrite(fd, buf + bytes_written, 275 + buf_sz - bytes_written, cur_offset); 276 + RDTICK(end); 277 + if (ret < 0) { 278 + fprintf(stderr, "pwrite(): error %d: %s\n", 279 + errno, strerror(errno)); 280 + return -errno; 281 + } 282 + 283 + elapsed_time += (end - start); 284 + update_stats(&pwrite_stats, elapsed_time, buf_sz); 285 + bytes_written += ret; 286 + cur_offset += ret; 287 + 288 + } while (bytes_written < buf_sz); 289 + 290 + DEBUG_PRINT_T("\tpwrite elapsed timed = %ld\n", elapsed_time); 291 + DEBUG_PRINT_L3("\tWrote %d of %d bytes starting at address 0x%lx\n", 292 + bytes_written, buf_sz, offset); 293 + 294 + return bytes_written; 295 + } 296 + 297 + static off_t seek_adi(int fd, off_t offset, int whence) 298 + { 299 + long start, end; 300 + off_t ret; 301 + 302 + RDTICK(start); 303 + ret = lseek(fd, offset, whence); 304 + RDTICK(end); 305 + DEBUG_PRINT_L2("\tlseek ret = 0x%llx\n", ret); 306 + if (ret < 0) 307 + goto out; 308 + 309 + DEBUG_PRINT_T("\tlseek elapsed timed = %ld\n", end - start); 310 + update_stats(&seek_stats, end - start, 0); 311 + 312 + out: 313 + (void)lseek(fd, 0, SEEK_END); 314 + return ret; 315 + } 316 + 317 + static int test0_prpw_aligned_1byte(int fd) 318 + { 319 + /* somewhat arbitrarily chosen address */ 320 + unsigned long paddr = 321 + (end_addr[range_count - 1] - 0x1000) & ~(ADI_BLKSZ - 1); 322 + unsigned char version[1], expected_version; 323 + loff_t offset; 324 + int ret; 325 + 326 + version[0] = random_version(); 327 + expected_version = version[0]; 328 + 329 + offset = paddr / ADI_BLKSZ; 330 + 331 + ret = pwrite_adi(fd, version, sizeof(version), offset); 332 + if (ret != sizeof(version)) 333 + TEST_STEP_FAILURE(ret); 334 + 335 + ret = pread_adi(fd, version, sizeof(version), offset); 336 + if (ret != sizeof(version)) 337 + TEST_STEP_FAILURE(ret); 338 + 339 + if (expected_version != version[0]) { 340 + DEBUG_PRINT_L2("\tExpected version %d but read version %d\n", 341 + expected_version, version[0]); 342 + TEST_STEP_FAILURE(-expected_version); 343 + } 344 + 345 + ret = 0; 346 + out: 347 + RETURN_FROM_TEST(ret); 348 + } 349 + 350 + #define TEST1_VERSION_SZ 4096 351 + static int test1_prpw_aligned_4096bytes(int fd) 352 + { 353 + /* somewhat arbitrarily chosen address */ 354 + unsigned long paddr = 355 + (end_addr[range_count - 1] - 0x6000) & ~(ADI_BLKSZ - 1); 356 + unsigned char version[TEST1_VERSION_SZ], 357 + expected_version[TEST1_VERSION_SZ]; 358 + loff_t offset; 359 + int ret, i; 360 + 361 + for (i = 0; i < TEST1_VERSION_SZ; i++) { 362 + version[i] = random_version(); 363 + expected_version[i] = version[i]; 364 + } 365 + 366 + offset = paddr / ADI_BLKSZ; 367 + 368 + ret = pwrite_adi(fd, version, sizeof(version), offset); 369 + if (ret != sizeof(version)) 370 + TEST_STEP_FAILURE(ret); 371 + 372 + ret = pread_adi(fd, version, sizeof(version), offset); 373 + if (ret != sizeof(version)) 374 + TEST_STEP_FAILURE(ret); 375 + 376 + for (i = 0; i < TEST1_VERSION_SZ; i++) { 377 + if (expected_version[i] != version[i]) { 378 + DEBUG_PRINT_L2( 379 + "\tExpected version %d but read version %d\n", 380 + expected_version, version[0]); 381 + TEST_STEP_FAILURE(-expected_version[i]); 382 + } 383 + } 384 + 385 + ret = 0; 386 + out: 387 + RETURN_FROM_TEST(ret); 388 + } 389 + 390 + #define TEST2_VERSION_SZ 10327 391 + static int test2_prpw_aligned_10327bytes(int fd) 392 + { 393 + /* somewhat arbitrarily chosen address */ 394 + unsigned long paddr = 395 + (start_addr[0] + 0x6000) & ~(ADI_BLKSZ - 1); 396 + unsigned char version[TEST2_VERSION_SZ], 397 + expected_version[TEST2_VERSION_SZ]; 398 + loff_t offset; 399 + int ret, i; 400 + 401 + for (i = 0; i < TEST2_VERSION_SZ; i++) { 402 + version[i] = random_version(); 403 + expected_version[i] = version[i]; 404 + } 405 + 406 + offset = paddr / ADI_BLKSZ; 407 + 408 + ret = pwrite_adi(fd, version, sizeof(version), offset); 409 + if (ret != sizeof(version)) 410 + TEST_STEP_FAILURE(ret); 411 + 412 + ret = pread_adi(fd, version, sizeof(version), offset); 413 + if (ret != sizeof(version)) 414 + TEST_STEP_FAILURE(ret); 415 + 416 + for (i = 0; i < TEST2_VERSION_SZ; i++) { 417 + if (expected_version[i] != version[i]) { 418 + DEBUG_PRINT_L2( 419 + "\tExpected version %d but read version %d\n", 420 + expected_version, version[0]); 421 + TEST_STEP_FAILURE(-expected_version[i]); 422 + } 423 + } 424 + 425 + ret = 0; 426 + out: 427 + RETURN_FROM_TEST(ret); 428 + } 429 + 430 + #define TEST3_VERSION_SZ 12541 431 + static int test3_prpw_unaligned_12541bytes(int fd) 432 + { 433 + /* somewhat arbitrarily chosen address */ 434 + unsigned long paddr = 435 + ((start_addr[0] + 0xC000) & ~(ADI_BLKSZ - 1)) + 17; 436 + unsigned char version[TEST3_VERSION_SZ], 437 + expected_version[TEST3_VERSION_SZ]; 438 + loff_t offset; 439 + int ret, i; 440 + 441 + for (i = 0; i < TEST3_VERSION_SZ; i++) { 442 + version[i] = random_version(); 443 + expected_version[i] = version[i]; 444 + } 445 + 446 + offset = paddr / ADI_BLKSZ; 447 + 448 + ret = pwrite_adi(fd, version, sizeof(version), offset); 449 + if (ret != sizeof(version)) 450 + TEST_STEP_FAILURE(ret); 451 + 452 + ret = pread_adi(fd, version, sizeof(version), offset); 453 + if (ret != sizeof(version)) 454 + TEST_STEP_FAILURE(ret); 455 + 456 + for (i = 0; i < TEST3_VERSION_SZ; i++) { 457 + if (expected_version[i] != version[i]) { 458 + DEBUG_PRINT_L2( 459 + "\tExpected version %d but read version %d\n", 460 + expected_version, version[0]); 461 + TEST_STEP_FAILURE(-expected_version[i]); 462 + } 463 + } 464 + 465 + ret = 0; 466 + out: 467 + RETURN_FROM_TEST(ret); 468 + } 469 + 470 + static int test4_lseek(int fd) 471 + { 472 + #define OFFSET_ADD (0x100) 473 + #define OFFSET_SUBTRACT (0xFFFFFFF000000000) 474 + 475 + off_t offset_out, offset_in; 476 + int ret; 477 + 478 + 479 + offset_in = 0x123456789abcdef0; 480 + offset_out = seek_adi(fd, offset_in, SEEK_SET); 481 + if (offset_out != offset_in) { 482 + ret = -1; 483 + TEST_STEP_FAILURE(ret); 484 + } 485 + 486 + /* seek to the current offset. this should return EINVAL */ 487 + offset_out = seek_adi(fd, offset_in, SEEK_SET); 488 + if (offset_out < 0 && errno == EINVAL) 489 + DEBUG_PRINT_L2( 490 + "\tSEEK_SET failed as designed. Not an error\n"); 491 + else { 492 + ret = -2; 493 + TEST_STEP_FAILURE(ret); 494 + } 495 + 496 + offset_out = seek_adi(fd, 0, SEEK_CUR); 497 + if (offset_out != offset_in) { 498 + ret = -3; 499 + TEST_STEP_FAILURE(ret); 500 + } 501 + 502 + offset_out = seek_adi(fd, OFFSET_ADD, SEEK_CUR); 503 + if (offset_out != (offset_in + OFFSET_ADD)) { 504 + ret = -4; 505 + TEST_STEP_FAILURE(ret); 506 + } 507 + 508 + offset_out = seek_adi(fd, OFFSET_SUBTRACT, SEEK_CUR); 509 + if (offset_out != (offset_in + OFFSET_ADD + OFFSET_SUBTRACT)) { 510 + ret = -5; 511 + TEST_STEP_FAILURE(ret); 512 + } 513 + 514 + ret = 0; 515 + out: 516 + RETURN_FROM_TEST(ret); 517 + } 518 + 519 + static int test5_rw_aligned_1byte(int fd) 520 + { 521 + /* somewhat arbitrarily chosen address */ 522 + unsigned long paddr = 523 + (end_addr[range_count - 1] - 0xF000) & ~(ADI_BLKSZ - 1); 524 + unsigned char version, expected_version; 525 + loff_t offset; 526 + off_t oret; 527 + int ret; 528 + 529 + offset = paddr / ADI_BLKSZ; 530 + version = expected_version = random_version(); 531 + 532 + oret = seek_adi(fd, offset, SEEK_SET); 533 + if (oret != offset) { 534 + ret = -1; 535 + TEST_STEP_FAILURE(ret); 536 + } 537 + 538 + ret = write_adi(fd, &version, sizeof(version)); 539 + if (ret != sizeof(version)) 540 + TEST_STEP_FAILURE(ret); 541 + 542 + oret = seek_adi(fd, offset, SEEK_SET); 543 + if (oret != offset) { 544 + ret = -1; 545 + TEST_STEP_FAILURE(ret); 546 + } 547 + 548 + ret = read_adi(fd, &version, sizeof(version)); 549 + if (ret != sizeof(version)) 550 + TEST_STEP_FAILURE(ret); 551 + 552 + if (expected_version != version) { 553 + DEBUG_PRINT_L2("\tExpected version %d but read version %d\n", 554 + expected_version, version); 555 + TEST_STEP_FAILURE(-expected_version); 556 + } 557 + 558 + ret = 0; 559 + out: 560 + RETURN_FROM_TEST(ret); 561 + } 562 + 563 + #define TEST6_VERSION_SZ 9434 564 + static int test6_rw_aligned_9434bytes(int fd) 565 + { 566 + /* somewhat arbitrarily chosen address */ 567 + unsigned long paddr = 568 + (end_addr[range_count - 1] - 0x5F000) & ~(ADI_BLKSZ - 1); 569 + unsigned char version[TEST6_VERSION_SZ], 570 + expected_version[TEST6_VERSION_SZ]; 571 + loff_t offset; 572 + off_t oret; 573 + int ret, i; 574 + 575 + offset = paddr / ADI_BLKSZ; 576 + for (i = 0; i < TEST6_VERSION_SZ; i++) 577 + version[i] = expected_version[i] = random_version(); 578 + 579 + oret = seek_adi(fd, offset, SEEK_SET); 580 + if (oret != offset) { 581 + ret = -1; 582 + TEST_STEP_FAILURE(ret); 583 + } 584 + 585 + ret = write_adi(fd, version, sizeof(version)); 586 + if (ret != sizeof(version)) 587 + TEST_STEP_FAILURE(ret); 588 + 589 + memset(version, 0, TEST6_VERSION_SZ); 590 + 591 + oret = seek_adi(fd, offset, SEEK_SET); 592 + if (oret != offset) { 593 + ret = -1; 594 + TEST_STEP_FAILURE(ret); 595 + } 596 + 597 + ret = read_adi(fd, version, sizeof(version)); 598 + if (ret != sizeof(version)) 599 + TEST_STEP_FAILURE(ret); 600 + 601 + for (i = 0; i < TEST6_VERSION_SZ; i++) { 602 + if (expected_version[i] != version[i]) { 603 + DEBUG_PRINT_L2( 604 + "\tExpected version %d but read version %d\n", 605 + expected_version[i], version[i]); 606 + TEST_STEP_FAILURE(-expected_version[i]); 607 + } 608 + } 609 + 610 + ret = 0; 611 + out: 612 + RETURN_FROM_TEST(ret); 613 + } 614 + 615 + #define TEST7_VERSION_SZ 14963 616 + static int test7_rw_aligned_14963bytes(int fd) 617 + { 618 + /* somewhat arbitrarily chosen address */ 619 + unsigned long paddr = 620 + ((start_addr[range_count - 1] + 0xF000) & ~(ADI_BLKSZ - 1)) + 39; 621 + unsigned char version[TEST7_VERSION_SZ], 622 + expected_version[TEST7_VERSION_SZ]; 623 + loff_t offset; 624 + off_t oret; 625 + int ret, i; 626 + 627 + offset = paddr / ADI_BLKSZ; 628 + for (i = 0; i < TEST7_VERSION_SZ; i++) { 629 + version[i] = random_version(); 630 + expected_version[i] = version[i]; 631 + } 632 + 633 + oret = seek_adi(fd, offset, SEEK_SET); 634 + if (oret != offset) { 635 + ret = -1; 636 + TEST_STEP_FAILURE(ret); 637 + } 638 + 639 + ret = write_adi(fd, version, sizeof(version)); 640 + if (ret != sizeof(version)) 641 + TEST_STEP_FAILURE(ret); 642 + 643 + memset(version, 0, TEST7_VERSION_SZ); 644 + 645 + oret = seek_adi(fd, offset, SEEK_SET); 646 + if (oret != offset) { 647 + ret = -1; 648 + TEST_STEP_FAILURE(ret); 649 + } 650 + 651 + ret = read_adi(fd, version, sizeof(version)); 652 + if (ret != sizeof(version)) 653 + TEST_STEP_FAILURE(ret); 654 + 655 + for (i = 0; i < TEST7_VERSION_SZ; i++) { 656 + if (expected_version[i] != version[i]) { 657 + DEBUG_PRINT_L2( 658 + "\tExpected version %d but read version %d\n", 659 + expected_version[i], version[i]); 660 + TEST_STEP_FAILURE(-expected_version[i]); 661 + } 662 + 663 + paddr += ADI_BLKSZ; 664 + } 665 + 666 + ret = 0; 667 + out: 668 + RETURN_FROM_TEST(ret); 669 + } 670 + 671 + static int (*tests[])(int fd) = { 672 + test0_prpw_aligned_1byte, 673 + test1_prpw_aligned_4096bytes, 674 + test2_prpw_aligned_10327bytes, 675 + test3_prpw_unaligned_12541bytes, 676 + test4_lseek, 677 + test5_rw_aligned_1byte, 678 + test6_rw_aligned_9434bytes, 679 + test7_rw_aligned_14963bytes, 680 + }; 681 + #define TEST_COUNT ARRAY_SIZE(tests) 682 + 683 + int main(int argc, char *argv[]) 684 + { 685 + int fd, ret, test; 686 + 687 + ret = build_memory_map(); 688 + if (ret < 0) 689 + return ret; 690 + 691 + fd = open("/dev/adi", O_RDWR); 692 + if (fd < 0) { 693 + fprintf(stderr, "open: error %d: %s\n", 694 + errno, strerror(errno)); 695 + return -errno; 696 + } 697 + 698 + for (test = 0; test < TEST_COUNT; test++) { 699 + DEBUG_PRINT_L1("Running test #%d\n", test); 700 + 701 + ret = (*tests[test])(fd); 702 + if (ret != 0) 703 + ksft_test_result_fail("Test #%d failed: error %d\n", 704 + test, ret); 705 + else 706 + ksft_test_result_pass("Test #%d passed\n", test); 707 + } 708 + 709 + print_stats(); 710 + close(fd); 711 + 712 + if (ksft_get_fail_cnt() > 0) 713 + ksft_exit_fail(); 714 + else 715 + ksft_exit_pass(); 716 + 717 + /* it's impossible to get here, but the compiler throws a warning 718 + * about control reaching the end of non-void function. bah. 719 + */ 720 + return 0; 721 + }
+30
tools/testing/selftests/sparc64/drivers/drivers_test.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + SRC_TREE=../../../../ 5 + 6 + test_run() 7 + { 8 + if [ -f ${SRC_TREE}/drivers/char/adi.ko ]; then 9 + insmod ${SRC_TREE}/drivers/char/adi.ko 2> /dev/null 10 + if [ $? -ne 0 ]; then 11 + rc=1 12 + fi 13 + else 14 + # Use modprobe dry run to check for missing adi module 15 + if ! /sbin/modprobe -q -n adi; then 16 + echo "adi: [SKIP]" 17 + elif /sbin/modprobe -q adi; then 18 + echo "adi: ok" 19 + else 20 + echo "adi: [FAIL]" 21 + rc=1 22 + fi 23 + fi 24 + ./adi-test 25 + rmmod adi 2> /dev/null 26 + } 27 + 28 + rc=0 29 + test_run 30 + exit $rc
+3
tools/testing/selftests/sparc64/run.sh
··· 1 + #!/bin/sh 2 + 3 + (cd drivers; ./drivers_test.sh)