Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+25 -28
+25 -28
drivers/firewire/core-device.c
··· 680 680 // Just prevent from torn writing/reading. 681 681 WRITE_ONCE(device->quirks, quirks); 682 682 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 - 709 683 /* 710 684 * Now parse the config rom. The config rom is a recursive 711 685 * directory structure so we parse it using a stack of ··· 756 782 length = i; 757 783 } 758 784 759 - device->max_speed = speed; 760 - 761 785 quirks |= detect_quirks_by_root_directory(rom + ROOT_DIR_OFFSET, length - ROOT_DIR_OFFSET); 762 786 763 787 // Just prevent from torn writing/reading. 764 788 WRITE_ONCE(device->quirks, quirks); 789 + 790 + speed = device->node->max_speed; 791 + 792 + // Determine the speed of 793 + // - devices with link speed less than PHY speed, 794 + // - devices with 1394b PHY (unless only connected to 1394a PHYs), 795 + // - all devices if there are 1394b repeaters. 796 + // Note, we cannot use the bus info block's link_spd as starting point because some buggy 797 + // firmwares set it lower than necessary and because 1394-1995 nodes do not have the field. 798 + if ((rom[2] & 0x7) < speed || speed == SCODE_BETA || card->beta_repeaters_present) { 799 + u32 dummy; 800 + 801 + // for S1600 and S3200. 802 + if (speed == SCODE_BETA) 803 + speed = card->link_speed; 804 + 805 + while (speed > SCODE_100) { 806 + if (read_rom(device, generation, speed, 0, &dummy) == 807 + RCODE_COMPLETE) 808 + break; 809 + --speed; 810 + } 811 + } 812 + 813 + device->max_speed = speed; 765 814 766 815 old_rom = device->config_rom; 767 816 new_rom = kmemdup(rom, length * 4, GFP_KERNEL);