mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
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>
This commit is contained in:
parent
6ba59ff422
commit
7bd10e0e3a
|
|
@ -4,3 +4,4 @@ CONFIG_FIREWIRE=y
|
|||
CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
|
||||
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y
|
||||
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y
|
||||
CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=y
|
||||
|
|
|
|||
|
|
@ -66,6 +66,21 @@ config FIREWIRE_KUNIT_PACKET_SERDES_TEST
|
|||
For more information on KUnit and unit tests in general, refer
|
||||
to the KUnit documentation in Documentation/dev-tools/kunit/.
|
||||
|
||||
config FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST
|
||||
tristate "KUnit tests for helpers of self ID sequence" if !KUNIT_ALL_TESTS
|
||||
depends on FIREWIRE && KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
This builds the KUnit tests for helpers of self ID sequence.
|
||||
|
||||
KUnit tests run during boot and output the results to the debug
|
||||
log in TAP format (https://testanything.org/). Only useful for
|
||||
kernel devs running KUnit test harness and are not for inclusion
|
||||
into a production build.
|
||||
|
||||
For more information on KUnit and unit tests in general, refer
|
||||
to the KUnit documentation in Documentation/dev-tools/kunit/.
|
||||
|
||||
config FIREWIRE_OHCI
|
||||
tristate "OHCI-1394 controllers"
|
||||
depends on PCI && FIREWIRE && MMU
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@ obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
|
|||
|
||||
obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += uapi-test.o
|
||||
obj-$(CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST) += packet-serdes-test.o
|
||||
obj-$(CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST) += self-id-sequence-helper-test.o
|
||||
|
|
|
|||
78
drivers/firewire/phy-packet-definitions.h
Normal file
78
drivers/firewire/phy-packet-definitions.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
// phy-packet-definitions.h - The definitions of phy packet for IEEE 1394.
|
||||
//
|
||||
// Copyright (c) 2024 Takashi Sakamoto
|
||||
|
||||
#ifndef _FIREWIRE_PHY_PACKET_DEFINITIONS_H
|
||||
#define _FIREWIRE_PHY_PACKET_DEFINITIONS_H
|
||||
|
||||
#define SELF_ID_EXTENDED_MASK 0x00800000
|
||||
#define SELF_ID_EXTENDED_SHIFT 23
|
||||
#define SELF_ID_MORE_PACKETS_MASK 0x00000001
|
||||
#define SELF_ID_MORE_PACKETS_SHIFT 0
|
||||
|
||||
#define SELF_ID_EXTENDED_SEQUENCE_MASK 0x00700000
|
||||
#define SELF_ID_EXTENDED_SEQUENCE_SHIFT 20
|
||||
|
||||
#define SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT 4
|
||||
|
||||
static inline bool phy_packet_self_id_get_extended(u32 quadlet)
|
||||
{
|
||||
return (quadlet & SELF_ID_EXTENDED_MASK) >> SELF_ID_EXTENDED_SHIFT;
|
||||
}
|
||||
|
||||
static inline bool phy_packet_self_id_get_more_packets(u32 quadlet)
|
||||
{
|
||||
return (quadlet & SELF_ID_MORE_PACKETS_MASK) >> SELF_ID_MORE_PACKETS_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned int phy_packet_self_id_extended_get_sequence(u32 quadlet)
|
||||
{
|
||||
return (quadlet & SELF_ID_EXTENDED_SEQUENCE_MASK) >> SELF_ID_EXTENDED_SEQUENCE_SHIFT;
|
||||
}
|
||||
|
||||
struct self_id_sequence_enumerator {
|
||||
const u32 *cursor;
|
||||
unsigned int quadlet_count;
|
||||
};
|
||||
|
||||
static inline const u32 *self_id_sequence_enumerator_next(
|
||||
struct self_id_sequence_enumerator *enumerator, unsigned int *quadlet_count)
|
||||
{
|
||||
const u32 *self_id_sequence, *cursor;
|
||||
u32 quadlet;
|
||||
unsigned int count;
|
||||
unsigned int sequence;
|
||||
|
||||
if (enumerator->cursor == NULL || enumerator->quadlet_count == 0)
|
||||
return ERR_PTR(-ENODATA);
|
||||
cursor = enumerator->cursor;
|
||||
count = 1;
|
||||
|
||||
quadlet = *cursor;
|
||||
sequence = 0;
|
||||
while (phy_packet_self_id_get_more_packets(quadlet)) {
|
||||
if (count >= enumerator->quadlet_count ||
|
||||
count >= SELF_ID_SEQUENCE_MAXIMUM_QUADLET_COUNT)
|
||||
return ERR_PTR(-EPROTO);
|
||||
++cursor;
|
||||
++count;
|
||||
quadlet = *cursor;
|
||||
|
||||
if (!phy_packet_self_id_get_extended(quadlet) ||
|
||||
sequence != phy_packet_self_id_extended_get_sequence(quadlet))
|
||||
return ERR_PTR(-EPROTO);
|
||||
++sequence;
|
||||
}
|
||||
|
||||
*quadlet_count = count;
|
||||
self_id_sequence = enumerator->cursor;
|
||||
|
||||
enumerator->cursor += count;
|
||||
enumerator->quadlet_count -= count;
|
||||
|
||||
return self_id_sequence;
|
||||
}
|
||||
|
||||
#endif // _FIREWIRE_PHY_PACKET_DEFINITIONS_H
|
||||
79
drivers/firewire/self-id-sequence-helper-test.c
Normal file
79
drivers/firewire/self-id-sequence-helper-test.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
// self-id-sequence-helper-test.c - An application of Kunit to test helpers of self ID sequence.
|
||||
//
|
||||
// Copyright (c) 2024 Takashi Sakamoto
|
||||
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include "phy-packet-definitions.h"
|
||||
|
||||
static void test_self_id_sequence_enumerator_valid(struct kunit *test)
|
||||
{
|
||||
static const u32 valid_sequences[] = {
|
||||
0x00000000,
|
||||
0x00000001, 0x00800000,
|
||||
0x00000001, 0x00800001, 0x00900000,
|
||||
0x00000000,
|
||||
};
|
||||
struct self_id_sequence_enumerator enumerator;
|
||||
const u32 *entry;
|
||||
unsigned int quadlet_count;
|
||||
|
||||
enumerator.cursor = valid_sequences;
|
||||
enumerator.quadlet_count = ARRAY_SIZE(valid_sequences);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count);
|
||||
KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[0]);
|
||||
KUNIT_EXPECT_EQ(test, quadlet_count, 1);
|
||||
KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 6);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count);
|
||||
KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[1]);
|
||||
KUNIT_EXPECT_EQ(test, quadlet_count, 2);
|
||||
KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 4);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count);
|
||||
KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[3]);
|
||||
KUNIT_EXPECT_EQ(test, quadlet_count, 3);
|
||||
KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 1);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count);
|
||||
KUNIT_EXPECT_PTR_EQ(test, entry, &valid_sequences[6]);
|
||||
KUNIT_EXPECT_EQ(test, quadlet_count, 1);
|
||||
KUNIT_EXPECT_EQ(test, enumerator.quadlet_count, 0);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &quadlet_count);
|
||||
KUNIT_EXPECT_EQ(test, PTR_ERR(entry), -ENODATA);
|
||||
}
|
||||
|
||||
static void test_self_id_sequence_enumerator_invalid(struct kunit *test)
|
||||
{
|
||||
static const u32 invalid_sequences[] = {
|
||||
0x00000001,
|
||||
};
|
||||
struct self_id_sequence_enumerator enumerator;
|
||||
const u32 *entry;
|
||||
unsigned int count;
|
||||
|
||||
enumerator.cursor = invalid_sequences;
|
||||
enumerator.quadlet_count = ARRAY_SIZE(invalid_sequences);
|
||||
|
||||
entry = self_id_sequence_enumerator_next(&enumerator, &count);
|
||||
KUNIT_EXPECT_EQ(test, PTR_ERR(entry), -EPROTO);
|
||||
}
|
||||
|
||||
static struct kunit_case self_id_sequence_helper_test_cases[] = {
|
||||
KUNIT_CASE(test_self_id_sequence_enumerator_valid),
|
||||
KUNIT_CASE(test_self_id_sequence_enumerator_invalid),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite self_id_sequence_helper_test_suite = {
|
||||
.name = "self-id-sequence-helper",
|
||||
.test_cases = self_id_sequence_helper_test_cases,
|
||||
};
|
||||
kunit_test_suite(self_id_sequence_helper_test_suite);
|
||||
|
||||
MODULE_DESCRIPTION("Unit test suite for helpers of self ID sequence");
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in New Issue
Block a user