From: Takashi Sakamoto Date: Sat, 18 Oct 2025 03:55:30 +0000 (+0900) Subject: firewire: core: determine transaction speed after detecting quirks X-Git-Tag: v6.19-rc1~147^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55b4e903a156bc81e15fbe3af9be0664f7a3b3ca;p=thirdparty%2Fkernel%2Flinux.git 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 --- 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) {