mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
firewire: core: add test to detect irm-is-1394-1995-only quirk in config ROM parser
Some Sony DV cameras have a quirk where their IRM functionality does not comply with IEEE 1394a:2000. This quirk was supported by commit1038953674("firewire: core: check for 1394a compliant IRM, fix inaccessibility of Sony camcorder") and refactored by commit5a43dc9f4e("firewire: core: detect device quirk when reading configuration ROM"). Add a KUnit test to check detection of the quirk. The configuration ROM content is retrieved from the following discussion: https://github.com/systemd/systemd/issues/25029. Link: https://lore.kernel.org/r/20260901134534.2386577-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
This commit is contained in:
parent
428ef9ca38
commit
bae885b9be
|
|
@ -7,13 +7,164 @@
|
||||||
// This file can not be built independently since it is intentionally included in core-device.c.
|
// This file can not be built independently since it is intentionally included in core-device.c.
|
||||||
|
|
||||||
#include <kunit/test.h>
|
#include <kunit/test.h>
|
||||||
|
#include <kunit/static_stub.h>
|
||||||
|
#include <kunit/device.h>
|
||||||
|
|
||||||
|
static const u32 sony_dcr_trv310k_config_rom[] = {
|
||||||
|
0x0404e552,
|
||||||
|
0x31333934,
|
||||||
|
0xe0648100,
|
||||||
|
0x00008500,
|
||||||
|
0x005eb597,
|
||||||
|
0x0007cdd0,
|
||||||
|
0x03000085,
|
||||||
|
0x8100000d,
|
||||||
|
0x17000002,
|
||||||
|
0x81000010,
|
||||||
|
0x0c0083c0,
|
||||||
|
0xd8000002,
|
||||||
|
0xd1000003,
|
||||||
|
0x0001ce96,
|
||||||
|
0xd1000001,
|
||||||
|
0x0004bbee,
|
||||||
|
0x1200a02d,
|
||||||
|
0x13010001,
|
||||||
|
0x17000002,
|
||||||
|
0x81000006,
|
||||||
|
0x00046dc8,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x43616e6f,
|
||||||
|
0x6e000000,
|
||||||
|
0x000621ee,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x4d563569,
|
||||||
|
0x204d4300,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct parser_test_case {
|
||||||
|
const char *name;
|
||||||
|
const u32 *quadlets;
|
||||||
|
size_t quadlet_length;
|
||||||
|
int phy_speed_in_self_id;
|
||||||
|
int expected_speed;
|
||||||
|
int expected_quirk;
|
||||||
|
unsigned int expected_max_rec;
|
||||||
|
bool expected_cmc;
|
||||||
|
bool expected_irmc;
|
||||||
|
} parser_test_cases[] = {
|
||||||
|
{
|
||||||
|
.name = "detect_irm_is_1394_1995_only_quirk",
|
||||||
|
.quadlets = sony_dcr_trv310k_config_rom,
|
||||||
|
.quadlet_length = ARRAY_SIZE(sony_dcr_trv310k_config_rom),
|
||||||
|
.phy_speed_in_self_id = SCODE_100,
|
||||||
|
.expected_speed = SCODE_100,
|
||||||
|
.expected_quirk = FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY,
|
||||||
|
.expected_max_rec = 8,
|
||||||
|
.expected_cmc = true,
|
||||||
|
.expected_irmc = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define parser_test_gen_params.
|
||||||
|
KUNIT_ARRAY_PARAM_DESC(parser_test, parser_test_cases, name);
|
||||||
|
|
||||||
|
static int stub_run_regular_transaction(struct fw_card *card, int tcode, int destination_id,
|
||||||
|
int generation, int speed, unsigned long long offset,
|
||||||
|
void *payload, size_t length)
|
||||||
|
{
|
||||||
|
struct kunit *test = kunit_get_current_test();
|
||||||
|
const struct parser_test_case *param = test->param_value;
|
||||||
|
|
||||||
|
KUNIT_ASSERT_GE(test, offset, CSR_REGISTER_BASE | CSR_CONFIG_ROM);
|
||||||
|
KUNIT_ASSERT_LT(test, offset, CSR_REGISTER_BASE | CSR_CONFIG_ROM_END);
|
||||||
|
KUNIT_ASSERT_NOT_NULL(test, payload);
|
||||||
|
KUNIT_ASSERT_EQ(test, length, 4);
|
||||||
|
|
||||||
|
unsigned int index = (offset - (CSR_REGISTER_BASE | CSR_CONFIG_ROM)) / sizeof(u32);
|
||||||
|
u32 *quadlet = payload;
|
||||||
|
|
||||||
|
KUNIT_EXPECT_LE(test, speed, param->expected_speed);
|
||||||
|
KUNIT_EXPECT_LT(test, index, param->quadlet_length);
|
||||||
|
|
||||||
|
*quadlet = cpu_to_be32(param->quadlets[index]);
|
||||||
|
|
||||||
|
return RCODE_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parser_with_regular_cases(struct kunit *test)
|
||||||
|
{
|
||||||
|
struct fw_device *device = test->priv;
|
||||||
|
const struct parser_test_case *param = test->param_value;
|
||||||
|
|
||||||
|
kunit_activate_static_stub(test, fw_run_transaction, stub_run_regular_transaction);
|
||||||
|
|
||||||
|
device->card->link_speed = SCODE_BETA;
|
||||||
|
device->node->max_speed = param->phy_speed_in_self_id;
|
||||||
|
|
||||||
|
KUNIT_EXPECT_EQ(test, read_config_rom(device, 0), RCODE_COMPLETE);
|
||||||
|
|
||||||
|
KUNIT_EXPECT_EQ(test, device->config_rom_length, param->quadlet_length);
|
||||||
|
KUNIT_EXPECT_MEMEQ(test, device->config_rom, param->quadlets, param->quadlet_length);
|
||||||
|
|
||||||
|
KUNIT_EXPECT_TRUE(test, device->quirks & param->expected_quirk);
|
||||||
|
KUNIT_EXPECT_EQ(test, device->max_speed, param->expected_speed);
|
||||||
|
KUNIT_EXPECT_EQ(test, (unsigned int)device->max_rec, param->expected_max_rec);
|
||||||
|
KUNIT_EXPECT_EQ(test, (bool)device->cmc, param->expected_cmc);
|
||||||
|
KUNIT_EXPECT_EQ(test, (bool)device->irmc, param->expected_irmc);
|
||||||
|
|
||||||
|
kunit_deactivate_static_stub(test, fw_run_transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct fw_card_driver dummy_card_driver;
|
||||||
|
|
||||||
|
static int config_rom_parser_test_init(struct kunit *test)
|
||||||
|
{
|
||||||
|
struct fw_device *device;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
device = kunit_kzalloc(test, sizeof(*device), GFP_KERNEL);
|
||||||
|
KUNIT_ASSERT_NOT_NULL(test, device);
|
||||||
|
|
||||||
|
device->node = kunit_kzalloc(test, sizeof(*device->node), GFP_KERNEL);
|
||||||
|
KUNIT_ASSERT_NOT_NULL(test, device->node);
|
||||||
|
kref_init(&device->node->kref);
|
||||||
|
|
||||||
|
device->card = kunit_kzalloc(test, sizeof(*device->card), GFP_KERNEL);
|
||||||
|
KUNIT_ASSERT_NOT_NULL(test, device->card);
|
||||||
|
|
||||||
|
dev = kunit_device_register(test, "dummy-device");
|
||||||
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||||
|
|
||||||
|
fw_card_initialize(device->card, &dummy_card_driver, dev);
|
||||||
|
|
||||||
|
test->priv = device;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void config_rom_parser_test_exit(struct kunit *test)
|
||||||
|
{
|
||||||
|
struct fw_device *device = test->priv;
|
||||||
|
|
||||||
|
kunit_device_unregister(test, device->card->device);
|
||||||
|
kunit_kfree(test, device->card);
|
||||||
|
kunit_kfree(test, device->node);
|
||||||
|
kunit_kfree(test, device);
|
||||||
|
}
|
||||||
|
|
||||||
static struct kunit_case config_rom_parser_test_cases[] = {
|
static struct kunit_case config_rom_parser_test_cases[] = {
|
||||||
|
KUNIT_CASE_PARAM(test_parser_with_regular_cases, parser_test_gen_params),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct kunit_suite config_rom_parser_test_suite = {
|
static struct kunit_suite config_rom_parser_test_suite = {
|
||||||
.name = "firewire-config-rom-parser",
|
.name = "firewire-config-rom-parser",
|
||||||
|
.init = config_rom_parser_test_init,
|
||||||
|
.exit = config_rom_parser_test_exit,
|
||||||
.test_cases = config_rom_parser_test_cases,
|
.test_cases = config_rom_parser_test_cases,
|
||||||
};
|
};
|
||||||
kunit_test_suite(config_rom_parser_test_suite);
|
kunit_test_suite(config_rom_parser_test_suite);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <kunit/static_stub.h>
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
|
@ -485,6 +486,9 @@ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
|
||||||
int generation, int speed, unsigned long long offset,
|
int generation, int speed, unsigned long long offset,
|
||||||
void *payload, size_t length)
|
void *payload, size_t length)
|
||||||
{
|
{
|
||||||
|
KUNIT_STATIC_STUB_REDIRECT(fw_run_transaction, card, tcode, destination_id, generation,
|
||||||
|
speed, offset, payload, length);
|
||||||
|
|
||||||
struct transaction_callback_data d;
|
struct transaction_callback_data d;
|
||||||
struct fw_transaction t;
|
struct fw_transaction t;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user