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

Configure Feed

Select the types of activity you want to include in your feed.

firewire: core: add enumerator of self ID sequences and its KUnit test

When the state of bus reset finishes, 1394 OHCI driver constructs self ID
sequences, then it calls fw_core_handle_bus_reset() in core function. The
core function enumerates the self ID sequences to build bus topology.

This commit adds a structure and some helper functions for the enumeration,
and adds a KUnit test suite to ensure its expected behaviour.

Link: https://lore.kernel.org/r/20240605235155.116468-2-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+174
+1
drivers/firewire/.kunitconfig
··· 4 4 CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y 5 5 CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y 6 6 CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y 7 + CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=y
+15
drivers/firewire/Kconfig
··· 66 66 For more information on KUnit and unit tests in general, refer 67 67 to the KUnit documentation in Documentation/dev-tools/kunit/. 68 68 69 + config FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST 70 + tristate "KUnit tests for helpers of self ID sequence" if !KUNIT_ALL_TESTS 71 + depends on FIREWIRE && KUNIT 72 + default KUNIT_ALL_TESTS 73 + help 74 + This builds the KUnit tests for helpers of self ID sequence. 75 + 76 + KUnit tests run during boot and output the results to the debug 77 + log in TAP format (https://testanything.org/). Only useful for 78 + kernel devs running KUnit test harness and are not for inclusion 79 + into a production build. 80 + 81 + For more information on KUnit and unit tests in general, refer 82 + to the KUnit documentation in Documentation/dev-tools/kunit/. 83 + 69 84 config FIREWIRE_OHCI 70 85 tristate "OHCI-1394 controllers" 71 86 depends on PCI && FIREWIRE && MMU
+1
drivers/firewire/Makefile
··· 18 18 19 19 obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += uapi-test.o 20 20 obj-$(CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST) += packet-serdes-test.o 21 + obj-$(CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST) += self-id-sequence-helper-test.o
+78
drivers/firewire/phy-packet-definitions.h
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // 3 + // phy-packet-definitions.h - The definitions of phy packet for IEEE 1394. 4 + // 5 + // Copyright (c) 2024 Takashi Sakamoto 6 + 7 + #ifndef _FIREWIRE_PHY_PACKET_DEFINITIONS_H 8 + #define _FIREWIRE_PHY_PACKET_DEFINITIONS_H 9 + 10 + #define SELF_ID_EXTENDED_MASK 0x00800000 11 + #define SELF_ID_EXTENDED_SHIFT 23 12 + #define SELF_ID_MORE_PACKETS_MASK 0x00000001 13 + #define SELF_ID_MORE_PACKETS_SHIFT 0 14 + 15 + #define SELF_ID_EXTENDED_SEQUENCE_MASK 0x00700000 16 + #define SELF_ID_EXTENDED_SEQUENCE_SHIFT 20 17 + 18 + #define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT 4 19 + 20 + static inline bool phy_packet_self_id_get_extended(u32 quadlet) 21 + { 22 + return (quadlet & SELF_ID_EXTENDED_MASK) >> SELF_ID_EXTENDED_SHIFT; 23 + } 24 + 25 + static inline bool phy_packet_self_id_get_more_packets(u32 quadlet) 26 + { 27 + return (quadlet & SELF_ID_MORE_PACKETS_MASK) >> SELF_ID_MORE_PACKETS_SHIFT; 28 + } 29 + 30 + static inline unsigned int phy_packet_self_id_extended_get_sequence(u32 quadlet) 31 + { 32 + return (quadlet & SELF_ID_EXTENDED_SEQUENCE_MASK) >> SELF_ID_EXTENDED_SEQUENCE_SHIFT; 33 + } 34 + 35 + struct self_id_sequence_enumerator { 36 + const u32 *cursor; 37 + unsigned int quadlet_count; 38 + }; 39 + 40 + static inline const u32 *self_id_sequence_enumerator_next( 41 + struct self_id_sequence_enumerator *enumerator, unsigned int *quadlet_count) 42 + { 43 + const u32 *self_id_sequence, *cursor; 44 + u32 quadlet; 45 + unsigned int count; 46 + unsigned int sequence; 47 + 48 + if (enumerator->cursor == NULL || enumerator->quadlet_count == 0) 49 + return ERR_PTR(-ENODATA); 50 + cursor = enumerator->cursor; 51 + count = 1; 52 + 53 + quadlet = *cursor; 54 + sequence = 0; 55 + while (phy_packet_self_id_get_more_packets(quadlet)) { 56 + if (count >= enumerator->quadlet_count || 57 + count >= SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT) 58 + return ERR_PTR(-EPROTO); 59 + ++cursor; 60 + ++count; 61 + quadlet = *cursor; 62 + 63 + if (!phy_packet_self_id_get_extended(quadlet) || 64 + sequence != phy_packet_self_id_extended_get_sequence(quadlet)) 65 + return ERR_PTR(-EPROTO); 66 + ++sequence; 67 + } 68 + 69 + *quadlet_count = count; 70 + self_id_sequence = enumerator->cursor; 71 + 72 + enumerator->cursor += count; 73 + enumerator->quadlet_count -= count; 74 + 75 + return self_id_sequence; 76 + } 77 + 78 + #endif // _FIREWIRE_PHY_PACKET_DEFINITIONS_H
+79
drivers/firewire/self-id-sequence-helper-test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // 3 + // self-id-sequence-helper-test.c - An application of Kunit to test helpers of self ID sequence. 4 + // 5 + // Copyright (c) 2024 Takashi Sakamoto 6 + 7 + #include <kunit/test.h> 8 + 9 + #include "phy-packet-definitions.h" 10 + 11 + static void test_self_id_sequence_enumerator_valid(struct kunit *test) 12 + { 13 + static const u32 valid_sequences[] = { 14 + 0x00000000, 15 + 0x00000001, 0x00800000, 16 + 0x00000001, 0x00800001, 0x00900000, 17 + 0x00000000, 18 + }; 19 + struct self_id_sequence_enumerator enumerator; 20 + const u32 *entry; 21 + unsigned int quadlet_count; 22 + 23 + enumerator.cursor = valid_sequences; 24 + enumerator.quadlet_count = ARRAY_SIZE(valid_sequences); 25 + 26 + entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count); 27 + KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[0]); 28 + KUNIT_EXPECT_EQ(test, quadlet_count, 1); 29 + KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 6); 30 + 31 + entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count); 32 + KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[1]); 33 + KUNIT_EXPECT_EQ(test, quadlet_count, 2); 34 + KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 4); 35 + 36 + entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count); 37 + KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[3]); 38 + KUNIT_EXPECT_EQ(test, quadlet_count, 3); 39 + KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 1); 40 + 41 + entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count); 42 + KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[6]); 43 + KUNIT_EXPECT_EQ(test, quadlet_count, 1); 44 + KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 0); 45 + 46 + entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count); 47 + KUNIT_EXPECT_EQ(test, PTR_ERR(entry), -ENODATA); 48 + } 49 + 50 + static void test_self_id_sequence_enumerator_invalid(struct kunit *test) 51 + { 52 + static const u32 invalid_sequences[] = { 53 + 0x00000001, 54 + }; 55 + struct self_id_sequence_enumerator enumerator; 56 + const u32 *entry; 57 + unsigned int count; 58 + 59 + enumerator.cursor = invalid_sequences; 60 + enumerator.quadlet_count = ARRAY_SIZE(invalid_sequences); 61 + 62 + entry = self_id_sequence_enumerator_next(&enumerator, &count); 63 + KUNIT_EXPECT_EQ(test, PTR_ERR(entry), -EPROTO); 64 + } 65 + 66 + static struct kunit_case self_id_sequence_helper_test_cases[] = { 67 + KUNIT_CASE(test_self_id_sequence_enumerator_valid), 68 + KUNIT_CASE(test_self_id_sequence_enumerator_invalid), 69 + {} 70 + }; 71 + 72 + static struct kunit_suite self_id_sequence_helper_test_suite = { 73 + .name = "self-id-sequence-helper", 74 + .test_cases = self_id_sequence_helper_test_cases, 75 + }; 76 + kunit_test_suite(self_id_sequence_helper_test_suite); 77 + 78 + MODULE_DESCRIPTION("Unit test suite for helpers of self ID sequence"); 79 + MODULE_LICENSE("GPL");