1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Test cases for API provided by resource.c and ioport.h 4 */ 5 6 #include <kunit/test.h> 7 #include <linux/ioport.h> 8 #include <linux/kernel.h> 9 #include <linux/string.h> 10 11 #define R0_START 0x0000 12 #define R0_END 0xffff 13 #define R1_START 0x1234 14 #define R1_END 0x2345 15 #define R2_START 0x4567 16 #define R2_END 0x5678 17 #define R3_START 0x6789 18 #define R3_END 0x789a 19 #define R4_START 0x2000 20 #define R4_END 0x7000 21 22 static struct resource r0 = { .start = R0_START, .end = R0_END }; 23 static struct resource r1 = { .start = R1_START, .end = R1_END }; 24 static struct resource r2 = { .start = R2_START, .end = R2_END }; 25 static struct resource r3 = { .start = R3_START, .end = R3_END }; 26 static struct resource r4 = { .start = R4_START, .end = R4_END }; 27 28 struct result { 29 struct resource *r1; 30 struct resource *r2; 31 struct resource r; 32 bool ret; 33 }; 34 35 static struct result results_for_union[] = { 36 { 37 .r1 = &r1, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, 38 }, { 39 .r1 = &r2, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, 40 }, { 41 .r1 = &r3, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, 42 }, { 43 .r1 = &r4, .r2 = &r0, .r.start = R0_START, .r.end = R0_END, .ret = true, 44 }, { 45 .r1 = &r2, .r2 = &r1, .ret = false, 46 }, { 47 .r1 = &r3, .r2 = &r1, .ret = false, 48 }, { 49 .r1 = &r4, .r2 = &r1, .r.start = R1_START, .r.end = R4_END, .ret = true, 50 }, { 51 .r1 = &r2, .r2 = &r3, .ret = false, 52 }, { 53 .r1 = &r2, .r2 = &r4, .r.start = R4_START, .r.end = R4_END, .ret = true, 54 }, { 55 .r1 = &r3, .r2 = &r4, .r.start = R4_START, .r.end = R3_END, .ret = true, 56 }, 57 }; 58 59 static struct result results_for_intersection[] = { 60 { 61 .r1 = &r1, .r2 = &r0, .r.start = R1_START, .r.end = R1_END, .ret = true, 62 }, { 63 .r1 = &r2, .r2 = &r0, .r.start = R2_START, .r.end = R2_END, .ret = true, 64 }, { 65 .r1 = &r3, .r2 = &r0, .r.start = R3_START, .r.end = R3_END, .ret = true, 66 }, { 67 .r1 = &r4, .r2 = &r0, .r.start = R4_START, .r.end = R4_END, .ret = true, 68 }, { 69 .r1 = &r2, .r2 = &r1, .ret = false, 70 }, { 71 .r1 = &r3, .r2 = &r1, .ret = false, 72 }, { 73 .r1 = &r4, .r2 = &r1, .r.start = R4_START, .r.end = R1_END, .ret = true, 74 }, { 75 .r1 = &r2, .r2 = &r3, .ret = false, 76 }, { 77 .r1 = &r2, .r2 = &r4, .r.start = R2_START, .r.end = R2_END, .ret = true, 78 }, { 79 .r1 = &r3, .r2 = &r4, .r.start = R3_START, .r.end = R4_END, .ret = true, 80 }, 81 }; 82 83 static void resource_do_test(struct kunit *test, bool ret, struct resource *r, 84 bool exp_ret, struct resource *exp_r, 85 struct resource *r1, struct resource *r2) 86 { 87 KUNIT_EXPECT_EQ_MSG(test, ret, exp_ret, "Resources %pR %pR", r1, r2); 88 KUNIT_EXPECT_EQ_MSG(test, r->start, exp_r->start, "Start elements are not equal"); 89 KUNIT_EXPECT_EQ_MSG(test, r->end, exp_r->end, "End elements are not equal"); 90 } 91 92 static void resource_do_union_test(struct kunit *test, struct result *r) 93 { 94 struct resource result; 95 bool ret; 96 97 memset(&result, 0, sizeof(result)); 98 ret = resource_union(r->r1, r->r2, &result); 99 resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2); 100 101 memset(&result, 0, sizeof(result)); 102 ret = resource_union(r->r2, r->r1, &result); 103 resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1); 104 } 105 106 static void resource_test_union(struct kunit *test) 107 { 108 struct result *r = results_for_union; 109 unsigned int i = 0; 110 111 do { 112 resource_do_union_test(test, &r[i]); 113 } while (++i < ARRAY_SIZE(results_for_union)); 114 } 115 116 static void resource_do_intersection_test(struct kunit *test, struct result *r) 117 { 118 struct resource result; 119 bool ret; 120 121 memset(&result, 0, sizeof(result)); 122 ret = resource_intersection(r->r1, r->r2, &result); 123 resource_do_test(test, ret, &result, r->ret, &r->r, r->r1, r->r2); 124 125 memset(&result, 0, sizeof(result)); 126 ret = resource_intersection(r->r2, r->r1, &result); 127 resource_do_test(test, ret, &result, r->ret, &r->r, r->r2, r->r1); 128 } 129 130 static void resource_test_intersection(struct kunit *test) 131 { 132 struct result *r = results_for_intersection; 133 unsigned int i = 0; 134 135 do { 136 resource_do_intersection_test(test, &r[i]); 137 } while (++i < ARRAY_SIZE(results_for_intersection)); 138 } 139 140 static struct kunit_case resource_test_cases[] = { 141 KUNIT_CASE(resource_test_union), 142 KUNIT_CASE(resource_test_intersection), 143 {} 144 }; 145 146 static struct kunit_suite resource_test_suite = { 147 .name = "resource", 148 .test_cases = resource_test_cases, 149 }; 150 kunit_test_suite(resource_test_suite); 151 152 MODULE_DESCRIPTION("I/O Port & Memory Resource manager unit tests"); 153 MODULE_LICENSE("GPL"); 154