Skip to content

Commit ac9184f

Browse files
committed
firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and ASM108x/VT630x PCIe cards
VIA VT6306/6307/6308 provides PCI interface compliant to 1394 OHCI. When the hardware is combined with Asmedia ASM1083/1085 PCIe-to-PCI bus bridge, it appears that accesses to its 'Isochronous Cycle Timer' register (offset 0xf0 on PCI memory space) often causes unexpected system reboot in any type of AMD Ryzen machine (both 0x17 and 0x19 families). It does not appears in the other type of machine (AMD pre-Ryzen machine, Intel machine, at least), or in the other OHCI 1394 hardware (e.g. Texas Instruments). The issue explicitly appears at a commit dcadfd7 ("firewire: core: use union for callback of transaction completion") added to v6.5 kernel. It changed 1394 OHCI driver to access to the register every time to dispatch local asynchronous transaction. However, the issue exists in older version of kernel as long as it runs in AMD Ryzen machine, since the access to the register is required to maintain bus time. It is not hard to imagine that users experience the unexpected system reboot when generating bus reset by plugging any devices in, or reading the register by time-aware application programs; e.g. audio sample processing. This commit suppresses the unexpected system reboot in the combination of hardware. It avoids the access itself. As a result, the software stack can not provide the hardware time anymore to unit drivers, userspace applications, and nodes in the same IEEE 1394 bus. It brings apparent disadvantage since time-aware application programs require it, while time-unaware applications are available again; e.g. sbp2. Cc: stable@vger.kernel.org Reported-by: Jiri Slaby <jirislaby@kernel.org> Closes: https://bugzilla.suse.com/show_bug.cgi?id=1215436 Reported-by: Mario Limonciello <mario.limonciello@amd.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217994 Reported-by: Tobias Gruetzmacher <tobias-lists@23.gs> Closes: https://sourceforge.net/p/linux1394/mailman/message/58711901/ Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2240973 Closes: https://bugs.launchpad.net/linux/+bug/2043905 Link: https://lore.kernel.org/r/20240102110150.244475-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
1 parent 610a9b8 commit ac9184f

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

drivers/firewire/ohci.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,51 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
279279
#define QUIRK_TI_SLLZ059 0x20
280280
#define QUIRK_IR_WAKE 0x40
281281

282+
// On PCI Express Root Complex in any type of AMD Ryzen machine, VIA VT6306/6307/6308 with Asmedia
283+
// ASM1083/1085 brings an inconvenience that the read accesses to 'Isochronous Cycle Timer' register
284+
// (at offset 0xf0 in PCI I/O space) often causes unexpected system reboot. The mechanism is not
285+
// clear, since the read access to the other registers is enough safe; e.g. 'Node ID' register,
286+
// while it is probable due to detection of any type of PCIe error.
287+
#define QUIRK_REBOOT_BY_CYCLE_TIMER_READ 0x80000000
288+
289+
#if IS_ENABLED(CONFIG_X86)
290+
291+
static bool has_reboot_by_cycle_timer_read_quirk(const struct fw_ohci *ohci)
292+
{
293+
return !!(ohci->quirks & QUIRK_REBOOT_BY_CYCLE_TIMER_READ);
294+
}
295+
296+
#define PCI_DEVICE_ID_ASMEDIA_ASM108X 0x1080
297+
298+
static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev *pdev)
299+
{
300+
const struct pci_dev *pcie_to_pci_bridge;
301+
302+
// Detect any type of AMD Ryzen machine.
303+
if (!static_cpu_has(X86_FEATURE_ZEN))
304+
return false;
305+
306+
// Detect VIA VT6306/6307/6308.
307+
if (pdev->vendor != PCI_VENDOR_ID_VIA)
308+
return false;
309+
if (pdev->device != PCI_DEVICE_ID_VIA_VT630X)
310+
return false;
311+
312+
// Detect Asmedia ASM1083/1085.
313+
pcie_to_pci_bridge = pdev->bus->self;
314+
if (pcie_to_pci_bridge->vendor != PCI_VENDOR_ID_ASMEDIA)
315+
return false;
316+
if (pcie_to_pci_bridge->device != PCI_DEVICE_ID_ASMEDIA_ASM108X)
317+
return false;
318+
319+
return true;
320+
}
321+
322+
#else
323+
#define has_reboot_by_cycle_timer_read_quirk(ohci) false
324+
#define detect_vt630x_with_asm1083_on_amd_ryzen_machine(pdev) false
325+
#endif
326+
282327
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
283328
static const struct {
284329
unsigned short vendor, device, revision, flags;
@@ -1724,6 +1769,9 @@ static u32 get_cycle_time(struct fw_ohci *ohci)
17241769
s32 diff01, diff12;
17251770
int i;
17261771

1772+
if (has_reboot_by_cycle_timer_read_quirk(ohci))
1773+
return 0;
1774+
17271775
c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
17281776

17291777
if (ohci->quirks & QUIRK_CYCLE_TIMER) {
@@ -3630,6 +3678,9 @@ static int pci_probe(struct pci_dev *dev,
36303678
if (param_quirks)
36313679
ohci->quirks = param_quirks;
36323680

3681+
if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev))
3682+
ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ;
3683+
36333684
/*
36343685
* Because dma_alloc_coherent() allocates at least one page,
36353686
* we save space by using a common buffer for the AR request/

0 commit comments

Comments
 (0)