Skip to content

Commit 7bd10e0

Browse files
committed
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>
1 parent 6ba59ff commit 7bd10e0

5 files changed

Lines changed: 174 additions & 0 deletions

File tree

drivers/firewire/.kunitconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ CONFIG_FIREWIRE=y
44
CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
55
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y
66
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y
7+
CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=y

drivers/firewire/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ config FIREWIRE_KUNIT_PACKET_SERDES_TEST
6666
For more information on KUnit and unit tests in general, refer
6767
to the KUnit documentation in Documentation/dev-tools/kunit/.
6868

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+
6984
config FIREWIRE_OHCI
7085
tristate "OHCI-1394 controllers"
7186
depends on PCI && FIREWIRE && MMU

drivers/firewire/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
1818

1919
obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += uapi-test.o
2020
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
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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");

0 commit comments

Comments
 (0)