Skip to content

Commit 55b4e90

Browse files
committed
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 <o-takashi@sakamocchi.jp>
1 parent 665ad59 commit 55b4e90

1 file changed

Lines changed: 25 additions & 28 deletions

File tree

drivers/firewire/core-device.c

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -680,32 +680,6 @@ static int read_config_rom(struct fw_device *device, int generation)
680680
// Just prevent from torn writing/reading.
681681
WRITE_ONCE(device->quirks, quirks);
682682

683-
speed = device->node->max_speed;
684-
685-
/*
686-
* Determine the speed of
687-
* - devices with link speed less than PHY speed,
688-
* - devices with 1394b PHY (unless only connected to 1394a PHYs),
689-
* - all devices if there are 1394b repeaters.
690-
* Note, we cannot use the bus info block's link_spd as starting point
691-
* because some buggy firmwares set it lower than necessary and because
692-
* 1394-1995 nodes do not have the field.
693-
*/
694-
if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) {
695-
u32 dummy;
696-
697-
/* for S1600 and S3200 */
698-
if (speed == SCODE_BETA)
699-
speed = card->link_speed;
700-
701-
while (speed > SCODE_100) {
702-
if (read_rom(device, generation, speed, 0, &dummy) ==
703-
RCODE_COMPLETE)
704-
break;
705-
--speed;
706-
}
707-
}
708-
709683
/*
710684
* Now parse the config rom. The config rom is a recursive
711685
* 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)
782756
length = i;
783757
}
784758

785-
device->max_speed = speed;
786-
787759
quirks |= detect_quirks_by_root_directory(rom + ROOT_DIR_OFFSET, length - ROOT_DIR_OFFSET);
788760

789761
// Just prevent from torn writing/reading.
790762
WRITE_ONCE(device->quirks, quirks);
791763

764+
speed = device->node->max_speed;
765+
766+
// Determine the speed of
767+
// - devices with link speed less than PHY speed,
768+
// - devices with 1394b PHY (unless only connected to 1394a PHYs),
769+
// - all devices if there are 1394b repeaters.
770+
// Note, we cannot use the bus info block's link_spd as starting point because some buggy
771+
// firmwares set it lower than necessary and because 1394-1995 nodes do not have the field.
772+
if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) {
773+
u32 dummy;
774+
775+
// for S1600 and S3200.
776+
if (speed == SCODE_BETA)
777+
speed = card->link_speed;
778+
779+
while (speed > SCODE_100) {
780+
if (read_rom(device, generation, speed, 0, &dummy) ==
781+
RCODE_COMPLETE)
782+
break;
783+
--speed;
784+
}
785+
}
786+
787+
device->max_speed = speed;
788+
792789
old_rom = device->config_rom;
793790
new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
794791
if (new_rom == NULL) {

0 commit comments

Comments
 (0)