]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
firewire: core: handle device quirk of TASCAM FW-1884/FW-1804/FW-1082
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 18 Oct 2025 03:55:31 +0000 (12:55 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 18 Oct 2025 03:58:56 +0000 (12:58 +0900)
TASCAM FW-1884/FW-1804/FW-1082 is too lazy to repspond to asynchronous
request at S400. The asynchronous transaction often results in timeout.
This is a problematic quirk.

This commit adds support for the quirk. When identifying the new quirk
flag, then the transaction speed is configured at S200.

Link: https://lore.kernel.org/r/20251018035532.287124-4-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
drivers/firewire/core-device.c
include/linux/firewire.h

index 6a5740ed4934b8123615ced8352e48af37264d92..1674de4778526e93aaa9752975ed5d8703bf6d76 100644 (file)
@@ -571,6 +571,14 @@ static const struct entry_match motu_audio_express_matches[] = {
        { 8, 0x17104800 },
 };
 
+static const struct entry_match tascam_fw_series_matches[] = {
+       { 1, 0x0300022e },
+       { 3, 0x8d000006 },
+       { 4, 0xd1000001 },
+       { 6, 0x1200022e },
+       { 8, 0xd4000004 },
+};
+
 static int detect_quirks_by_root_directory(const u32 *root_directory, unsigned int length)
 {
        static const struct {
@@ -583,6 +591,11 @@ static int detect_quirks_by_root_directory(const u32 *root_directory, unsigned i
                        .matches = motu_audio_express_matches,
                        .match_count = ARRAY_SIZE(motu_audio_express_matches),
                },
+               {
+                       .quirk = FW_DEVICE_QUIRK_UNSTABLE_AT_S400,
+                       .matches = tascam_fw_series_matches,
+                       .match_count = ARRAY_SIZE(tascam_fw_series_matches),
+               },
        };
        int quirks = 0;
        int i;
@@ -761,7 +774,10 @@ 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;
+       if (unlikely(quirks & FW_DEVICE_QUIRK_UNSTABLE_AT_S400))
+               speed = SCODE_200;
+       else
+               speed = device->node->max_speed;
 
        // Determine the speed of
        //   - devices with link speed less than PHY speed,
index f1d8734c0ec6caf97cd017ffca7b2b1db8d5f579..6143b7d28eac5f9278210e66847f581c6a664161 100644 (file)
@@ -179,6 +179,9 @@ enum fw_device_quirk {
 
        // MOTU Audio Express transfers acknowledge packet with 0x10 for pending state.
        FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE = BIT(2),
+
+       // TASCAM FW-1082/FW-1804/FW-1884 often freezes when receiving S400 packets.
+       FW_DEVICE_QUIRK_UNSTABLE_AT_S400 = BIT(3),
 };
 
 enum fw_device_state {