Skip to content

Commit 7a14f78

Browse files
committed
firewire: ohci: add static inline functions to deserialize for Self-ID DMA operation
The SelfI-ID is one type of DMAs defined in 1394 OHCI specification. It is operated by two registers, one interrupt, and has one format of buffer. This commit adds some static inline functions to deserialize the data in the buffer and registers. Some KUnit tests are also added to check their reliability. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent c538b06 commit 7a14f78

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

drivers/firewire/.kunitconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
55
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y
66
CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST=y
77
CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST=y
8+
CONFIG_FIREWIRE_KUNIT_OHCI_SERDES_TEST=y

drivers/firewire/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ config FIREWIRE_OHCI
9292
To compile this driver as a module, say M here: The module will be
9393
called firewire-ohci.
9494

95+
config FIREWIRE_KUNIT_OHCI_SERDES_TEST
96+
tristate "KUnit tests for serialization/deserialization of data in buffers/registers" if !KUNIT_ALL_TESTS
97+
depends on FIREWIRE && KUNIT
98+
default KUNIT_ALL_TESTS
99+
help
100+
This builds the KUnit tests to check serialization and deserialization
101+
of data in buffers and registers defined in 1394 OHCI specification.
102+
103+
KUnit tests run during boot and output the results to the debug
104+
log in TAP format (https://testanything.org/). Only useful for
105+
kernel devs running KUnit test harness and are not for inclusion
106+
into a production build.
107+
108+
For more information on KUnit and unit tests in general, refer
109+
to the KUnit documentation in Documentation/dev-tools/kunit/.
110+
95111
config FIREWIRE_SBP2
96112
tristate "Storage devices (SBP-2 protocol)"
97113
depends on FIREWIRE && SCSI

drivers/firewire/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
1919
obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += uapi-test.o
2020
obj-$(CONFIG_FIREWIRE_KUNIT_PACKET_SERDES_TEST) += packet-serdes-test.o
2121
obj-$(CONFIG_FIREWIRE_KUNIT_SELF_ID_SEQUENCE_HELPER_TEST) += self-id-sequence-helper-test.o
22+
obj-$(CONFIG_FIREWIRE_KUNIT_OHCI_SERDES_TEST) += ohci-serdes-test.o

drivers/firewire/ohci-serdes-test.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
//
3+
// ohci-serdes-test.c - An application of Kunit to check serialization/deserialization of data in
4+
// buffers and registers defined in 1394 OHCI specification.
5+
//
6+
// Copyright (c) 2024 Takashi Sakamoto
7+
8+
#include <kunit/test.h>
9+
10+
#include "ohci.h"
11+
12+
13+
static void test_self_id_count_register_deserialization(struct kunit *test)
14+
{
15+
const u32 expected = 0x803d0594;
16+
17+
bool is_error = ohci1394_self_id_count_is_error(expected);
18+
u8 generation = ohci1394_self_id_count_get_generation(expected);
19+
u32 size = ohci1394_self_id_count_get_size(expected);
20+
21+
KUNIT_EXPECT_TRUE(test, is_error);
22+
KUNIT_EXPECT_EQ(test, 0x3d, generation);
23+
KUNIT_EXPECT_EQ(test, 0x165, size);
24+
}
25+
26+
static void test_self_id_receive_buffer_deserialization(struct kunit *test)
27+
{
28+
const u32 buffer[] = {
29+
0x0006f38b,
30+
0x807fcc56,
31+
0x7f8033a9,
32+
0x8145cc5e,
33+
0x7eba33a1,
34+
};
35+
36+
u8 generation = ohci1394_self_id_receive_q0_get_generation(buffer[0]);
37+
u16 timestamp = ohci1394_self_id_receive_q0_get_timestamp(buffer[0]);
38+
39+
KUNIT_EXPECT_EQ(test, 0x6, generation);
40+
KUNIT_EXPECT_EQ(test, 0xf38b, timestamp);
41+
}
42+
43+
static struct kunit_case ohci_serdes_test_cases[] = {
44+
KUNIT_CASE(test_self_id_count_register_deserialization),
45+
KUNIT_CASE(test_self_id_receive_buffer_deserialization),
46+
{}
47+
};
48+
49+
static struct kunit_suite ohci_serdes_test_suite = {
50+
.name = "firewire-ohci-serdes",
51+
.test_cases = ohci_serdes_test_cases,
52+
};
53+
kunit_test_suite(ohci_serdes_test_suite);
54+
55+
MODULE_DESCRIPTION("FireWire buffers and registers serialization/deserialization unit test suite");
56+
MODULE_LICENSE("GPL");

drivers/firewire/ohci.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,46 @@
156156

157157
#define OHCI1394_phy_tcode 0xe
158158

159+
// Self-ID DMA.
160+
161+
#define OHCI1394_SelfIDCount_selfIDError_MASK 0x80000000
162+
#define OHCI1394_SelfIDCount_selfIDError_SHIFT 31
163+
#define OHCI1394_SelfIDCount_selfIDGeneration_MASK 0x00ff0000
164+
#define OHCI1394_SelfIDCount_selfIDGeneration_SHIFT 16
165+
#define OHCI1394_SelfIDCount_selfIDSize_MASK 0x000007fc
166+
#define OHCI1394_SelfIDCount_selfIDSize_SHIFT 2
167+
168+
static inline bool ohci1394_self_id_count_is_error(u32 value)
169+
{
170+
return !!((value & OHCI1394_SelfIDCount_selfIDError_MASK) >> OHCI1394_SelfIDCount_selfIDError_SHIFT);
171+
}
172+
173+
static inline u8 ohci1394_self_id_count_get_generation(u32 value)
174+
{
175+
return (value & OHCI1394_SelfIDCount_selfIDGeneration_MASK) >> OHCI1394_SelfIDCount_selfIDGeneration_SHIFT;
176+
}
177+
178+
// In 1394 OHCI specification, the maximum size of self ID stream is 504 quadlets
179+
// (= 63 devices * 4 self ID packets * 2 quadlets). The selfIDSize field accommodates it and its
180+
// additional first quadlet, since the field is 9 bits (0x1ff = 511).
181+
static inline u32 ohci1394_self_id_count_get_size(u32 value)
182+
{
183+
return (value & OHCI1394_SelfIDCount_selfIDSize_MASK) >> OHCI1394_SelfIDCount_selfIDSize_SHIFT;
184+
}
185+
186+
#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK 0x00ff0000
187+
#define OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT 16
188+
#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK 0x0000ffff
189+
#define OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT 0
190+
191+
static inline u8 ohci1394_self_id_receive_q0_get_generation(u32 quadlet0)
192+
{
193+
return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_GENERATION_SHIFT;
194+
}
195+
196+
static inline u16 ohci1394_self_id_receive_q0_get_timestamp(u32 quadlet0)
197+
{
198+
return (quadlet0 & OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_MASK) >> OHCI1394_SELF_ID_RECEIVE_Q0_TIMESTAMP_SHIFT;
199+
}
200+
159201
#endif /* _FIREWIRE_OHCI_H */

0 commit comments

Comments
 (0)