From nobody Fri Dec 19 15:37:17 2025 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0EC4024C669 for ; Mon, 13 Oct 2025 14:03:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760364200; cv=none; b=uscRYNO6TJHDNJLzNe8cCekP8crk2MrElKLF6KuXE/Z+HWgUfjP/Rqnx1ELOBYK7gRhZJawiGrCpKI/XrTY4Bn7ni+Nf/OZlvtV5BbOH06voOc5F7v7DifdrWUmPeg9k2GzfApY+zaIWhOQ3KRxlB/HNrCQYOtTHBQ4d9Bx50Ro= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760364200; c=relaxed/simple; bh=JXIr/+m0sRwMSO2HHUK5t7TbwXeRArxztqgG8xpBlic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tRTai6Vxv5L/Ae7AbPF4D2GyKWU1D+u2mSo6YAs8LRxEcfmVqZkNaYoApi0s6EOEQHZUu0doeMJQNRb2nETPwDPhpADvIj7SkmWgizV0CBqWpFXuMUjcIuAmLn5JMtfsuEMXBw8NOIu7mGhhNZrQy7DdY92MqFWeies79daxHNs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp; spf=pass smtp.mailfrom=sakamocchi.jp; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b=ZNHFSJdr; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=WSZ3Un4x; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="ZNHFSJdr"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="WSZ3Un4x" Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfout.stl.internal (Postfix) with ESMTP id 0E1A01D00082; Mon, 13 Oct 2025 10:03:17 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-06.internal (MEProxy); Mon, 13 Oct 2025 10:03:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1760364196; x= 1760450596; bh=Ou5rMncd5Jeoym/hVv0RnHa2lDSKYB/GpkWGveWhdBE=; b=Z NHFSJdr+WD2JXtuoiEYUmZ4YAKrccQJru2X5lI2zzOgku2V84IzUuuh48qPkkljL Qii0IVVX3rOw+KYj2V8M4tKpJNH1y7yDF6Hgm3bqBANQoeiQmszaT0vxYaPKWMMy KZB+dkVL4Hr1wP33uH/XQXiZduBGavMlxQWmp26eaY7Q5U9Dm8Cp/+DFUUF1AygY xxrsBv4t+iKB2Gqr6n0v7NK0mqSxRIz95A6zj1yAZ3IytN8tUw+7Ag4/0wrtzjFc Q0zp/jK8CFPfAkNoFEThotqi1umlhYWsdizoAWfPpm3ucdEe/fvjXsDyHMFEV+ka 7PzksUEQ9Tkjx/2EuOSFw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1760364196; x=1760450596; bh=O u5rMncd5Jeoym/hVv0RnHa2lDSKYB/GpkWGveWhdBE=; b=WSZ3Un4xhj6NxIjFn N4dOvBylMLuaHjOZuyCUqvWZWMh35qtmghuNp/EIRMv7vydqJg45qpvpsoJ2k1Sz rRNIopZmokgk+qXg7KG3gFqCWZmsbyvJU5h0m+MBEmp4VHSxA7Rojp1OQtWSCmrP e/yH8pbEkqa530B2KaFr6Lb7EACtOPb3xRJRf2DjdjfA4Ssaummhz3YzurB7m8f9 Qko2JCnJ05pkOLKQ5SU1HtYI7A/YuDsVxpGQYDgVRbuuDnxr4aZIantF9eVCmUjG ennItNI7JTJBqPMqU6skZ/nEzbHY5SRCTwLOKUhQyIpFue68oaDVIo7qp6NtL5/S CCM6w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggdduudejkeegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpefvrghkrghshhhiucfurghkrghmohhtohcuoehoqdhtrghkrghs hhhisehsrghkrghmohgttghhihdrjhhpqeenucggtffrrghtthgvrhhnpedvjefgjeeuvd fguddukeelveetgfdtvefhtdfffeeigfevueetffeivdffkedvtdenucevlhhushhtvghr ufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehoqdhtrghkrghshhhisehsrg hkrghmohgttghhihdrjhhppdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpohhu thdprhgtphhtthhopehlihhnuhigudefleegqdguvghvvghlsehlihhsthhsrdhsohhurh gtvghfohhrghgvrdhnvghtpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgv rhdrkhgvrhhnvghlrdhorhhg X-ME-Proxy: Feedback-ID: ie8e14432:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 13 Oct 2025 10:03:15 -0400 (EDT) From: Takashi Sakamoto To: linux1394-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/2] firewire: core: detect device quirk when reading configuration ROM Date: Mon, 13 Oct 2025 23:03:10 +0900 Message-ID: <20251013140311.97159-2-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251013140311.97159-1-o-takashi@sakamocchi.jp> References: <20251013140311.97159-1-o-takashi@sakamocchi.jp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Every time the bus manager runs, the cached configuration ROM content of the IRM device is investigated to detect device-specific quirks. This detection can be performed in advance when reading the configuration ROM. This commit adds device quirk flags to the fw_device structure, and initializes them after reading the bus information block of the configuration ROM. The quirk flags are immutable once the configuration ROM has been read. Although they are likely accessed concurrently only by the bus manager, this commit ensures safe access by preventing torn writes and reads using the WRITE_ONCE()/READ_ONCE() macros. Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-card.c | 21 +++++++-------------- drivers/firewire/core-device.c | 25 +++++++++++++++++++++++-- include/linux/firewire.h | 11 +++++++++++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index e5e0174a0335..6979d6a88ae2 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -86,8 +86,6 @@ static size_t config_rom_length =3D 1 + 4 + 1 + 1; */ #define DEFAULT_SPLIT_TIMEOUT (2 * 8000) =20 -#define CANON_OUI 0x000085 - static void generate_config_rom(struct fw_card *card, __be32 *config_rom) { struct fw_descriptor *desc; @@ -308,11 +306,9 @@ __must_hold(&card->lock) cpu_to_be32(local_id), }; bool grace =3D time_is_before_jiffies64(card->reset_jiffies + msecs_to_ji= ffies(125)); - bool irm_is_1394_1995_only =3D false; - bool keep_this_irm =3D false; struct fw_node *irm_node; struct fw_device *irm_device; - int irm_node_id; + int irm_node_id, irm_device_quirks =3D 0; int rcode; =20 lockdep_assert_held(&card->lock); @@ -328,15 +324,12 @@ __must_hold(&card->lock) return BM_CONTENTION_OUTCOME_IRM_HAS_LINK_OFF; } =20 + // NOTE: It is likely that the quirk detection for IRM device has not don= e yet. irm_device =3D fw_node_get_device(irm_node); - if (irm_device && irm_device->config_rom) { - irm_is_1394_1995_only =3D (irm_device->config_rom[2] & 0x000000f0) =3D= =3D 0; - - // Canon MV5i works unreliably if it is not root node. - keep_this_irm =3D irm_device->config_rom[3] >> 8 =3D=3D CANON_OUI; - } - - if (irm_is_1394_1995_only && !keep_this_irm) { + if (irm_device) + irm_device_quirks =3D READ_ONCE(irm_device->quirks); + if ((irm_device_quirks & FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY) && + !(irm_device_quirks & FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER)) { fw_notice(card, "IRM is not 1394a compliant, making local node (%02x) ro= ot\n", local_id); return BM_CONTENTION_OUTCOME_IRM_COMPLIES_1394_1995_ONLY; @@ -373,7 +366,7 @@ __must_hold(&card->lock) return BM_CONTENTION_OUTCOME_IRM_HOLDS_LOCAL_NODE_AS_BM; } default: - if (!keep_this_irm) { + if (!(irm_device_quirks & FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER)) { fw_notice(card, "BM lock failed (%s), making local node (%02x) root\n", fw_rcode_string(rcode), local_id); return BM_CONTENTION_OUTCOME_IRM_COMPLIES_1394_1995_ONLY; diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 457a0da024a7..9bab2d594b89 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -542,6 +542,21 @@ static struct device_attribute fw_device_attributes[] = =3D { __ATTR_NULL, }; =20 +#define CANON_OUI 0x000085 + +static int detect_quirks_by_bus_information_block(const u32 *bus_informati= on_block) +{ + int quirks =3D 0; + + if ((bus_information_block[2] & 0x000000f0) =3D=3D 0) + quirks |=3D FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY; + + if ((bus_information_block[3] >> 8) =3D=3D CANON_OUI) + quirks |=3D FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER; + + return quirks; +} + static int read_rom(struct fw_device *device, int generation, int index, u32 *data) { @@ -582,6 +597,7 @@ static int read_config_rom(struct fw_device *device, in= t generation) u32 *rom, *stack; u32 sp, key; int i, end, length, ret; + int quirks; =20 rom =3D kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE + sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL); @@ -612,6 +628,11 @@ static int read_config_rom(struct fw_device *device, i= nt generation) } } =20 + quirks =3D detect_quirks_by_bus_information_block(rom); + + // Just prevent from torn writing/reading. + WRITE_ONCE(device->quirks, quirks); + device->max_speed =3D device->node->max_speed; =20 /* @@ -1122,10 +1143,10 @@ static void fw_device_init(struct work_struct *work) device->workfn =3D fw_device_shutdown; fw_schedule_device_work(device, SHUTDOWN_DELAY); } else { - fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", + fw_notice(card, "created device %s: GUID %08x%08x, S%d00, quirks %08x\n", dev_name(&device->device), device->config_rom[3], device->config_rom[4], - 1 << device->max_speed); + 1 << device->max_speed, device->quirks); device->config_rom_retries =3D 0; =20 set_broadcast_channel(device, device->generation); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 6d208769d456..161829cfcc00 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -170,6 +170,14 @@ struct fw_attribute_group { struct attribute *attrs[13]; }; =20 +enum fw_device_quirk { + // See afa1282a35d3 ("firewire: core: check for 1394a compliant IRM, fix = inaccessibility of Sony camcorder"). + FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY =3D BIT(0), + + // See a509e43ff338 ("firewire: core: fix unstable I/O with Canon camcord= er"). + FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER =3D BIT(1), +}; + enum fw_device_state { FW_DEVICE_INITIALIZING, FW_DEVICE_RUNNING, @@ -203,6 +211,9 @@ struct fw_device { struct fw_card *card; struct device device; =20 + // A set of enum fw_device_quirk. + int quirks; + struct mutex client_list_mutex; struct list_head client_list; =20 --=20 2.51.0 From nobody Fri Dec 19 15:37:17 2025 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F7C1255F5E for ; Mon, 13 Oct 2025 14:03:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760364201; cv=none; b=tBJkeE0HnBVEa8XjYJyeZNTqBXJm7mm6R+Y3qFZeYw27pt37P57xbsmZIZaqnnDqyig6TSW8cP2QClzmkps8Z2YqsT4CA4HY3gj79Wc3eqXuHEl6LEIK7kVdWNPcV6KUiOiN53Ot3LAqBdAXI4eFRmxQBlrZhi1DmNvXQPSOdHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760364201; c=relaxed/simple; bh=aTuDQJOc9QyDWw7NeVePyqs/4KWPG9WwxbPFBpmsEgI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gsKu+JKjyvQyiVqF136HtZhC9cZpfXWQOwr9PXHZtTBYZsoQm75C9TE1GK3go95MRU+Jfxuj1XFyFVpNbOeIZG4fglpJL9Oqr2IqylGypOn/bWsyjRECKSVH8Z2HItA/WqhhJvvZEFsYBaXcb5p/rB50dW0laH/0ZrC0n0aemt8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp; spf=pass smtp.mailfrom=sakamocchi.jp; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b=c1JrtJKd; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ruIN39Fm; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="c1JrtJKd"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ruIN39Fm" Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailfout.stl.internal (Postfix) with ESMTP id B4E341D00188; Mon, 13 Oct 2025 10:03:18 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-01.internal (MEProxy); Mon, 13 Oct 2025 10:03:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1760364198; x= 1760450598; bh=ju0TXwkvur7Pc8DU4WdaqDLH7X5oT5Eo8QJC4dqaWb4=; b=c 1JrtJKdnXQfxlqtEAInguBEN0kIlB+MFkFPvFIm6GNUqeXiVb6ZRt7uWy4029yx3 AVGhnkiovIaahOPaFt7ckFdIgwrcZvzYPMDknT1Es+TZkfT6ffKnztms/PJnIhBL uI2Renv6an7qno1Y6EQtNbWDEe04YEL8P2ASuvdT3XHLeUsLK3a6hNCFnpB43E77 RDzPU9gZ52MPpznF1Eb6TxFy3kULDMg1GO466buC5TnlE84LIIWVbrBgYZqahHKO Rek3KYhmgmAvQvkUOMSZ47ws6/bUeU2AmMVPaTbqZESFhBo86m37o0EIetgFhRpd 4iC7fep53HkaAexDEbinw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1760364198; x=1760450598; bh=j u0TXwkvur7Pc8DU4WdaqDLH7X5oT5Eo8QJC4dqaWb4=; b=ruIN39FmjGCMhtRJV ARr8ow+pwdnOlbw1WWTXQYyi1+1OBKlwlP8IB4kf8uCksYF1dB8QCMyIkSIOXS91 Xykefta5lDZ01ousXCBndsAFLE1kBaA3+vkDupdRarCkm8M5YxULh56EFoI9CpwB ZZLf86z0mPwKozwSHnOnQe3Aymwjkh1vSycMDs2A0xbJ63UyZdoQ3ZVzJpJF0SnN 7Rcclx1qVvc7RxhKHTuyd9Hxb2JbuOj43q+fuCGE3TEUlRpZHsFH3b/nLCyvFvDY 7WSdnbZVEsuluX0wXy7m4ZYwzdZGVpW36Fszew/fBhYIWmYLXxdPJ4IhAjXE7R/F /7kyQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggdduudejkeegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpefvrghkrghshhhiucfurghkrghmohhtohcuoehoqdhtrghkrghs hhhisehsrghkrghmohgttghhihdrjhhpqeenucggtffrrghtthgvrhhnpedvjefgjeeuvd fguddukeelveetgfdtvefhtdfffeeigfevueetffeivdffkedvtdenucevlhhushhtvghr ufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehoqdhtrghkrghshhhisehsrg hkrghmohgttghhihdrjhhppdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpohhu thdprhgtphhtthhopehlihhnuhigudefleegqdguvghvvghlsehlihhsthhsrdhsohhurh gtvghfohhrghgvrdhnvghtpdhrtghpthhtoheplhhinhhugidqkhgvrhhnvghlsehvghgv rhdrkhgvrhhnvghlrdhorhhg X-ME-Proxy: Feedback-ID: ie8e14432:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 13 Oct 2025 10:03:17 -0400 (EDT) From: Takashi Sakamoto To: linux1394-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org Subject: [PATCH 2/2] firewire: core: handle device quirk of MOTU Audio Express Date: Mon, 13 Oct 2025 23:03:11 +0900 Message-ID: <20251013140311.97159-3-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251013140311.97159-1-o-takashi@sakamocchi.jp> References: <20251013140311.97159-1-o-takashi@sakamocchi.jp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A commit 3a93d082bacf ("ALSA: firewire-motu: add support for MOTU Audio Express") describes a quirk of MOTU Audio Express. The device returns acknowledge packet with 0x10 as the pending state of any types of asynchronous request transaction. It is completely out of specification. This commit implements handling for that device-specific quirk. The quirk is detected after reading the root directory of configuration ROM. When processing the acknowledge code in 1394 OHCI AT context event handler, firewire-ohci module seeks the device instance of destination node by traversing device hierarchy. If the device has the quirk, the acknowledge code is replaced with the standard code. The 1394 OHCI AT context events occur for outgoing asynchronous request packets. The device traversal is safe since no new request initiators exist after the fw_card_instance has been invalidated. Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-device.c | 53 ++++++++++++++++++++++++++++++++++ drivers/firewire/ohci.c | 29 +++++++++++++++++++ include/linux/firewire.h | 3 ++ 3 files changed, 85 insertions(+) diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9bab2d594b89..33ce4cd357ed 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -557,6 +557,54 @@ static int detect_quirks_by_bus_information_block(cons= t u32 *bus_information_blo return quirks; } =20 +struct entry_match { + unsigned int index; + u32 value; +}; + +static const struct entry_match motu_audio_express_matches[] =3D { + { 1, 0x030001f2 }, + { 3, 0xd1000002 }, + { 4, 0x8d000005 }, + { 6, 0x120001f2 }, + { 7, 0x13000033 }, + { 8, 0x17104800 }, +}; + +static int detect_quirks_by_root_directory(const u32 *root_directory, unsi= gned int length) +{ + static const struct { + enum fw_device_quirk quirk; + const struct entry_match *matches; + unsigned int match_count; + } *entry, entries[] =3D { + { + .quirk =3D FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE, + .matches =3D motu_audio_express_matches, + .match_count =3D ARRAY_SIZE(motu_audio_express_matches), + }, + }; + int quirks =3D 0; + int i; + + for (i =3D 0; i < ARRAY_SIZE(entries); ++i) { + int j; + + entry =3D entries + i; + for (j =3D 0; j < entry->match_count; ++j) { + unsigned int index =3D entry->matches[j].index; + unsigned int value =3D entry->matches[j].value; + + if ((length < index) || (root_directory[index] !=3D value)) + break; + } + if (j =3D=3D entry->match_count) + quirks |=3D entry->quirk; + } + + return quirks; +} + static int read_rom(struct fw_device *device, int generation, int index, u32 *data) { @@ -737,6 +785,11 @@ static int read_config_rom(struct fw_device *device, i= nt generation) length =3D i; } =20 + quirks |=3D detect_quirks_by_root_directory(rom + ROOT_DIR_OFFSET, length= - ROOT_DIR_OFFSET); + + // Just prevent from torn writing/reading. + WRITE_ONCE(device->quirks, quirks); + old_rom =3D device->config_rom; new_rom =3D kmemdup(rom, length * 4, GFP_KERNEL); if (new_rom =3D=3D NULL) { diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 030aed5453a1..757dd9c64b1c 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1319,6 +1319,14 @@ static void at_context_flush(struct at_context *ctx) enable_work(&ctx->work); } =20 +static int find_fw_device(struct device *dev, const void *data) +{ + struct fw_device *device =3D fw_device(dev); + const u32 *params =3D data; + + return (device->generation =3D=3D params[0]) && (device->node_id =3D=3D p= arams[1]); +} + static int handle_at_packet(struct context *context, struct descriptor *d, struct descriptor *last) @@ -1390,6 +1398,27 @@ static int handle_at_packet(struct context *context, fallthrough; =20 default: + if (unlikely(evt =3D=3D 0x10)) { + u32 params[2] =3D { + packet->generation, + async_header_get_destination(packet->header), + }; + struct device *dev; + + fw_card_get(&ohci->card); + dev =3D device_find_child(ohci->card.device, (const void *)params, find= _fw_device); + fw_card_put(&ohci->card); + if (dev) { + struct fw_device *device =3D fw_device(dev); + int quirks =3D READ_ONCE(device->quirks); + + put_device(dev); + if (quirks & FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE) { + packet->ack =3D ACK_PENDING; + break; + } + } + } packet->ack =3D RCODE_SEND_ERROR; break; } diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 161829cfcc00..f1d8734c0ec6 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -176,6 +176,9 @@ enum fw_device_quirk { =20 // See a509e43ff338 ("firewire: core: fix unstable I/O with Canon camcord= er"). FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER =3D BIT(1), + + // MOTU Audio Express transfers acknowledge packet with 0x10 for pending = state. + FW_DEVICE_QUIRK_ACK_PACKET_WITH_INVALID_PENDING_CODE =3D BIT(2), }; =20 enum fw_device_state { --=20 2.51.0