1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | // |
3 | // device-attribute-test.c - An application of Kunit to test implementation for device attributes. |
4 | // |
5 | // Copyright (c) 2023 Takashi Sakamoto |
6 | // |
7 | // This file can not be built independently since it is intentionally included in core-device.c. |
8 | |
9 | #include <kunit/test.h> |
10 | |
11 | // Configuration ROM for AV/C Devices 1.0 (Dec. 12, 2000, 1394 Trading Association) |
12 | // Annex C:Configuration ROM example(informative) |
13 | // C.1 Simple AV/C device |
14 | // |
15 | // Copied from the documentation. |
16 | static const u32 simple_avc_config_rom[] = { |
17 | 0x0404eabf, |
18 | 0x31333934, |
19 | 0xe0646102, |
20 | 0xffffffff, |
21 | 0xffffffff, |
22 | 0x00063287, // root directory. |
23 | 0x03ffffff, |
24 | 0x8100000a, |
25 | 0x17ffffff, |
26 | 0x8100000e, |
27 | 0x0c0083c0, |
28 | 0xd1000001, |
29 | 0x0004442d, // unit 0 directory. |
30 | 0x1200a02d, |
31 | 0x13010001, |
32 | 0x17ffffff, |
33 | 0x81000007, |
34 | 0x0005c915, // leaf for textual descriptor. |
35 | 0x00000000, |
36 | 0x00000000, |
37 | 0x56656e64, |
38 | 0x6f72204e, |
39 | 0x616d6500, |
40 | 0x00057f16, // leaf for textual descriptor. |
41 | 0x00000000, |
42 | 0x00000000, |
43 | 0x4d6f6465, |
44 | 0x6c204e61, |
45 | 0x6d650000, |
46 | }; |
47 | |
48 | // Ibid. |
49 | // Annex A:Consideration for configuration ROM reader design (informative) |
50 | // A.1 Vendor directory |
51 | // |
52 | // Written by hand. |
53 | static const u32 legacy_avc_config_rom[] = { |
54 | 0x04199fe7, |
55 | 0x31333934, |
56 | 0xe0644000, |
57 | 0x00112233, |
58 | 0x44556677, |
59 | 0x0005dace, // root directory. |
60 | 0x03012345, |
61 | 0x0c0083c0, |
62 | 0x8d000009, |
63 | 0xd1000002, |
64 | 0xc3000004, |
65 | 0x0002e107, // unit 0 directory. |
66 | 0x12abcdef, |
67 | 0x13543210, |
68 | 0x0002cb73, // vendor directory. |
69 | 0x17fedcba, |
70 | 0x81000004, |
71 | 0x00026dc1, // leaf for EUI-64. |
72 | 0x00112233, |
73 | 0x44556677, |
74 | 0x00050e84, // leaf for textual descriptor. |
75 | 0x00000000, |
76 | 0x00000000, |
77 | 0x41424344, |
78 | 0x45464748, |
79 | 0x494a0000, |
80 | }; |
81 | |
82 | static void device_attr_simple_avc(struct kunit *test) |
83 | { |
84 | static const struct fw_device node = { |
85 | .device = { |
86 | .type = &fw_device_type, |
87 | }, |
88 | .config_rom = simple_avc_config_rom, |
89 | .config_rom_length = sizeof(simple_avc_config_rom), |
90 | }; |
91 | static const struct fw_unit unit0 = { |
92 | .device = { |
93 | .type = &fw_unit_type, |
94 | .parent = (struct device *)&node.device, |
95 | }, |
96 | .directory = &simple_avc_config_rom[12], |
97 | }; |
98 | struct device *node_dev = (struct device *)&node.device; |
99 | struct device *unit0_dev = (struct device *)&unit0.device; |
100 | static const int unit0_expected_ids[] = {0x00ffffff, 0x00ffffff, 0x0000a02d, 0x00010001}; |
101 | char *buf = kunit_kzalloc(test, PAGE_SIZE, GFP_KERNEL); |
102 | int ids[4] = {0, 0, 0, 0}; |
103 | |
104 | // Ensure associations for node and unit devices. |
105 | |
106 | KUNIT_ASSERT_TRUE(test, is_fw_device(node_dev)); |
107 | KUNIT_ASSERT_FALSE(test, is_fw_unit(node_dev)); |
108 | KUNIT_ASSERT_PTR_EQ(test, fw_device(node_dev), &node); |
109 | |
110 | KUNIT_ASSERT_FALSE(test, is_fw_device(unit0_dev)); |
111 | KUNIT_ASSERT_TRUE(test, is_fw_unit(unit0_dev)); |
112 | KUNIT_ASSERT_PTR_EQ(test, fw_parent_device((&unit0)), &node); |
113 | KUNIT_ASSERT_PTR_EQ(test, fw_unit(unit0_dev), &unit0); |
114 | |
115 | // For entries in root directory. |
116 | |
117 | // Vendor immediate entry is found. |
118 | KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[0].attr, buf), 0); |
119 | KUNIT_EXPECT_STREQ(test, buf, "0xffffff\n" ); |
120 | |
121 | // Model immediate entry is found. |
122 | KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[4].attr, buf), 0); |
123 | KUNIT_EXPECT_STREQ(test, buf, "0xffffff\n" ); |
124 | |
125 | // Descriptor leaf entry for vendor is found. |
126 | KUNIT_EXPECT_GT(test, show_text_leaf(node_dev, &config_rom_attributes[5].attr, buf), 0); |
127 | KUNIT_EXPECT_STREQ(test, buf, "Vendor Name\n" ); |
128 | |
129 | // Descriptor leaf entry for model is found. |
130 | KUNIT_EXPECT_GT(test, show_text_leaf(node_dev, &config_rom_attributes[6].attr, buf), 0); |
131 | KUNIT_EXPECT_STREQ(test, buf, "Model Name\n" ); |
132 | |
133 | // For entries in unit 0 directory. |
134 | |
135 | // Vendor immediate entry is not found. |
136 | KUNIT_EXPECT_LT(test, show_immediate(unit0_dev, &config_rom_attributes[0].attr, buf), 0); |
137 | |
138 | // Model immediate entry is found. |
139 | KUNIT_EXPECT_GT(test, show_immediate(unit0_dev, &config_rom_attributes[4].attr, buf), 0); |
140 | KUNIT_EXPECT_STREQ(test, buf, "0xffffff\n" ); |
141 | |
142 | // Descriptor leaf entry for vendor is not found. |
143 | KUNIT_EXPECT_LT(test, show_text_leaf(unit0_dev, &config_rom_attributes[5].attr, buf), 0); |
144 | |
145 | // Descriptor leaf entry for model is found. |
146 | KUNIT_EXPECT_GT(test, show_text_leaf(unit0_dev, &config_rom_attributes[6].attr, buf), 0); |
147 | KUNIT_EXPECT_STREQ(test, buf, "Model Name\n" ); |
148 | |
149 | // Specifier_ID immediate entry is found. |
150 | KUNIT_EXPECT_GT(test, show_immediate(unit0_dev, &config_rom_attributes[2].attr, buf), 0); |
151 | KUNIT_EXPECT_STREQ(test, buf, "0x00a02d\n" ); |
152 | |
153 | // Version immediate entry is found. |
154 | KUNIT_EXPECT_GT(test, show_immediate(unit0_dev, &config_rom_attributes[3].attr, buf), 0); |
155 | KUNIT_EXPECT_STREQ(test, buf, "0x010001\n" ); |
156 | |
157 | kunit_kfree(test, ptr: buf); |
158 | |
159 | get_modalias_ids(unit: &unit0, id: ids); |
160 | KUNIT_EXPECT_MEMEQ(test, ids, unit0_expected_ids, sizeof(ids)); |
161 | } |
162 | |
163 | static void device_attr_legacy_avc(struct kunit *test) |
164 | { |
165 | static const struct fw_device node = { |
166 | .device = { |
167 | .type = &fw_device_type, |
168 | }, |
169 | .config_rom = legacy_avc_config_rom, |
170 | .config_rom_length = sizeof(legacy_avc_config_rom), |
171 | }; |
172 | static const struct fw_unit unit0 = { |
173 | .device = { |
174 | .type = &fw_unit_type, |
175 | .parent = (struct device *)&node.device, |
176 | }, |
177 | .directory = &legacy_avc_config_rom[11], |
178 | }; |
179 | struct device *node_dev = (struct device *)&node.device; |
180 | struct device *unit0_dev = (struct device *)&unit0.device; |
181 | static const int unit0_expected_ids[] = {0x00012345, 0x00fedcba, 0x00abcdef, 0x00543210}; |
182 | char *buf = kunit_kzalloc(test, PAGE_SIZE, GFP_KERNEL); |
183 | int ids[4] = {0, 0, 0, 0}; |
184 | |
185 | // Ensure associations for node and unit devices. |
186 | |
187 | KUNIT_ASSERT_TRUE(test, is_fw_device(node_dev)); |
188 | KUNIT_ASSERT_FALSE(test, is_fw_unit(node_dev)); |
189 | KUNIT_ASSERT_PTR_EQ(test, fw_device((node_dev)), &node); |
190 | |
191 | KUNIT_ASSERT_FALSE(test, is_fw_device(unit0_dev)); |
192 | KUNIT_ASSERT_TRUE(test, is_fw_unit(unit0_dev)); |
193 | KUNIT_ASSERT_PTR_EQ(test, fw_parent_device((&unit0)), &node); |
194 | KUNIT_ASSERT_PTR_EQ(test, fw_unit(unit0_dev), &unit0); |
195 | |
196 | // For entries in root directory. |
197 | |
198 | // Vendor immediate entry is found. |
199 | KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[0].attr, buf), 0); |
200 | KUNIT_EXPECT_STREQ(test, buf, "0x012345\n" ); |
201 | |
202 | // Model immediate entry is found. |
203 | KUNIT_EXPECT_GT(test, show_immediate(node_dev, &config_rom_attributes[4].attr, buf), 0); |
204 | KUNIT_EXPECT_STREQ(test, buf, "0xfedcba\n" ); |
205 | |
206 | // Descriptor leaf entry for vendor is not found. |
207 | KUNIT_EXPECT_LT(test, show_text_leaf(node_dev, &config_rom_attributes[5].attr, buf), 0); |
208 | |
209 | // Descriptor leaf entry for model is found. |
210 | KUNIT_EXPECT_GT(test, show_text_leaf(node_dev, &config_rom_attributes[6].attr, buf), 0); |
211 | KUNIT_EXPECT_STREQ(test, buf, "ABCDEFGHIJ\n" ); |
212 | |
213 | // For entries in unit 0 directory. |
214 | |
215 | // Vendor immediate entry is not found. |
216 | KUNIT_EXPECT_LT(test, show_immediate(unit0_dev, &config_rom_attributes[0].attr, buf), 0); |
217 | |
218 | // Model immediate entry is not found. |
219 | KUNIT_EXPECT_LT(test, show_immediate(unit0_dev, &config_rom_attributes[4].attr, buf), 0); |
220 | |
221 | // Descriptor leaf entry for vendor is not found. |
222 | KUNIT_EXPECT_LT(test, show_text_leaf(unit0_dev, &config_rom_attributes[5].attr, buf), 0); |
223 | |
224 | // Descriptor leaf entry for model is not found. |
225 | KUNIT_EXPECT_LT(test, show_text_leaf(unit0_dev, &config_rom_attributes[6].attr, buf), 0); |
226 | |
227 | // Specifier_ID immediate entry is found. |
228 | KUNIT_EXPECT_GT(test, show_immediate(unit0_dev, &config_rom_attributes[2].attr, buf), 0); |
229 | KUNIT_EXPECT_STREQ(test, buf, "0xabcdef\n" ); |
230 | |
231 | // Version immediate entry is found. |
232 | KUNIT_EXPECT_GT(test, show_immediate(unit0_dev, &config_rom_attributes[3].attr, buf), 0); |
233 | KUNIT_EXPECT_STREQ(test, buf, "0x543210\n" ); |
234 | |
235 | kunit_kfree(test, ptr: buf); |
236 | |
237 | get_modalias_ids(unit: &unit0, id: ids); |
238 | KUNIT_EXPECT_MEMEQ(test, ids, unit0_expected_ids, sizeof(ids)); |
239 | } |
240 | |
241 | static struct kunit_case device_attr_test_cases[] = { |
242 | KUNIT_CASE(device_attr_simple_avc), |
243 | KUNIT_CASE(device_attr_legacy_avc), |
244 | {} |
245 | }; |
246 | |
247 | static struct kunit_suite device_attr_test_suite = { |
248 | .name = "firewire-device-attribute" , |
249 | .test_cases = device_attr_test_cases, |
250 | }; |
251 | kunit_test_suite(device_attr_test_suite); |
252 | |