Merge tag 'firewire-fixes-6.7-final' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394

Pull firewire fix from Takashi Sakamoto:
"A single patch to suppress unexpected system reboot in AMD Ryzen
machines with PCIe card consisting of Asmedia ASM1083/1085 and
VT6306/6307/6308.

When the 1394 OHCI driver for the card accesses a specific register
in PCI memory space, the system reboot often occurs.

The issue affects all versions of Linux kernel as long as the 1394
OHCI driver is included. The mechanism of unexpected system reboot is
not clear, so the driver is changed to avoid the access itself when
detecting the combination of hardware"

* tag 'firewire-fixes-6.7-final' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394:
firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and ASM108x/VT630x PCIe cards

Changed files
+51
drivers
firewire
+51
drivers/firewire/ohci.c
··· 279 279 #define QUIRK_TI_SLLZ059 0x20 280 280 #define QUIRK_IR_WAKE 0x40 281 281 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 + 282 327 /* In case of multiple matches in ohci_quirks[], only the first one is used. */ 283 328 static const struct { 284 329 unsigned short vendor, device, revision, flags; ··· 1768 1723 u32 t0, t1, t2; 1769 1724 s32 diff01, diff12; 1770 1725 int i; 1726 + 1727 + if (has_reboot_by_cycle_timer_read_quirk(ohci)) 1728 + return 0; 1771 1729 1772 1730 c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); 1773 1731 ··· 3677 3629 } 3678 3630 if (param_quirks) 3679 3631 ohci->quirks = param_quirks; 3632 + 3633 + if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev)) 3634 + ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ; 3680 3635 3681 3636 /* 3682 3637 * Because dma_alloc_coherent() allocates at least one page,