Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * selftest for sparc64's privileged ADI driver
0004  *
0005  * Author: Tom Hromatka <tom.hromatka@oracle.com>
0006  */
0007 #include <linux/kernel.h>
0008 #include <errno.h>
0009 #include <fcntl.h>
0010 #include <stdarg.h>
0011 #include <stdio.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <sys/syscall.h>
0015 #include <sys/types.h>
0016 #include <sys/stat.h>
0017 #include <unistd.h>
0018 
0019 #include "../../kselftest.h"
0020 
0021 #define DEBUG_LEVEL_1_BIT   (0x0001)
0022 #define DEBUG_LEVEL_2_BIT   (0x0002)
0023 #define DEBUG_LEVEL_3_BIT   (0x0004)
0024 #define DEBUG_LEVEL_4_BIT   (0x0008)
0025 #define DEBUG_TIMING_BIT    (0x1000)
0026 
0027 /* bit mask of enabled bits to print */
0028 #define DEBUG 0x0001
0029 
0030 #define DEBUG_PRINT_L1(...) debug_print(DEBUG_LEVEL_1_BIT, __VA_ARGS__)
0031 #define DEBUG_PRINT_L2(...) debug_print(DEBUG_LEVEL_2_BIT, __VA_ARGS__)
0032 #define DEBUG_PRINT_L3(...) debug_print(DEBUG_LEVEL_3_BIT, __VA_ARGS__)
0033 #define DEBUG_PRINT_L4(...) debug_print(DEBUG_LEVEL_4_BIT, __VA_ARGS__)
0034 #define DEBUG_PRINT_T(...)  debug_print(DEBUG_TIMING_BIT, __VA_ARGS__)
0035 
0036 static void debug_print(int level, const char *s, ...)
0037 {
0038     va_list args;
0039 
0040     va_start(args, s);
0041 
0042     if (DEBUG & level)
0043         vfprintf(stdout, s, args);
0044     va_end(args);
0045 }
0046 
0047 #ifndef min
0048 #define min(x, y) ((x) < (y) ? x : y)
0049 #endif
0050 
0051 #define RETURN_FROM_TEST(_ret) \
0052     do { \
0053         DEBUG_PRINT_L1( \
0054             "\tTest %s returned %d\n", __func__, _ret); \
0055         return _ret; \
0056     } while (0)
0057 
0058 #define ADI_BLKSZ   64
0059 #define ADI_MAX_VERSION 15
0060 
0061 #define TEST_STEP_FAILURE(_ret) \
0062     do { \
0063         fprintf(stderr, "\tTest step failure: %d at %s:%d\n", \
0064             _ret, __func__, __LINE__); \
0065         goto out; \
0066     } while (0)
0067 
0068 #define RDTICK(_x) \
0069     asm volatile(" rd %%tick, %0\n" : "=r" (_x))
0070 
0071 static int random_version(void)
0072 {
0073     long tick;
0074 
0075     RDTICK(tick);
0076 
0077     return tick % (ADI_MAX_VERSION + 1);
0078 }
0079 
0080 #define MAX_RANGES_SUPPORTED    5
0081 static const char system_ram_str[] = "System RAM\n";
0082 static int range_count;
0083 static unsigned long long int start_addr[MAX_RANGES_SUPPORTED];
0084 static unsigned long long int   end_addr[MAX_RANGES_SUPPORTED];
0085 
0086 struct stats {
0087     char        name[16];
0088     unsigned long   total;
0089     unsigned long   count;
0090     unsigned long   bytes;
0091 };
0092 
0093 static struct stats read_stats = {
0094     .name = "read", .total = 0, .count = 0, .bytes = 0};
0095 static struct stats pread_stats = {
0096     .name = "pread", .total = 0, .count = 0, .bytes = 0};
0097 static struct stats write_stats = {
0098     .name = "write", .total = 0, .count = 0, .bytes = 0};
0099 static struct stats pwrite_stats = {
0100     .name = "pwrite", .total = 0, .count = 0, .bytes = 0};
0101 static struct stats seek_stats = {
0102     .name = "seek", .total = 0, .count = 0, .bytes = 0};
0103 
0104 static void update_stats(struct stats * const ustats,
0105              unsigned long measurement, unsigned long bytes)
0106 {
0107     ustats->total += measurement;
0108     ustats->bytes += bytes;
0109     ustats->count++;
0110 }
0111 
0112 static void print_ustats(const struct stats * const ustats)
0113 {
0114     DEBUG_PRINT_L1("%s\t%7d\t%7.0f\t%7.0f\n",
0115                ustats->name, ustats->count,
0116                (float)ustats->total / (float)ustats->count,
0117                (float)ustats->bytes / (float)ustats->count);
0118 }
0119 
0120 static void print_stats(void)
0121 {
0122     DEBUG_PRINT_L1("\nSyscall\tCall\tAvgTime\tAvgSize\n"
0123                "\tCount\t(ticks)\t(bytes)\n"
0124                "-------------------------------\n");
0125 
0126     print_ustats(&read_stats);
0127     print_ustats(&pread_stats);
0128     print_ustats(&write_stats);
0129     print_ustats(&pwrite_stats);
0130     print_ustats(&seek_stats);
0131 }
0132 
0133 static int build_memory_map(void)
0134 {
0135     char line[256];
0136     FILE *fp;
0137     int i;
0138 
0139     range_count = 0;
0140 
0141     fp = fopen("/proc/iomem", "r");
0142     if (!fp) {
0143         fprintf(stderr, "/proc/iomem: error %d: %s\n",
0144             errno, strerror(errno));
0145         return -errno;
0146     }
0147 
0148     while (fgets(line, sizeof(line), fp) != 0) {
0149         if (strstr(line, system_ram_str)) {
0150             char *dash, *end_ptr;
0151 
0152             /* Given a line like this:
0153              * d0400000-10ffaffff : System RAM
0154              * replace the "-" with a space
0155              */
0156             dash = strstr(line, "-");
0157             dash[0] = 0x20;
0158 
0159             start_addr[range_count] = strtoull(line, &end_ptr, 16);
0160             end_addr[range_count] = strtoull(end_ptr, NULL, 16);
0161             range_count++;
0162         }
0163     }
0164 
0165     fclose(fp);
0166 
0167     DEBUG_PRINT_L1("RAM Ranges\n");
0168     for (i = 0; i < range_count; i++)
0169         DEBUG_PRINT_L1("\trange %d: 0x%llx\t- 0x%llx\n",
0170                    i, start_addr[i], end_addr[i]);
0171 
0172     if (range_count == 0) {
0173         fprintf(stderr, "No valid address ranges found.  Error.\n");
0174         return -1;
0175     }
0176 
0177     return 0;
0178 }
0179 
0180 static int read_adi(int fd, unsigned char *buf, int buf_sz)
0181 {
0182     int ret, bytes_read = 0;
0183     long start, end, elapsed_time = 0;
0184 
0185     do {
0186         RDTICK(start);
0187         ret = read(fd, buf + bytes_read, buf_sz - bytes_read);
0188         RDTICK(end);
0189         if (ret < 0)
0190             return -errno;
0191 
0192         elapsed_time += end - start;
0193         update_stats(&read_stats, elapsed_time, buf_sz);
0194         bytes_read += ret;
0195 
0196     } while (bytes_read < buf_sz);
0197 
0198     DEBUG_PRINT_T("\tread elapsed timed = %ld\n", elapsed_time);
0199     DEBUG_PRINT_L3("\tRead  %d bytes\n", bytes_read);
0200 
0201     return bytes_read;
0202 }
0203 
0204 static int pread_adi(int fd, unsigned char *buf,
0205              int buf_sz, unsigned long offset)
0206 {
0207     int ret, i, bytes_read = 0;
0208     unsigned long cur_offset;
0209     long start, end, elapsed_time = 0;
0210 
0211     cur_offset = offset;
0212     do {
0213         RDTICK(start);
0214         ret = pread(fd, buf + bytes_read, buf_sz - bytes_read,
0215                 cur_offset);
0216         RDTICK(end);
0217         if (ret < 0)
0218             return -errno;
0219 
0220         elapsed_time += end - start;
0221         update_stats(&pread_stats, elapsed_time, buf_sz);
0222         bytes_read += ret;
0223         cur_offset += ret;
0224 
0225     } while (bytes_read < buf_sz);
0226 
0227     DEBUG_PRINT_T("\tpread elapsed timed = %ld\n", elapsed_time);
0228     DEBUG_PRINT_L3("\tRead  %d bytes starting at offset 0x%lx\n",
0229                bytes_read, offset);
0230     for (i = 0; i < bytes_read; i++)
0231         DEBUG_PRINT_L4("\t\t0x%lx\t%d\n", offset + i, buf[i]);
0232 
0233     return bytes_read;
0234 }
0235 
0236 static int write_adi(int fd, const unsigned char * const buf, int buf_sz)
0237 {
0238     int ret, bytes_written = 0;
0239     long start, end, elapsed_time = 0;
0240 
0241     do {
0242         RDTICK(start);
0243         ret = write(fd, buf + bytes_written, buf_sz - bytes_written);
0244         RDTICK(end);
0245         if (ret < 0)
0246             return -errno;
0247 
0248         elapsed_time += (end - start);
0249         update_stats(&write_stats, elapsed_time, buf_sz);
0250         bytes_written += ret;
0251     } while (bytes_written < buf_sz);
0252 
0253     DEBUG_PRINT_T("\twrite elapsed timed = %ld\n", elapsed_time);
0254     DEBUG_PRINT_L3("\tWrote %d of %d bytes\n", bytes_written, buf_sz);
0255 
0256     return bytes_written;
0257 }
0258 
0259 static int pwrite_adi(int fd, const unsigned char * const buf,
0260               int buf_sz, unsigned long offset)
0261 {
0262     int ret, bytes_written = 0;
0263     unsigned long cur_offset;
0264     long start, end, elapsed_time = 0;
0265 
0266     cur_offset = offset;
0267 
0268     do {
0269         RDTICK(start);
0270         ret = pwrite(fd, buf + bytes_written,
0271                  buf_sz - bytes_written, cur_offset);
0272         RDTICK(end);
0273         if (ret < 0) {
0274             fprintf(stderr, "pwrite(): error %d: %s\n",
0275                 errno, strerror(errno));
0276             return -errno;
0277         }
0278 
0279         elapsed_time += (end - start);
0280         update_stats(&pwrite_stats, elapsed_time, buf_sz);
0281         bytes_written += ret;
0282         cur_offset += ret;
0283 
0284     } while (bytes_written < buf_sz);
0285 
0286     DEBUG_PRINT_T("\tpwrite elapsed timed = %ld\n", elapsed_time);
0287     DEBUG_PRINT_L3("\tWrote %d of %d bytes starting at address 0x%lx\n",
0288                bytes_written, buf_sz, offset);
0289 
0290     return bytes_written;
0291 }
0292 
0293 static off_t seek_adi(int fd, off_t offset, int whence)
0294 {
0295     long start, end;
0296     off_t ret;
0297 
0298     RDTICK(start);
0299     ret = lseek(fd, offset, whence);
0300     RDTICK(end);
0301     DEBUG_PRINT_L2("\tlseek ret = 0x%llx\n", ret);
0302     if (ret < 0)
0303         goto out;
0304 
0305     DEBUG_PRINT_T("\tlseek elapsed timed = %ld\n", end - start);
0306     update_stats(&seek_stats, end - start, 0);
0307 
0308 out:
0309     (void)lseek(fd, 0, SEEK_END);
0310     return ret;
0311 }
0312 
0313 static int test0_prpw_aligned_1byte(int fd)
0314 {
0315     /* somewhat arbitrarily chosen address */
0316     unsigned long paddr =
0317         (end_addr[range_count - 1] - 0x1000) & ~(ADI_BLKSZ - 1);
0318     unsigned char version[1], expected_version;
0319     loff_t offset;
0320     int ret;
0321 
0322     version[0] = random_version();
0323     expected_version = version[0];
0324 
0325     offset = paddr / ADI_BLKSZ;
0326 
0327     ret = pwrite_adi(fd, version, sizeof(version), offset);
0328     if (ret != sizeof(version))
0329         TEST_STEP_FAILURE(ret);
0330 
0331     ret = pread_adi(fd, version, sizeof(version), offset);
0332     if (ret != sizeof(version))
0333         TEST_STEP_FAILURE(ret);
0334 
0335     if (expected_version != version[0]) {
0336         DEBUG_PRINT_L2("\tExpected version %d but read version %d\n",
0337                    expected_version, version[0]);
0338         TEST_STEP_FAILURE(-expected_version);
0339     }
0340 
0341     ret = 0;
0342 out:
0343     RETURN_FROM_TEST(ret);
0344 }
0345 
0346 #define TEST1_VERSION_SZ    4096
0347 static int test1_prpw_aligned_4096bytes(int fd)
0348 {
0349     /* somewhat arbitrarily chosen address */
0350     unsigned long paddr =
0351         (end_addr[range_count - 1] - 0x6000) & ~(ADI_BLKSZ - 1);
0352     unsigned char version[TEST1_VERSION_SZ],
0353         expected_version[TEST1_VERSION_SZ];
0354     loff_t offset;
0355     int ret, i;
0356 
0357     for (i = 0; i < TEST1_VERSION_SZ; i++) {
0358         version[i] = random_version();
0359         expected_version[i] = version[i];
0360     }
0361 
0362     offset = paddr / ADI_BLKSZ;
0363 
0364     ret = pwrite_adi(fd, version, sizeof(version), offset);
0365     if (ret != sizeof(version))
0366         TEST_STEP_FAILURE(ret);
0367 
0368     ret = pread_adi(fd, version, sizeof(version), offset);
0369     if (ret != sizeof(version))
0370         TEST_STEP_FAILURE(ret);
0371 
0372     for (i = 0; i < TEST1_VERSION_SZ; i++) {
0373         if (expected_version[i] != version[i]) {
0374             DEBUG_PRINT_L2(
0375                 "\tExpected version %d but read version %d\n",
0376                 expected_version, version[0]);
0377             TEST_STEP_FAILURE(-expected_version[i]);
0378         }
0379     }
0380 
0381     ret = 0;
0382 out:
0383     RETURN_FROM_TEST(ret);
0384 }
0385 
0386 #define TEST2_VERSION_SZ    10327
0387 static int test2_prpw_aligned_10327bytes(int fd)
0388 {
0389     /* somewhat arbitrarily chosen address */
0390     unsigned long paddr =
0391         (start_addr[0] + 0x6000) & ~(ADI_BLKSZ - 1);
0392     unsigned char version[TEST2_VERSION_SZ],
0393         expected_version[TEST2_VERSION_SZ];
0394     loff_t offset;
0395     int ret, i;
0396 
0397     for (i = 0; i < TEST2_VERSION_SZ; i++) {
0398         version[i] = random_version();
0399         expected_version[i] = version[i];
0400     }
0401 
0402     offset = paddr / ADI_BLKSZ;
0403 
0404     ret = pwrite_adi(fd, version, sizeof(version), offset);
0405     if (ret != sizeof(version))
0406         TEST_STEP_FAILURE(ret);
0407 
0408     ret = pread_adi(fd, version, sizeof(version), offset);
0409     if (ret != sizeof(version))
0410         TEST_STEP_FAILURE(ret);
0411 
0412     for (i = 0; i < TEST2_VERSION_SZ; i++) {
0413         if (expected_version[i] != version[i]) {
0414             DEBUG_PRINT_L2(
0415                 "\tExpected version %d but read version %d\n",
0416                 expected_version, version[0]);
0417             TEST_STEP_FAILURE(-expected_version[i]);
0418         }
0419     }
0420 
0421     ret = 0;
0422 out:
0423     RETURN_FROM_TEST(ret);
0424 }
0425 
0426 #define TEST3_VERSION_SZ    12541
0427 static int test3_prpw_unaligned_12541bytes(int fd)
0428 {
0429     /* somewhat arbitrarily chosen address */
0430     unsigned long paddr =
0431         ((start_addr[0] + 0xC000) & ~(ADI_BLKSZ - 1)) + 17;
0432     unsigned char version[TEST3_VERSION_SZ],
0433         expected_version[TEST3_VERSION_SZ];
0434     loff_t offset;
0435     int ret, i;
0436 
0437     for (i = 0; i < TEST3_VERSION_SZ; i++) {
0438         version[i] = random_version();
0439         expected_version[i] = version[i];
0440     }
0441 
0442     offset = paddr / ADI_BLKSZ;
0443 
0444     ret = pwrite_adi(fd, version, sizeof(version), offset);
0445     if (ret != sizeof(version))
0446         TEST_STEP_FAILURE(ret);
0447 
0448     ret = pread_adi(fd, version, sizeof(version), offset);
0449     if (ret != sizeof(version))
0450         TEST_STEP_FAILURE(ret);
0451 
0452     for (i = 0; i < TEST3_VERSION_SZ; i++) {
0453         if (expected_version[i] != version[i]) {
0454             DEBUG_PRINT_L2(
0455                 "\tExpected version %d but read version %d\n",
0456                 expected_version, version[0]);
0457             TEST_STEP_FAILURE(-expected_version[i]);
0458         }
0459     }
0460 
0461     ret = 0;
0462 out:
0463     RETURN_FROM_TEST(ret);
0464 }
0465 
0466 static int test4_lseek(int fd)
0467 {
0468 #define OFFSET_ADD  (0x100)
0469 #define OFFSET_SUBTRACT (0xFFFFFFF000000000)
0470 
0471     off_t offset_out, offset_in;
0472     int ret;
0473 
0474 
0475     offset_in = 0x123456789abcdef0;
0476     offset_out = seek_adi(fd, offset_in, SEEK_SET);
0477     if (offset_out != offset_in) {
0478         ret = -1;
0479         TEST_STEP_FAILURE(ret);
0480     }
0481 
0482     /* seek to the current offset.  this should return EINVAL */
0483     offset_out = seek_adi(fd, offset_in, SEEK_SET);
0484     if (offset_out < 0 && errno == EINVAL)
0485         DEBUG_PRINT_L2(
0486             "\tSEEK_SET failed as designed. Not an error\n");
0487     else {
0488         ret = -2;
0489         TEST_STEP_FAILURE(ret);
0490     }
0491 
0492     offset_out = seek_adi(fd, 0, SEEK_CUR);
0493     if (offset_out != offset_in) {
0494         ret = -3;
0495         TEST_STEP_FAILURE(ret);
0496     }
0497 
0498     offset_out = seek_adi(fd, OFFSET_ADD, SEEK_CUR);
0499     if (offset_out != (offset_in + OFFSET_ADD)) {
0500         ret = -4;
0501         TEST_STEP_FAILURE(ret);
0502     }
0503 
0504     offset_out = seek_adi(fd, OFFSET_SUBTRACT, SEEK_CUR);
0505     if (offset_out != (offset_in + OFFSET_ADD + OFFSET_SUBTRACT)) {
0506         ret = -5;
0507         TEST_STEP_FAILURE(ret);
0508     }
0509 
0510     ret = 0;
0511 out:
0512     RETURN_FROM_TEST(ret);
0513 }
0514 
0515 static int test5_rw_aligned_1byte(int fd)
0516 {
0517     /* somewhat arbitrarily chosen address */
0518     unsigned long paddr =
0519         (end_addr[range_count - 1] - 0xF000) & ~(ADI_BLKSZ - 1);
0520     unsigned char version, expected_version;
0521     loff_t offset;
0522     off_t oret;
0523     int ret;
0524 
0525     offset = paddr / ADI_BLKSZ;
0526     version = expected_version = random_version();
0527 
0528     oret = seek_adi(fd, offset, SEEK_SET);
0529     if (oret != offset) {
0530         ret = -1;
0531         TEST_STEP_FAILURE(ret);
0532     }
0533 
0534     ret = write_adi(fd, &version, sizeof(version));
0535     if (ret != sizeof(version))
0536         TEST_STEP_FAILURE(ret);
0537 
0538     oret = seek_adi(fd, offset, SEEK_SET);
0539     if (oret != offset) {
0540         ret = -1;
0541         TEST_STEP_FAILURE(ret);
0542     }
0543 
0544     ret = read_adi(fd, &version, sizeof(version));
0545     if (ret != sizeof(version))
0546         TEST_STEP_FAILURE(ret);
0547 
0548     if (expected_version != version) {
0549         DEBUG_PRINT_L2("\tExpected version %d but read version %d\n",
0550                    expected_version, version);
0551         TEST_STEP_FAILURE(-expected_version);
0552     }
0553 
0554     ret = 0;
0555 out:
0556     RETURN_FROM_TEST(ret);
0557 }
0558 
0559 #define TEST6_VERSION_SZ        9434
0560 static int test6_rw_aligned_9434bytes(int fd)
0561 {
0562     /* somewhat arbitrarily chosen address */
0563     unsigned long paddr =
0564         (end_addr[range_count - 1] - 0x5F000) & ~(ADI_BLKSZ - 1);
0565     unsigned char version[TEST6_VERSION_SZ],
0566               expected_version[TEST6_VERSION_SZ];
0567     loff_t offset;
0568     off_t oret;
0569     int ret, i;
0570 
0571     offset = paddr / ADI_BLKSZ;
0572     for (i = 0; i < TEST6_VERSION_SZ; i++)
0573         version[i] = expected_version[i] = random_version();
0574 
0575     oret = seek_adi(fd, offset, SEEK_SET);
0576     if (oret != offset) {
0577         ret = -1;
0578         TEST_STEP_FAILURE(ret);
0579     }
0580 
0581     ret = write_adi(fd, version, sizeof(version));
0582     if (ret != sizeof(version))
0583         TEST_STEP_FAILURE(ret);
0584 
0585     memset(version, 0, TEST6_VERSION_SZ);
0586 
0587     oret = seek_adi(fd, offset, SEEK_SET);
0588     if (oret != offset) {
0589         ret = -1;
0590         TEST_STEP_FAILURE(ret);
0591     }
0592 
0593     ret = read_adi(fd, version, sizeof(version));
0594     if (ret != sizeof(version))
0595         TEST_STEP_FAILURE(ret);
0596 
0597     for (i = 0; i < TEST6_VERSION_SZ; i++) {
0598         if (expected_version[i] != version[i]) {
0599             DEBUG_PRINT_L2(
0600                 "\tExpected version %d but read version %d\n",
0601                 expected_version[i], version[i]);
0602             TEST_STEP_FAILURE(-expected_version[i]);
0603         }
0604     }
0605 
0606     ret = 0;
0607 out:
0608     RETURN_FROM_TEST(ret);
0609 }
0610 
0611 #define TEST7_VERSION_SZ        14963
0612 static int test7_rw_aligned_14963bytes(int fd)
0613 {
0614     /* somewhat arbitrarily chosen address */
0615     unsigned long paddr =
0616       ((start_addr[range_count - 1] + 0xF000) & ~(ADI_BLKSZ - 1)) + 39;
0617     unsigned char version[TEST7_VERSION_SZ],
0618               expected_version[TEST7_VERSION_SZ];
0619     loff_t offset;
0620     off_t oret;
0621     int ret, i;
0622 
0623     offset = paddr / ADI_BLKSZ;
0624     for (i = 0; i < TEST7_VERSION_SZ; i++) {
0625         version[i] = random_version();
0626         expected_version[i] = version[i];
0627     }
0628 
0629     oret = seek_adi(fd, offset, SEEK_SET);
0630     if (oret != offset) {
0631         ret = -1;
0632         TEST_STEP_FAILURE(ret);
0633     }
0634 
0635     ret = write_adi(fd, version, sizeof(version));
0636     if (ret != sizeof(version))
0637         TEST_STEP_FAILURE(ret);
0638 
0639     memset(version, 0, TEST7_VERSION_SZ);
0640 
0641     oret = seek_adi(fd, offset, SEEK_SET);
0642     if (oret != offset) {
0643         ret = -1;
0644         TEST_STEP_FAILURE(ret);
0645     }
0646 
0647     ret = read_adi(fd, version, sizeof(version));
0648     if (ret != sizeof(version))
0649         TEST_STEP_FAILURE(ret);
0650 
0651     for (i = 0; i < TEST7_VERSION_SZ; i++) {
0652         if (expected_version[i] != version[i]) {
0653             DEBUG_PRINT_L2(
0654                 "\tExpected version %d but read version %d\n",
0655                 expected_version[i], version[i]);
0656             TEST_STEP_FAILURE(-expected_version[i]);
0657         }
0658 
0659         paddr += ADI_BLKSZ;
0660     }
0661 
0662     ret = 0;
0663 out:
0664     RETURN_FROM_TEST(ret);
0665 }
0666 
0667 static int (*tests[])(int fd) = {
0668     test0_prpw_aligned_1byte,
0669     test1_prpw_aligned_4096bytes,
0670     test2_prpw_aligned_10327bytes,
0671     test3_prpw_unaligned_12541bytes,
0672     test4_lseek,
0673     test5_rw_aligned_1byte,
0674     test6_rw_aligned_9434bytes,
0675     test7_rw_aligned_14963bytes,
0676 };
0677 #define TEST_COUNT  ARRAY_SIZE(tests)
0678 
0679 int main(int argc, char *argv[])
0680 {
0681     int fd, ret, test;
0682 
0683     ret = build_memory_map();
0684     if (ret < 0)
0685         return ret;
0686 
0687     fd = open("/dev/adi", O_RDWR);
0688     if (fd < 0) {
0689         fprintf(stderr, "open: error %d: %s\n",
0690             errno, strerror(errno));
0691         return -errno;
0692     }
0693 
0694     for (test = 0; test < TEST_COUNT; test++) {
0695         DEBUG_PRINT_L1("Running test #%d\n", test);
0696 
0697         ret = (*tests[test])(fd);
0698         if (ret != 0)
0699             ksft_test_result_fail("Test #%d failed: error %d\n",
0700                           test, ret);
0701         else
0702             ksft_test_result_pass("Test #%d passed\n", test);
0703     }
0704 
0705     print_stats();
0706     close(fd);
0707 
0708     if (ksft_get_fail_cnt() > 0)
0709         ksft_exit_fail();
0710     else
0711         ksft_exit_pass();
0712 
0713     /* it's impossible to get here, but the compiler throws a warning
0714      * about control reaching the end of non-void function.  bah.
0715      */
0716     return 0;
0717 }