From: Greg Kroah-Hartman Date: Mon, 13 Jul 2026 13:02:53 +0000 (+0200) Subject: 6.12-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=60b665ef4d61c765359b1f66f828ce3c0135f21f;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: alsa-caiaq-fix-out-of-bounds-read-in-the-traktor-kontrol-s4-input-parser.patch alsa-cmipci-check-snd_ctl_new1-return-value.patch alsa-es1938-check-snd_ctl_new1-return-value.patch alsa-firewire-isight-bound-the-sample-count-to-the-packet-payload.patch alsa-gus-check-snd_ctl_new1-return-value.patch alsa-ice1712-check-snd_ctl_new1-return-value.patch alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch alsa-usb-audio-avoid-kobject-path-lookup-in-dualsense-match.patch alsa-usb-audio-propagate-errors-in-scarlett_ctl_enum_put.patch alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callbacks.patch alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch --- diff --git a/queue-6.12/alsa-caiaq-fix-out-of-bounds-read-in-the-traktor-kontrol-s4-input-parser.patch b/queue-6.12/alsa-caiaq-fix-out-of-bounds-read-in-the-traktor-kontrol-s4-input-parser.patch new file mode 100644 index 0000000000..fa4d6debc5 --- /dev/null +++ b/queue-6.12/alsa-caiaq-fix-out-of-bounds-read-in-the-traktor-kontrol-s4-input-parser.patch @@ -0,0 +1,51 @@ +From f7f3f9fd81e7adbaa12c2e62ee07f0e094a543fd Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Thu, 18 Jun 2026 14:03:15 +0800 +Subject: ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser + +From: Maoyi Xie + +commit f7f3f9fd81e7adbaa12c2e62ee07f0e094a543fd upstream. + +snd_usb_caiaq_tks4_dispatch() decodes the Traktor Kontrol S4 input +stream in fixed 16-byte (TKS4_MSGBLOCK_SIZE) message blocks. On every +iteration it advances buf and subtracts the block size while looping on +"while (len)". + +len is urb->actual_length. That value is supplied by the device and is +not guaranteed to be a multiple of 16. When a final short block leaves +len between 1 and 15, the loop runs once more, reads up to buf[15], and +then does "len -= TKS4_MSGBLOCK_SIZE". As len is unsigned this underflows +to a huge value. The loop then keeps iterating and walking buf far past +the end of the 512-byte ep4_in_buf, reading out of bounds until a bogus +block id happens to be hit. + +Iterate only while a full message block is available. This stops the +unsigned underflow and silently drops any trailing partial block, which +carries no complete control value anyway. + +The sibling endpoint-4 parsers are not affected. The Traktor Kontrol X1 +and Maschine arms in snd_usb_caiaq_ep4_reply_dispatch() floor +urb->actual_length before dispatching. + +Fixes: 15c5ab607045 ("ALSA: snd-usb-caiaq: Add support for Traktor Kontrol S4") +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Link: https://patch.msgid.link/178176259547.3343534.2724779296835237429@maoyixie.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/caiaq/input.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/usb/caiaq/input.c ++++ b/sound/usb/caiaq/input.c +@@ -330,7 +330,7 @@ static void snd_usb_caiaq_tks4_dispatch( + { + struct device *dev = caiaqdev_to_dev(cdev); + +- while (len) { ++ while (len >= TKS4_MSGBLOCK_SIZE) { + unsigned int i, block_id = (buf[0] << 8) | buf[1]; + + switch (block_id) { diff --git a/queue-6.12/alsa-cmipci-check-snd_ctl_new1-return-value.patch b/queue-6.12/alsa-cmipci-check-snd_ctl_new1-return-value.patch new file mode 100644 index 0000000000..9abecc0a05 --- /dev/null +++ b/queue-6.12/alsa-cmipci-check-snd_ctl_new1-return-value.patch @@ -0,0 +1,53 @@ +From c205bd1b28fb7e5f1061a4e78813fad7d315cb3e Mon Sep 17 00:00:00 2001 +From: Zhao Dongdong +Date: Wed, 27 May 2026 20:09:13 +0800 +Subject: ALSA: cmipci: check snd_ctl_new1() return value + +From: Zhao Dongdong + +commit c205bd1b28fb7e5f1061a4e78813fad7d315cb3e upstream. + +snd_ctl_new1() can return NULL when memory allocation fails. +snd_cmipci_spdif_controls() does not check the return value before +dereferencing kctl->id.device, which can lead to a NULL pointer +dereference. + +Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any +fails. + +Assisted-by: Opencode:DeepSeek-V4-Flash +Cc: stable@vger.kernel.org +Fixes: f2f312ad88c6 ("ALSA: cmipci: Fix kctl->id initialization") +Signed-off-by: Zhao Dongdong +Link: https://patch.msgid.link/tencent_964433DCD132125D5EDA79EE068A2D6EFA09@qq.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/cmipci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/sound/pci/cmipci.c ++++ b/sound/pci/cmipci.c +@@ -2672,16 +2672,22 @@ static int snd_cmipci_mixer_new(struct c + } + if (cm->can_ac3_hw) { + kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = pcm_spdif_device; + err = snd_ctl_add(card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = pcm_spdif_device; + err = snd_ctl_add(card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = pcm_spdif_device; + err = snd_ctl_add(card, kctl); + if (err < 0) diff --git a/queue-6.12/alsa-es1938-check-snd_ctl_new1-return-value.patch b/queue-6.12/alsa-es1938-check-snd_ctl_new1-return-value.patch new file mode 100644 index 0000000000..10a3e257e6 --- /dev/null +++ b/queue-6.12/alsa-es1938-check-snd_ctl_new1-return-value.patch @@ -0,0 +1,37 @@ +From 1edd1f02dddd20aeb6066ded41017615766ea42f Mon Sep 17 00:00:00 2001 +From: Zhao Dongdong +Date: Wed, 27 May 2026 20:09:09 +0800 +Subject: ALSA: es1938: check snd_ctl_new1() return value + +From: Zhao Dongdong + +commit 1edd1f02dddd20aeb6066ded41017615766ea42f upstream. + +snd_ctl_new1() can return NULL when memory allocation fails. +snd_es1938_mixer() does not check the return value before dereferencing +the pointer, which can lead to a NULL pointer dereference. + +Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails. + +Assisted-by: Opencode:DeepSeek-V4-Flash +Cc: stable@vger.kernel.org +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Zhao Dongdong +Link: https://patch.msgid.link/tencent_E0DC65165FDF2C8982BAFB6794B854B53B0A@qq.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/es1938.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/pci/es1938.c ++++ b/sound/pci/es1938.c +@@ -1663,6 +1663,8 @@ static int snd_es1938_mixer(struct es193 + for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) { + struct snd_kcontrol *kctl; + kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip); ++ if (!kctl) ++ return -ENOMEM; + switch (idx) { + case 0: + chip->master_volume = kctl; diff --git a/queue-6.12/alsa-firewire-isight-bound-the-sample-count-to-the-packet-payload.patch b/queue-6.12/alsa-firewire-isight-bound-the-sample-count-to-the-packet-payload.patch new file mode 100644 index 0000000000..de79d6cb94 --- /dev/null +++ b/queue-6.12/alsa-firewire-isight-bound-the-sample-count-to-the-packet-payload.patch @@ -0,0 +1,55 @@ +From 29b9667982e4df2ed7744f86b1144f8bb58eb698 Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Sun, 21 Jun 2026 23:09:07 +0800 +Subject: ALSA: firewire: isight: bound the sample count to the packet payload + +From: Maoyi Xie + +commit 29b9667982e4df2ed7744f86b1144f8bb58eb698 upstream. + +isight_packet() takes the frame count from the device iso packet and +checks it only against the device claimed iso length. + + count = be32_to_cpu(payload->sample_count); + if (likely(count <= (length - 16) / 4)) + isight_samples(isight, payload->samples, count); + +length is the iso header data_length. It can be up to 0xffff. So the +gate allows a count up to about 16379. isight_samples() then copies +count frames out of payload->samples into the PCM DMA buffer. + +payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The +device multiplexes two samples per frame. A count past +MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer +size writes past runtime->dma_area. The smallest PCM buffer is larger +than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET +keeps both the read and the write in range. + +A malicious or faulty Apple iSight on the FireWire bus reaches this +during a normal capture. + +Add the MAX_FRAMES_PER_PACKET bound to the gate. + +Fixes: 3a691b28a0ca ("ALSA: add Apple iSight microphone driver") +Suggested-by: Takashi Sakamoto +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Link: https://patch.msgid.link/178205454729.1900991.7807310178296762772@maoyixie.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/firewire/isight.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/sound/firewire/isight.c ++++ b/sound/firewire/isight.c +@@ -179,7 +179,8 @@ static void isight_packet(struct fw_iso_ + if (likely(length >= 16 && + payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) { + count = be32_to_cpu(payload->sample_count); +- if (likely(count <= (length - 16) / 4)) { ++ if (likely(count <= (length - 16) / 4 && ++ count <= MAX_FRAMES_PER_PACKET)) { + total = be32_to_cpu(payload->sample_total); + if (unlikely(total != isight->total_samples)) { + if (!isight->first_packet) diff --git a/queue-6.12/alsa-gus-check-snd_ctl_new1-return-value.patch b/queue-6.12/alsa-gus-check-snd_ctl_new1-return-value.patch new file mode 100644 index 0000000000..07abebd33b --- /dev/null +++ b/queue-6.12/alsa-gus-check-snd_ctl_new1-return-value.patch @@ -0,0 +1,38 @@ +From c7fa99d30c7a166a5e5db5a585ce7501ff68326b Mon Sep 17 00:00:00 2001 +From: Zhao Dongdong +Date: Wed, 27 May 2026 20:09:10 +0800 +Subject: ALSA: gus: check snd_ctl_new1() return value + +From: Zhao Dongdong + +commit c7fa99d30c7a166a5e5db5a585ce7501ff68326b upstream. + +snd_ctl_new1() can return NULL when memory allocation fails. +snd_gf1_pcm_volume_control() does not check the return value before +dereferencing kctl->id.index, which can lead to a NULL pointer +dereference. + +Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails. + +Assisted-by: Opencode:DeepSeek-V4-Flash +Cc: stable@vger.kernel.org +Fixes: c5ae57b1bb99 ("ALSA: gus: Fix kctl->id initialization") +Signed-off-by: Zhao Dongdong +Link: https://patch.msgid.link/tencent_F644A3DCAD32945D62DB2FEEBE8A996F6809@qq.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/isa/gus/gus_pcm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/isa/gus/gus_pcm.c ++++ b/sound/isa/gus/gus_pcm.c +@@ -862,6 +862,8 @@ int snd_gf1_pcm_new(struct snd_gus_card + kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus); + else + kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.index = control_index; + err = snd_ctl_add(card, kctl); + if (err < 0) diff --git a/queue-6.12/alsa-ice1712-check-snd_ctl_new1-return-value.patch b/queue-6.12/alsa-ice1712-check-snd_ctl_new1-return-value.patch new file mode 100644 index 0000000000..c64783e16f --- /dev/null +++ b/queue-6.12/alsa-ice1712-check-snd_ctl_new1-return-value.patch @@ -0,0 +1,98 @@ +From 2b929b91b0f3bc6de8a844370049cd99ee8e31ff Mon Sep 17 00:00:00 2001 +From: Zhao Dongdong +Date: Wed, 27 May 2026 20:09:11 +0800 +Subject: ALSA: ice1712: check snd_ctl_new1() return value + +From: Zhao Dongdong + +commit 2b929b91b0f3bc6de8a844370049cd99ee8e31ff upstream. + +snd_ctl_new1() can return NULL when memory allocation fails. The +ice1712 driver calls snd_ctl_new1() without checking the return value +before dereferencing the pointer in multiple places (ice1712.c, +ice1724.c, aureon.c), which can lead to NULL pointer dereferences. + +Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any +fails. + +Assisted-by: Opencode:DeepSeek-V4-Flash +Cc: stable@vger.kernel.org +Fixes: b9a4efd61b6b ("ALSA: ice1712,ice1724: fix the kcontrol->id initialization") +Signed-off-by: Zhao Dongdong +Link: https://patch.msgid.link/tencent_42E5E2AB1B6A5101F7EE8C2117F1F687BB07@qq.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/ice1712/aureon.c | 2 ++ + sound/pci/ice1712/ice1712.c | 8 ++++++++ + sound/pci/ice1712/ice1724.c | 6 ++++++ + 3 files changed, 16 insertions(+) + +--- a/sound/pci/ice1712/aureon.c ++++ b/sound/pci/ice1712/aureon.c +@@ -1900,6 +1900,8 @@ static int aureon_add_controls(struct sn + for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) { + struct snd_kcontrol *kctl; + kctl = snd_ctl_new1(&cs8415_controls[i], ice); ++ if (!kctl) ++ return -ENOMEM; + if (i > 1) + kctl->id.device = ice->pcm->device; + err = snd_ctl_add(ice->card, kctl); +--- a/sound/pci/ice1712/ice1712.c ++++ b/sound/pci/ice1712/ice1712.c +@@ -2372,21 +2372,29 @@ int snd_ice1712_spdif_build_controls(str + if (snd_BUG_ON(!ice->pcm_pro)) + return -EIO; + kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm_pro->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm_pro->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm_pro->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm_pro->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) +--- a/sound/pci/ice1712/ice1724.c ++++ b/sound/pci/ice1712/ice1724.c +@@ -2393,16 +2393,22 @@ static int snd_vt1724_spdif_build_contro + return err; + + kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) + return err; + kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice); ++ if (!kctl) ++ return -ENOMEM; + kctl->id.device = ice->pcm->device; + err = snd_ctl_add(ice->card, kctl); + if (err < 0) diff --git a/queue-6.12/alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch b/queue-6.12/alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch new file mode 100644 index 0000000000..d0a8316373 --- /dev/null +++ b/queue-6.12/alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch @@ -0,0 +1,55 @@ +From 435990e25bf1f4af3e6df12a6fbfd1f7ba4a97d4 Mon Sep 17 00:00:00 2001 +From: HyeongJun An +Date: Wed, 24 Jun 2026 08:38:40 +0900 +Subject: ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup() + +From: HyeongJun An + +commit 435990e25bf1f4af3e6df12a6fbfd1f7ba4a97d4 upstream. + +snd_seq_event_dup() copies an incoming event into a pool cell and, in +the UMP-enabled build, clears the trailing cell->ump.raw.extra word that +the memcpy() did not cover. The guard deciding whether to clear it +compares the copied size against sizeof(cell->event): + + memcpy(&cell->ump, event, size); + if (size < sizeof(cell->event)) + cell->ump.raw.extra = 0; + +For a legacy (non-UMP) event, size == sizeof(struct snd_seq_event) == +sizeof(cell->event), so the condition is false and the extra word keeps +stale data. The cell pool is allocated with kvmalloc() (not zeroed) and +cells are reused via a free list, so that word holds uninitialised heap +or leftover event data. + +When such a cell is delivered to a UMP client (client->midi_version > 0) +that set SNDRV_SEQ_FILTER_NO_CONVERT -- so the legacy event reaches it +unconverted -- snd_seq_read() reads it out as the larger struct +snd_seq_ump_event and copies the stale word to user space, a 4-byte +kernel heap infoleak to an unprivileged /dev/snd/seq client. + +Compare against sizeof(cell->ump) instead, so the trailing word is zeroed +for every event shorter than the UMP cell. + +Fixes: 46397622a3fa ("ALSA: seq: Add UMP support") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: HyeongJun An +Link: https://patch.msgid.link/20260623233841.853326-1-sammiee5311@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/core/seq/seq_memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/core/seq/seq_memory.c ++++ b/sound/core/seq/seq_memory.c +@@ -364,7 +364,7 @@ int snd_seq_event_dup(struct snd_seq_poo + size = snd_seq_event_packet_size(event); + memcpy(&cell->ump, event, size); + #if IS_ENABLED(CONFIG_SND_SEQ_UMP) +- if (size < sizeof(cell->event)) ++ if (size < sizeof(cell->ump)) + cell->ump.raw.extra = 0; + #endif + diff --git a/queue-6.12/alsa-usb-audio-avoid-kobject-path-lookup-in-dualsense-match.patch b/queue-6.12/alsa-usb-audio-avoid-kobject-path-lookup-in-dualsense-match.patch new file mode 100644 index 0000000000..46748825ae --- /dev/null +++ b/queue-6.12/alsa-usb-audio-avoid-kobject-path-lookup-in-dualsense-match.patch @@ -0,0 +1,106 @@ +From 7693c0cc415f3a16a7a3355f245474a5e661be4e Mon Sep 17 00:00:00 2001 +From: Darvell Long +Date: Wed, 24 Jun 2026 07:37:23 -0700 +Subject: ALSA: usb-audio: avoid kobject path lookup in DualSense match + +From: Darvell Long + +commit 7693c0cc415f3a16a7a3355f245474a5e661be4e upstream. + +The DualSense jack-detection input handler verifies that a matching input +device belongs to the same physical controller by building kobject path +strings for both the input device and the USB audio device, then comparing +the path prefix. + +This was observed when a weak physical connection caused the controller +to rapidly disconnect and reconnect. During that repeated hotplug, +snd_dualsense_ih_match() can run while the controller's USB device is +being disconnected. kobject_get_path() walks ancestor kobjects and +dereferences their names; if the USB device kobject name is no longer +valid, this can fault in strlen(): + + RIP: 0010:strlen+0x10/0x30 + Call Trace: + kobject_get_path+0x34/0x150 + snd_dualsense_ih_match+0x49/0xd0 [snd_usb_audio] + input_register_device+0x566/0x6a0 + ps_probe+0xb89/0x1590 [hid_playstation] + +The same ownership check can be done without building kobject path +strings. The input device is parented below the HID device, USB interface +and USB device, so walking the input device parent chain and comparing +against the mixer USB device preserves the check without dereferencing +kobject names during disconnect. + +Fixes: 79d561c4ec04 ("ALSA: usb-audio: Add mixer quirk for Sony DualSense PS5") +Cc: +Assisted-by: Cute:gpt-5.5 +Signed-off-by: Darvell Long +Link: https://patch.msgid.link/20260624143723.2986353-1-contact@darvell.me +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_quirks.c | 40 ++++++++++++---------------------------- + 1 file changed, 12 insertions(+), 28 deletions(-) + +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -571,46 +571,30 @@ static bool snd_dualsense_ih_match(struc + { + struct dualsense_mixer_elem_info *mei; + struct usb_device *snd_dev; +- char *input_dev_path, *usb_dev_path; +- size_t usb_dev_path_len; +- bool match = false; ++ struct device *parent; + + mei = container_of(handler, struct dualsense_mixer_elem_info, ih); + snd_dev = mei->info.head.mixer->chip->dev; + +- input_dev_path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); +- if (!input_dev_path) { +- dev_warn(&snd_dev->dev, "Failed to get input dev path\n"); +- return false; +- } +- +- usb_dev_path = kobject_get_path(&snd_dev->dev.kobj, GFP_KERNEL); +- if (!usb_dev_path) { +- dev_warn(&snd_dev->dev, "Failed to get USB dev path\n"); +- goto free_paths; +- } +- + /* + * Ensure the VID:PID matched input device supposedly owned by the + * hid-playstation driver belongs to the actual hardware handled by +- * the current USB audio device, which implies input_dev_path being +- * a subpath of usb_dev_path. ++ * the current USB audio device. + * + * This verification is necessary when there is more than one identical + * controller attached to the host system. ++ * ++ * The input device is registered below the HID device, USB interface and ++ * USB device, so compare the parent chain directly instead of building ++ * kobject path strings. This avoids dereferencing kobject names while the ++ * USB device hierarchy is being torn down during disconnect. + */ +- usb_dev_path_len = strlen(usb_dev_path); +- if (usb_dev_path_len >= strlen(input_dev_path)) +- goto free_paths; +- +- usb_dev_path[usb_dev_path_len] = '/'; +- match = !memcmp(input_dev_path, usb_dev_path, usb_dev_path_len + 1); +- +-free_paths: +- kfree(input_dev_path); +- kfree(usb_dev_path); ++ for (parent = dev->dev.parent; parent; parent = parent->parent) { ++ if (parent == &snd_dev->dev) ++ return true; ++ } + +- return match; ++ return false; + } + + static int snd_dualsense_ih_connect(struct input_handler *handler, diff --git a/queue-6.12/alsa-usb-audio-propagate-errors-in-scarlett_ctl_enum_put.patch b/queue-6.12/alsa-usb-audio-propagate-errors-in-scarlett_ctl_enum_put.patch new file mode 100644 index 0000000000..776cbfedad --- /dev/null +++ b/queue-6.12/alsa-usb-audio-propagate-errors-in-scarlett_ctl_enum_put.patch @@ -0,0 +1,42 @@ +From 0f25cf1f02e3dba626791d949c759a48c0a44996 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= +Date: Sun, 19 Apr 2026 17:30:30 -0300 +Subject: ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +commit 0f25cf1f02e3dba626791d949c759a48c0a44996 upstream. + +scarlett_ctl_enum_put() ignores the return value from +snd_usb_set_cur_mix_value() and reports success whenever the +requested enum value differs from the current one. + +If the SET_CUR request fails, the callback still returns success even +though neither the hardware state nor the cached mixer value changed. + +Fixes: 76b188c4b370 ("ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260419-usb-write-error-propagation-v1-2-5a3bd4a673ae@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_scarlett.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sound/usb/mixer_scarlett.c ++++ b/sound/usb/mixer_scarlett.c +@@ -438,7 +438,9 @@ static int scarlett_ctl_enum_put(struct + val = ucontrol->value.integer.value[0]; + val = val + opt->start; + if (val != oval) { +- snd_usb_set_cur_mix_value(elem, 0, 0, val); ++ err = snd_usb_set_cur_mix_value(elem, 0, 0, val); ++ if (err < 0) ++ return err; + return 1; + } + return 0; diff --git a/queue-6.12/alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callbacks.patch b/queue-6.12/alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callbacks.patch new file mode 100644 index 0000000000..b06f1ca320 --- /dev/null +++ b/queue-6.12/alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callbacks.patch @@ -0,0 +1,134 @@ +From 3c06aec8abda6ba068b58a8b7119cdb2a48456b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= +Date: Sun, 19 Apr 2026 17:30:31 -0300 +Subject: ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +commit 3c06aec8abda6ba068b58a8b7119cdb2a48456b1 upstream. + +Several US-16x08 mixer put callbacks log failed control URBs but +still return success to userspace. That hides device write failures +even though the requested value was not applied. + +Return the negative write error instead in the route, master, bus, +channel, and EQ switch put callbacks. + +Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260419-usb-write-error-propagation-v1-3-5a3bd4a673ae@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_us16x08.c | 49 ++++++++++++++++++++++------------------------ + 1 file changed, 24 insertions(+), 25 deletions(-) + +--- a/sound/usb/mixer_us16x08.c ++++ b/sound/usb/mixer_us16x08.c +@@ -225,14 +225,14 @@ static int snd_us16x08_route_put(struct + + err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg)); + +- if (err > 0) { +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err); ++ return err; + } + +- return err > 0 ? 1 : 0; ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; ++ return 1; + } + + static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol, +@@ -284,14 +284,14 @@ static int snd_us16x08_master_put(struct + buf[5] = index + 1; + err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out)); + +- if (err > 0) { +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set master, err:%d\n", err); ++ return err; + } + +- return err > 0 ? 1 : 0; ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; ++ return 1; + } + + static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol, +@@ -325,14 +325,14 @@ static int snd_us16x08_bus_put(struct sn + break; + } + +- if (err > 0) { +- elem->cached |= 1; +- elem->cache_val[0] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err); ++ return err; + } + +- return err > 0 ? 1 : 0; ++ elem->cached |= 1; ++ elem->cache_val[0] = val; ++ return 1; + } + + static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol, +@@ -393,14 +393,14 @@ static int snd_us16x08_channel_put(struc + + err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in)); + +- if (err > 0) { +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err); ++ return err; + } + +- return err > 0 ? 1 : 0; ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; ++ return 1; + } + + static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol, +@@ -530,13 +530,13 @@ static int snd_us16x08_eqswitch_put(stru + msleep(15); + } + +- if (err > 0) { +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err); ++ return err; + } + ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; + return 1; + } + +@@ -1419,4 +1419,3 @@ int snd_us16x08_controls_create(struct u + + return 0; + } +- diff --git a/queue-6.12/alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch b/queue-6.12/alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch new file mode 100644 index 0000000000..ff3c90e679 --- /dev/null +++ b/queue-6.12/alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch @@ -0,0 +1,165 @@ +From 6380957fa24251856a532e48a46a4dc3d1ae26b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= +Date: Wed, 29 Apr 2026 10:20:01 -0300 +Subject: ALSA: usb-audio: Roll back quirk control caches on write errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +commit 6380957fa24251856a532e48a46a4dc3d1ae26b6 upstream. + +Several mixer quirk callbacks cache the requested +control value in kcontrol->private_value before +issuing a single vendor or class write. + +Their paired get and resume paths consume that cache +directly, so a failed write currently leaves software +state changed even though the update did not succeed. +That can make later reads report a value the device +never accepted and can replay the stale cache on resume. + +Restore the previous cached value on failure in +the Audigy2NX LED, Emu0204 channel switch, +Xonar U1 output switch, Native Instruments controls, +FTU effect program switch, and Sound Blaster E1 input source switch. + +Fixes: 9cf3689bfe07 ("ALSA: usb-audio: Add audigy2nx resume support") +Fixes: 5f503ee9e270 ("ALSA: usb-audio: Add Emu0204 channel switch resume support") +Fixes: 2bfb14c3b8fb ("ALSA: usb-audio: Add Xonar U1 resume support") +Fixes: da6d276957ea ("ALSA: usb-audio: Add resume support for Native Instruments controls") +Fixes: 0b4e9cfcef05 ("ALSA: usb-audio: Add resume support for FTU controls") +Fixes: 388fdb8f882a ("ALSA: usb-audio: Support changing input on Sound Blaster E1") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Link: https://patch.msgid.link/20260429-alsa-usb-quirks-cache-rollback-v1-1-01b35c688b80@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_quirks.c | 45 +++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 37 insertions(+), 8 deletions(-) + +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -333,6 +333,7 @@ static int snd_audigy2nx_led_put(struct + int index = kcontrol->private_value & 0xff; + unsigned int value = ucontrol->value.integer.value[0]; + int old_value = kcontrol->private_value >> 8; ++ unsigned long old_pval = kcontrol->private_value; + int err; + + if (value > 1) +@@ -341,7 +342,11 @@ static int snd_audigy2nx_led_put(struct + return 0; + kcontrol->private_value = (value << 8) | index; + err = snd_audigy2nx_led_update(mixer, value, index); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kcontrol->private_value = old_pval; ++ return err; ++ } ++ return 1; + } + + static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list) +@@ -491,6 +496,7 @@ static int snd_emu0204_ch_switch_put(str + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + struct usb_mixer_interface *mixer = list->mixer; + unsigned int value = ucontrol->value.enumerated.item[0]; ++ unsigned long old_pval = kcontrol->private_value; + int err; + + if (value > 1) +@@ -501,7 +507,11 @@ static int snd_emu0204_ch_switch_put(str + + kcontrol->private_value = value; + err = snd_emu0204_ch_switch_update(mixer, value); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kcontrol->private_value = old_pval; ++ return err; ++ } ++ return 1; + } + + static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list) +@@ -812,7 +822,11 @@ static int snd_xonar_u1_switch_put(struc + + kcontrol->private_value = new_status; + err = snd_xonar_u1_switch_update(list->mixer, new_status); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kcontrol->private_value = old_status; ++ return err; ++ } ++ return 1; + } + + static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list) +@@ -1161,7 +1175,8 @@ static int snd_nativeinstruments_control + struct snd_ctl_elem_value *ucontrol) + { + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); +- u8 oldval = (kcontrol->private_value >> 24) & 0xff; ++ unsigned long old_pval = kcontrol->private_value; ++ u8 oldval = (old_pval >> 24) & 0xff; + u8 newval = ucontrol->value.integer.value[0]; + int err; + +@@ -1171,7 +1186,11 @@ static int snd_nativeinstruments_control + kcontrol->private_value &= ~(0xff << 24); + kcontrol->private_value |= (unsigned int)newval << 24; + err = snd_ni_update_cur_val(list); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kcontrol->private_value = old_pval; ++ return err; ++ } ++ return 1; + } + + static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = { +@@ -1329,7 +1348,8 @@ static int snd_ftu_eff_switch_put(struct + struct snd_ctl_elem_value *ucontrol) + { + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); +- unsigned int pval = list->kctl->private_value; ++ unsigned long old_pval = list->kctl->private_value; ++ unsigned int pval = old_pval; + int cur_val, err, new_val; + + cur_val = pval >> 24; +@@ -1340,7 +1360,11 @@ static int snd_ftu_eff_switch_put(struct + kctl->private_value &= ~(0xff << 24); + kctl->private_value |= new_val << 24; + err = snd_ftu_eff_switch_update(list); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kctl->private_value = old_pval; ++ return err; ++ } ++ return 1; + } + + static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, +@@ -2138,13 +2162,18 @@ static int snd_soundblaster_e1_switch_pu + { + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + unsigned char value = !!ucontrol->value.integer.value[0]; ++ unsigned long old_pval = kcontrol->private_value; + int err; + + if (kcontrol->private_value == value) + return 0; + kcontrol->private_value = value; + err = snd_soundblaster_e1_switch_update(list->mixer, value); +- return err < 0 ? err : 1; ++ if (err < 0) { ++ kcontrol->private_value = old_pval; ++ return err; ++ } ++ return 1; + } + + static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list) diff --git a/queue-6.12/alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch b/queue-6.12/alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch new file mode 100644 index 0000000000..4b492f1210 --- /dev/null +++ b/queue-6.12/alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch @@ -0,0 +1,69 @@ +From d8f802ccf1fdbeb89d62748d6a0d0fbd442c8127 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= +Date: Wed, 29 Apr 2026 10:20:02 -0300 +Subject: ALSA: usb-audio: Update Babyface Pro control caches only after successful writes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +commit d8f802ccf1fdbeb89d62748d6a0d0fbd442c8127 upstream. + +snd_bbfpro_ctl_put() and snd_bbfpro_vol_put() +cache the requested packed control state in +kcontrol->private_value before issuing the USB write. + +Their get and resume paths use that cached value directly, +so a failed write can leave the driver reporting and later +replaying a setting the hardware never accepted. + +Update the cached state only after a successful USB write. + +Fixes: 3e8f3bd04716 ("ALSA: usb-audio: RME Babyface Pro mixer patch") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Link: https://patch.msgid.link/20260429-alsa-usb-quirks-cache-rollback-v1-2-01b35c688b80@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_quirks.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -2958,12 +2958,14 @@ static int snd_bbfpro_ctl_put(struct snd + if (val == old_value) + return 0; + ++ err = snd_bbfpro_ctl_update(mixer, reg, idx, val); ++ if (err < 0) ++ return err; ++ + kcontrol->private_value = reg + | ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT) + | ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT); +- +- err = snd_bbfpro_ctl_update(mixer, reg, idx, val); +- return err < 0 ? err : 1; ++ return 1; + } + + static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list) +@@ -3156,11 +3158,13 @@ static int snd_bbfpro_vol_put(struct snd + + new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK; + ++ err = snd_bbfpro_vol_update(mixer, idx, new_val); ++ if (err < 0) ++ return err; ++ + kcontrol->private_value = idx + | (new_val << SND_BBFPRO_MIXER_VAL_SHIFT); +- +- err = snd_bbfpro_vol_update(mixer, idx, new_val); +- return err < 0 ? err : 1; ++ return 1; + } + + static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list) diff --git a/queue-6.12/alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch b/queue-6.12/alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch new file mode 100644 index 0000000000..c45791f16b --- /dev/null +++ b/queue-6.12/alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch @@ -0,0 +1,156 @@ +From a440c17869ecd71da0f295b62868fc742d09a8ba Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= +Date: Sun, 19 Apr 2026 17:30:32 -0300 +Subject: ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +commit a440c17869ecd71da0f295b62868fc742d09a8ba upstream. + +snd_us16x08_comp_put() and snd_us16x08_eq_put() update their +software stores before sending the USB write. If the transfer +fails, later get callbacks report a value the hardware never +accepted. + +Build the outgoing message from the current store plus the +pending value, then commit the store only after a successful +write. + +Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20260419-usb-write-error-propagation-v1-4-5a3bd4a673ae@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_us16x08.c | 78 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 52 insertions(+), 26 deletions(-) + +--- a/sound/usb/mixer_us16x08.c ++++ b/sound/usb/mixer_us16x08.c +@@ -436,6 +436,7 @@ static int snd_us16x08_comp_put(struct s + int index = ucontrol->id.index; + char buf[sizeof(comp_msg)]; + int val_idx, val; ++ int threshold, ratio, attack, release, gain, switch_on; + int err; + + val = ucontrol->value.integer.value[0]; +@@ -448,36 +449,61 @@ static int snd_us16x08_comp_put(struct s + /* new control value incl. bias*/ + val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE; + +- store->val[val_idx][index] = ucontrol->value.integer.value[0]; ++ threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)] ++ [index]; ++ ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]; ++ attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]; ++ release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)] ++ [index]; ++ gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index]; ++ switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)] ++ [index]; ++ ++ switch (val_idx) { ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD): ++ threshold = val; ++ break; ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO): ++ ratio = val; ++ break; ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK): ++ attack = val; ++ break; ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE): ++ release = val; ++ break; ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN): ++ gain = val; ++ break; ++ case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH): ++ switch_on = val; ++ break; ++ } + + /* prepare compressor URB message from template */ + memcpy(buf, comp_msg, sizeof(comp_msg)); + + /* place comp values in message buffer watch bias! */ +- buf[8] = store->val[ +- COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index] +- - SND_US16X08_COMP_THRESHOLD_BIAS; +- buf[11] = ratio_map[store->val[ +- COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]]; +- buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index] +- + SND_US16X08_COMP_ATTACK_BIAS; +- buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index] +- + SND_US16X08_COMP_RELEASE_BIAS; +- buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index]; +- buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index]; ++ buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS; ++ buf[11] = ratio_map[ratio]; ++ buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS; ++ buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS; ++ buf[20] = gain; ++ buf[26] = switch_on; + + /* place channel selector in message buffer */ + buf[5] = index + 1; + + err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg)); + +- if (err > 0) { +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err); ++ return err; + } + ++ store->val[val_idx][index] = val; ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; + return 1; + } + +@@ -579,11 +605,10 @@ static int snd_us16x08_eq_put(struct snd + /* copy URB buffer from EQ template */ + memcpy(buf, eqs_msq, sizeof(eqs_msq)); + +- store->val[b_idx][p_idx][index] = val; +- buf[20] = store->val[b_idx][3][index]; +- buf[17] = store->val[b_idx][2][index]; +- buf[14] = store->val[b_idx][1][index]; +- buf[11] = store->val[b_idx][0][index]; ++ buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index]; ++ buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index]; ++ buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index]; ++ buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index]; + + /* place channel index in URB buffer */ + buf[5] = index + 1; +@@ -593,14 +618,15 @@ static int snd_us16x08_eq_put(struct snd + + err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq)); + +- if (err > 0) { +- /* store new value in EQ band cache */ +- elem->cached |= 1 << index; +- elem->cache_val[index] = val; +- } else { ++ if (err < 0) { + usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err); ++ return err; + } + ++ store->val[b_idx][p_idx][index] = val; ++ /* store new value in EQ band cache */ ++ elem->cached |= 1 << index; ++ elem->cache_val[index] = val; + return 1; + } + diff --git a/queue-6.12/series b/queue-6.12/series index 0ee01d1312..9a032afe4d 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -71,3 +71,16 @@ iio-temperature-ltc2983-fix-reinit_completion-called-after-conversion-start.patc alsa-virtio-add-missing-384-khz-pcm-rate-mapping.patch alsa-virtio-validate-control-metadata-from-the-device.patch alsa-ymfpci-check-snd_ctl_new1-return-value.patch +alsa-caiaq-fix-out-of-bounds-read-in-the-traktor-kontrol-s4-input-parser.patch +alsa-cmipci-check-snd_ctl_new1-return-value.patch +alsa-es1938-check-snd_ctl_new1-return-value.patch +alsa-firewire-isight-bound-the-sample-count-to-the-packet-payload.patch +alsa-gus-check-snd_ctl_new1-return-value.patch +alsa-ice1712-check-snd_ctl_new1-return-value.patch +alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch +alsa-usb-audio-avoid-kobject-path-lookup-in-dualsense-match.patch +alsa-usb-audio-propagate-errors-in-scarlett_ctl_enum_put.patch +alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callbacks.patch +alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch +alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch +alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch