From 55b4e903a156bc81e15fbe3af9be0664f7a3b3ca Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sat, 18 Oct 2025 12:55:30 +0900 Subject: [PATCH] firewire: core: determine transaction speed after detecting quirks Current implementation determines the maximum transaction speed supported by the target device after reading bus information block of configuration ROM. The read operations for root directory block are then performed at the determined speed. However, some devices have quirks that cause issues when transactions are performed at the determined speed. In the first place, all devices are required to support the lowest speed (S100) and must respond successfully to any read request within the configuration ROM space. Therefore it is safe to postpone speed determination until the entire configuration ROM has been read. This commit moves the speed determination after reading root directory. Link: https://lore.kernel.org/r/20251018035532.287124-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-device.c | 53 ++++++++++++++++------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index c698d4ced7d78..6a5740ed4934b 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -680,32 +680,6 @@ static int read_config_rom(struct fw_device *device, int generation) // Just prevent from torn writing/reading. WRITE_ONCE(device->quirks, quirks); - speed = device->node->max_speed; - - /* - * Determine the speed of - * - devices with link speed less than PHY speed, - * - devices with 1394b PHY (unless only connected to 1394a PHYs), - * - all devices if there are 1394b repeaters. - * Note, we cannot use the bus info block's link_spd as starting point - * because some buggy firmwares set it lower than necessary and because - * 1394-1995 nodes do not have the field. - */ - if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) { - u32 dummy; - - /* for S1600 and S3200 */ - if (speed == SCODE_BETA) - speed = card->link_speed; - - while (speed > SCODE_100) { - if (read_rom(device, generation, speed, 0, &dummy) == - RCODE_COMPLETE) - break; - --speed; - } - } - /* * Now parse the config rom. The config rom is a recursive * directory structure so we parse it using a stack of @@ -782,13 +756,36 @@ static int read_config_rom(struct fw_device *device, int generation) length = i; } - device->max_speed = speed; - quirks |= detect_quirks_by_root_directory(rom + ROOT_DIR_OFFSET, length - ROOT_DIR_OFFSET); // Just prevent from torn writing/reading. WRITE_ONCE(device->quirks, quirks); + speed = device->node->max_speed; + + // Determine the speed of + // - devices with link speed less than PHY speed, + // - devices with 1394b PHY (unless only connected to 1394a PHYs), + // - all devices if there are 1394b repeaters. + // Note, we cannot use the bus info block's link_spd as starting point because some buggy + // firmwares set it lower than necessary and because 1394-1995 nodes do not have the field. + if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) { + u32 dummy; + + // for S1600 and S3200. + if (speed == SCODE_BETA) + speed = card->link_speed; + + while (speed > SCODE_100) { + if (read_rom(device, generation, speed, 0, &dummy) == + RCODE_COMPLETE) + break; + --speed; + } + } + + device->max_speed = speed; + old_rom = device->config_rom; new_rom = kmemdup(rom, length * 4, GFP_KERNEL); if (new_rom == NULL) { -- 2.47.3