1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // node-tree-test.c - An application of Kunit to test node tree. 4 // 5 // Copyright (c) 2026 Takashi Sakamoto 6 // 7 // This file can not be built independently since it is intentionally included in core-topology.c. 8 9 #include <kunit/test.h> 10 #include <kunit/test-bug.h> 11 #include <kunit/device.h> 12 13 struct private_data { 14 struct fw_card *card; 15 unsigned int release_count; 16 }; 17 18 static int node_tree_test_init(struct kunit *test) 19 { 20 struct private_data *data; 21 22 data = kunit_kzalloc(test, sizeof(*data), GFP_KERNEL); 23 KUNIT_ASSERT_NOT_NULL(test, data); 24 25 data->card = kunit_kzalloc(test, sizeof(struct fw_card), GFP_KERNEL); 26 KUNIT_ASSERT_NOT_NULL(test, data->card); 27 28 data->card->device = kunit_device_register(test, "dummy-device"); 29 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, data->card->device); 30 31 test->priv = data; 32 33 return 0; 34 } 35 36 static void node_tree_test_exit(struct kunit *test) 37 { 38 struct private_data *data = test->priv; 39 40 kunit_device_unregister(test, data->card->device); 41 kunit_kfree(test, data->card); 42 kunit_kfree(test, data); 43 } 44 45 static void release_fw_node(struct fw_card *card, struct fw_node *node, struct fw_node *parent) 46 { 47 struct private_data *data = kunit_get_current_test()->priv; 48 49 fw_node_put(node); 50 ++data->release_count; 51 } 52 53 static void node_tree_test_two_nodes(struct kunit *test) 54 { 55 // root 56 // ++============++ 57 // || phy 1 || 58 // || P0 P1 P2 || 59 // ++===|==|==|==++ 60 // | 61 // +-----+ 62 // | 63 // ++===|==x==x==++ 64 // || P0 P1 P2 || 65 // || phy 0 || 66 // ++============++ 67 // 68 static const u32 self_id_sequence[] = { 69 0x80000080, 70 0x8100005e, 71 }; 72 struct private_data *data = test->priv; 73 struct fw_card *card = data->card; 74 75 card->node_id = LOCAL_BUS | 0x01; 76 77 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 78 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 79 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 80 81 struct fw_node *node = card->root_node; 82 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 83 KUNIT_EXPECT_EQ(test, node->port_count, 3); 84 KUNIT_EXPECT_NULL(test, node->ports[0]); 85 KUNIT_EXPECT_NULL(test, node->ports[1]); 86 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 87 88 struct fw_node *parent = node; 89 node = parent->ports[2]; 90 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 91 KUNIT_EXPECT_EQ(test, node->port_count, 1); 92 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 93 94 ++card->color; 95 for_each_fw_node(card, card->root_node, release_fw_node); 96 KUNIT_EXPECT_EQ(test, data->release_count, 2); 97 } 98 99 static void node_tree_test_two_nodes_1394a(struct kunit *test) 100 { 101 // root 102 // ++===============++ 103 // || phy 0 || 104 // || P0 P1 P2 P3 || 105 // ++===|==|==|==|==++ 106 // | 107 // +--+ 108 // | 109 // ++===|==|==|==|==|==++ 110 // || P0 P1 P2 P3 P4 || 111 // || phy 1 || 112 // ++==================++ 113 // 114 // NOTE: Just for Self-ID Packets Zero and One. 115 static const u32 self_id_sequence[] = { 116 0x80000065, 0x80814000, 117 0x8100005d, 0x81810000, 118 }; 119 struct private_data *data = test->priv; 120 struct fw_card *card = data->card; 121 122 card->node_id = LOCAL_BUS | 0x01; 123 124 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 125 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 126 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 127 128 struct fw_node *node = card->root_node; 129 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 130 KUNIT_EXPECT_EQ(test, node->port_count, 4); 131 KUNIT_EXPECT_NULL(test, node->ports[0]); 132 KUNIT_EXPECT_NULL(test, node->ports[1]); 133 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 134 KUNIT_EXPECT_NULL(test, node->ports[3]); 135 136 struct fw_node *parent = node; 137 node = parent->ports[2]; 138 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 139 KUNIT_EXPECT_EQ(test, node->port_count, 5); 140 KUNIT_EXPECT_NULL(test, node->ports[0]); 141 KUNIT_EXPECT_PTR_EQ(test, node->ports[1], parent); 142 KUNIT_EXPECT_NULL(test, node->ports[2]); 143 KUNIT_EXPECT_NULL(test, node->ports[3]); 144 KUNIT_EXPECT_NULL(test, node->ports[4]); 145 146 ++card->color; 147 for_each_fw_node(card, card->root_node, release_fw_node); 148 KUNIT_EXPECT_EQ(test, data->release_count, 2); 149 } 150 151 static void node_tree_test_three_nodes_case0(struct kunit *test) 152 { 153 // root 154 // ++============++ 155 // || phy 2 || 156 // || P0 P1 P2 || 157 // ++===|==|==|==++ 158 // | | 159 // +--+ +-----------------+ 160 // | | 161 // ++===|==|==x==++ ++===|==|==|==++ 162 // || P0 P1 P2 || || P0 P1 P2 || 163 // || phy 0 || || phy 1 || 164 // ++============++ ++============++ 165 // 166 static const u32 self_id_sequence[] = { 167 0x80000060, 168 0x81000058, 169 0x820000dc, 170 }; 171 struct private_data *data = test->priv; 172 struct fw_card *card = data->card; 173 174 card->node_id = LOCAL_BUS | 0x02; 175 176 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 177 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 178 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 179 180 struct fw_node *node = card->root_node; 181 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 182 KUNIT_EXPECT_EQ(test, node->port_count, 3); 183 KUNIT_EXPECT_NOT_NULL(test, node->ports[0]); 184 KUNIT_EXPECT_NULL(test, node->ports[1]); 185 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 186 187 struct fw_node *parent = node; 188 node = parent->ports[0]; 189 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 190 KUNIT_EXPECT_EQ(test, node->port_count, 2); 191 KUNIT_EXPECT_NULL(test, node->ports[0]); 192 KUNIT_EXPECT_PTR_EQ(test, node->ports[1], parent); 193 194 node = parent->ports[2]; 195 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 196 KUNIT_EXPECT_EQ(test, node->port_count, 3); 197 KUNIT_EXPECT_NULL(test, node->ports[0]); 198 KUNIT_EXPECT_NULL(test, node->ports[1]); 199 KUNIT_EXPECT_PTR_EQ(test, node->ports[2], parent); 200 201 ++card->color; 202 for_each_fw_node(card, card->root_node, release_fw_node); 203 KUNIT_EXPECT_EQ(test, data->release_count, 3); 204 } 205 206 static void node_tree_test_three_nodes_case1(struct kunit *test) 207 { 208 // root 209 // ++============++ 210 // || phy 2 || 211 // || P0 P1 P2 || 212 // ++===|==|==x==++ 213 // | 214 // | +-----------+ 215 // | | | 216 // ++===|==|==|==++ ++===|==x==x==++ 217 // || P0 P1 P2 || || P0 P1 P2 || 218 // || phy 1 || || phy 0 || 219 // ++============++ ++============++ 220 // 221 static const u32 self_id_sequence[] = { 222 0x80000080, 223 0x8100006c, 224 0x82000070, 225 }; 226 struct private_data *data = test->priv; 227 struct fw_card *card = data->card; 228 229 card->node_id = LOCAL_BUS | 0x02; 230 231 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 232 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 233 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 234 235 struct fw_node *node = card->root_node; 236 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 237 KUNIT_EXPECT_EQ(test, node->port_count, 2); 238 KUNIT_EXPECT_NULL(test, node->ports[0]); 239 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 240 241 struct fw_node *parent = node; 242 node = parent->ports[1]; 243 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 244 KUNIT_EXPECT_EQ(test, node->port_count, 3); 245 KUNIT_EXPECT_NULL(test, node->ports[0]); 246 KUNIT_EXPECT_PTR_EQ(test, node->ports[1], parent); 247 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 248 249 parent = node; 250 node = parent->ports[2]; 251 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 252 KUNIT_EXPECT_EQ(test, node->port_count, 1); 253 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 254 255 ++card->color; 256 for_each_fw_node(card, card->root_node, release_fw_node); 257 KUNIT_EXPECT_EQ(test, data->release_count, 3); 258 } 259 260 static void node_tree_test_four_nodes_case0(struct kunit *test) 261 { 262 // root 263 // ++============++ 264 // || phy 3 || 265 // || P0 P1 P2 || 266 // ++===|==|==|==++ 267 // | 268 // | +-----------+ +--------------+ 269 // | | | | | 270 // ++===|==|==|==++ ++===|==|==x==++ ++===|==x==x==++ 271 // || P0 P1 P2 || || P0 P1 P2 || || P0 P1 P2 || 272 // || phy 2 || || phy 1 || || phy 0 || 273 // ++============++ ++============++ ++============++ 274 // 275 static const u32 self_id_sequence[] = { 276 0x80000080, 277 0x810000b0, 278 0x8200006c, 279 0x83000074, 280 }; 281 struct private_data *data = test->priv; 282 struct fw_card *card = data->card; 283 284 card->node_id = LOCAL_BUS | 0x03; 285 286 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 287 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 288 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 289 290 struct fw_node *node = card->root_node; 291 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x03); 292 KUNIT_EXPECT_EQ(test, node->port_count, 3); 293 KUNIT_EXPECT_NULL(test, node->ports[0]); 294 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 295 KUNIT_EXPECT_NULL(test, node->ports[2]); 296 297 struct fw_node *parent = node; 298 node = parent->ports[1]; 299 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 300 KUNIT_EXPECT_EQ(test, node->port_count, 3); 301 KUNIT_EXPECT_NULL(test, node->ports[0]); 302 KUNIT_EXPECT_PTR_EQ(test, node->ports[1], parent); 303 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 304 305 parent = node; 306 node = parent->ports[2]; 307 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 308 KUNIT_EXPECT_EQ(test, node->port_count, 2); 309 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 310 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 311 312 parent = node; 313 node = parent->ports[1]; 314 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 315 KUNIT_EXPECT_EQ(test, node->port_count, 1); 316 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 317 318 ++card->color; 319 for_each_fw_node(card, card->root_node, release_fw_node); 320 KUNIT_EXPECT_EQ(test, data->release_count, 4); 321 } 322 323 static void node_tree_test_four_nodes_case1(struct kunit *test) 324 { 325 // root 326 // ++============++ 327 // || phy 3 || 328 // || P0 P1 P2 || 329 // ++===|==|==x==++ 330 // | 331 // | +--------------------------------+ 332 // | | +-----------+ | 333 // ++===|==|==|==++ ++===|==x==x==++ ++===|==|==|==++ 334 // || P0 P1 P2 || || P0 P1 P2 || || P0 P1 P2 || 335 // || phy 2 || || phy 1 || || phy 0 || 336 // ++============++ ++============++ ++============++ 337 // 338 static const u32 self_id_sequence[] = { 339 0x80000094, 340 0x81000080, 341 0x820000bc, 342 0x830000d0, 343 }; 344 struct private_data *data = test->priv; 345 struct fw_card *card = data->card; 346 347 card->node_id = LOCAL_BUS | 0x03; 348 349 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 350 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 351 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 352 353 struct fw_node *node = card->root_node; 354 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x03); 355 KUNIT_EXPECT_EQ(test, node->port_count, 2); 356 KUNIT_EXPECT_NOT_NULL(test, node->ports[0]); 357 KUNIT_EXPECT_NULL(test, node->ports[1]); 358 359 struct fw_node *parent = node; 360 node = parent->ports[0]; 361 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 362 KUNIT_EXPECT_EQ(test, node->port_count, 3); 363 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 364 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 365 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 366 367 parent = node; 368 node = parent->ports[2]; 369 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 370 KUNIT_EXPECT_EQ(test, node->port_count, 1); 371 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 372 373 node = parent->ports[1]; 374 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 375 KUNIT_EXPECT_EQ(test, node->port_count, 3); 376 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 377 KUNIT_EXPECT_NULL(test, node->ports[1]); 378 KUNIT_EXPECT_NULL(test, node->ports[2]); 379 380 ++card->color; 381 for_each_fw_node(card, card->root_node, release_fw_node); 382 KUNIT_EXPECT_EQ(test, data->release_count, 4); 383 } 384 385 static void node_tree_test_four_nodes_case2(struct kunit *test) 386 { 387 // root 388 // ++============++ 389 // || phy 3 || 390 // || P0 P1 P2 || 391 // ++===|==|==|==++ 392 // | | 393 // | +-----------------------------+ 394 // | +--------------+ | 395 // ++===|==|==x==++ ++===|==|==|==++ ++===|==x==x==++ 396 // || P0 P1 P2 || || P0 P1 P2 || || P0 P1 P2 || 397 // || phy 1 || || phy 0 || || phy 2 || 398 // ++============++ ++============++ ++============++ 399 // 400 static const u32 self_id_sequence[] = { 401 0x80000094, 402 0x810000b0, 403 0x82000080, 404 0x830000dc, 405 }; 406 struct private_data *data = test->priv; 407 struct fw_card *card = data->card; 408 409 card->node_id = LOCAL_BUS | 0x03; 410 411 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 412 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 413 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 414 415 struct fw_node *node = card->root_node; 416 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x03); 417 KUNIT_EXPECT_EQ(test, node->port_count, 3); 418 KUNIT_EXPECT_NOT_NULL(test, node->ports[0]); 419 KUNIT_EXPECT_NULL(test, node->ports[1]); 420 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 421 422 struct fw_node *parent = node; 423 node = parent->ports[2]; 424 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 425 KUNIT_EXPECT_EQ(test, node->port_count, 1); 426 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 427 428 node = parent->ports[0]; 429 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 430 KUNIT_EXPECT_EQ(test, node->port_count, 2); 431 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 432 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 433 434 parent = node; 435 node = parent->ports[1]; 436 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 437 KUNIT_EXPECT_EQ(test, node->port_count, 3); 438 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 439 KUNIT_EXPECT_NULL(test, node->ports[1]); 440 KUNIT_EXPECT_NULL(test, node->ports[2]); 441 442 ++card->color; 443 for_each_fw_node(card, card->root_node, release_fw_node); 444 KUNIT_EXPECT_EQ(test, data->release_count, 4); 445 } 446 447 static void node_tree_test_four_nodes_case3(struct kunit *test) 448 { 449 // root 450 // ++============++ 451 // || phy 3 || 452 // || P0 P1 P2 || 453 // ++===|==|==|==++ 454 // | | +--------------------------------+ 455 // | +--------------------+ | 456 // | | | 457 // ++===|==|==x==++ ++===|==|==|==++ ++===|==|==x==++ 458 // || P0 P1 P2 || || P0 P1 P2 || || P0 P1 P2 || 459 // || phy 0 || || phy 1 || || phy 2 || 460 // ++============++ ++============++ ++============++ 461 // 462 static const u32 self_id_sequence[] = { 463 0x80000090, 464 0x81000058, 465 0x82000060, 466 0x830000fc, 467 }; 468 struct private_data *data = test->priv; 469 struct fw_card *card = data->card; 470 471 card->node_id = LOCAL_BUS | 0x03; 472 473 card->local_node = build_tree(card, self_id_sequence, ARRAY_SIZE(self_id_sequence), 123); 474 KUNIT_EXPECT_NOT_NULL(test, card->local_node); 475 KUNIT_EXPECT_PTR_EQ(test, card->local_node, card->root_node); 476 477 struct fw_node *node = card->root_node; 478 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x03); 479 KUNIT_EXPECT_EQ(test, node->port_count, 3); 480 KUNIT_EXPECT_NOT_NULL(test, node->ports[0]); 481 KUNIT_EXPECT_NOT_NULL(test, node->ports[1]); 482 KUNIT_EXPECT_NOT_NULL(test, node->ports[2]); 483 484 struct fw_node *parent = node; 485 node = parent->ports[2]; 486 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x02); 487 KUNIT_EXPECT_EQ(test, node->port_count, 2); 488 KUNIT_EXPECT_NULL(test, node->ports[0]); 489 KUNIT_EXPECT_PTR_EQ(test, node->ports[1], parent); 490 491 node = parent->ports[1]; 492 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x01); 493 KUNIT_EXPECT_EQ(test, node->port_count, 3); 494 KUNIT_EXPECT_NULL(test, node->ports[0]); 495 KUNIT_EXPECT_NULL(test, node->ports[1]); 496 KUNIT_EXPECT_PTR_EQ(test, node->ports[2], parent); 497 498 node = parent->ports[0]; 499 KUNIT_EXPECT_EQ(test, node->node_id, LOCAL_BUS | 0x00); 500 KUNIT_EXPECT_EQ(test, node->port_count, 2); 501 KUNIT_EXPECT_PTR_EQ(test, node->ports[0], parent); 502 KUNIT_EXPECT_NULL(test, node->ports[1]); 503 504 ++card->color; 505 for_each_fw_node(card, card->root_node, release_fw_node); 506 KUNIT_EXPECT_EQ(test, data->release_count, 4); 507 } 508 509 static struct kunit_case node_tree_test_cases[] = { 510 KUNIT_CASE(node_tree_test_two_nodes), 511 KUNIT_CASE(node_tree_test_two_nodes_1394a), 512 KUNIT_CASE(node_tree_test_three_nodes_case0), 513 KUNIT_CASE(node_tree_test_three_nodes_case1), 514 KUNIT_CASE(node_tree_test_four_nodes_case0), 515 KUNIT_CASE(node_tree_test_four_nodes_case1), 516 KUNIT_CASE(node_tree_test_four_nodes_case2), 517 KUNIT_CASE(node_tree_test_four_nodes_case3), 518 {} 519 }; 520 521 static struct kunit_suite node_tree_test_suite = { 522 .name = "firewire-node-tree", 523 .init = node_tree_test_init, 524 .exit = node_tree_test_exit, 525 .test_cases = node_tree_test_cases, 526 }; 527 kunit_test_suite(node_tree_test_suite); 528