We've used __bitwise and __force for some integer parameters for
sanity-checks via sparse, with a hope that it'll reduce the misuse or
incorrect assignments. This worked in principle, but OTOH, it's been
quite a PITA, making the code much uglier than its gain, too, because
one had to cast with __force everywhere. Also, Rust-binding would
skip those defines because of __force usage, which will become more
pains in near future.
So let's drop __bitwise and __force prefix usages. In this patch, we
start cleaning up the UAPI headers at first. The former bit-wised
typedefs are still kept for compatibility for now.
As it's only markers for sparse, the changes are absolutely safe, per
se. Only that we'll need to watch out more carefully about the
variable usage for PCM format type, etc.
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260812060557.80445-2-tiwai@suse.de
The HP 250 G8 Laptop PC (subsystem 103c:85f3) using the Realtek ALC236
codec requires a specific quirk to enable the mute button LED.
Currently, the audio mutes in software, but the physical indicator
light remains unlit.
Adding a quirk entry to the alc236_fixup_tbl with the
ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup correctly maps the
LED to the mute state via COEF index 0x07.
Signed-off-by: Bramwel Barack <bramwelbarack89@gmail.com>
Link: https://patch.msgid.link/20260812192832.69240-1-bramwelbarack89@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_hdac_ext_stream_reset() polls PPLCCTL for STRST by masking the
register value with AZX_PPLCCTL_STRST:
val = readl(...) & AZX_PPLCCTL_STRST;
The same masked value is then used when clearing STRST. Since val
contains no bits other than STRST, clearing STRST from it always
produces zero. The subsequent writel() therefore writes zero to the
entire PPLCCTL register instead of clearing only the reset bit.
PPLCCTL contains other stream control fields, including the stream tag
in AZX_PPLCCTL_STRM_MASK. Those fields must not be modified as a side
effect of clearing stream reset.
Use snd_hdac_updatel() to clear STRST, matching the existing set-reset
path and preserving all unrelated PPLCCTL bits.
Fixes: df203a4e46 ("ALSA: hdac_ext: add extended stream capabilities")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/43BB7930B0F07C09+20260813065524.1955696-1-raoxu@uniontech.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The struct describes a bounce payload of an error code followed by the
original event and its external data. No kernel has ever sent that.
Before commit efc86691e4 ("ALSA: seq: Fix kernel heap address leak in
bounce_error_event()") the kernel emitted no SNDRV_SEQ_EVENT_BOUNCE at
all, and since then it sends the event record alone.
Nothing has ever read it either. Its only accessor,
snd_seq_event_bounce_ext_data(), has had no caller for the whole git
history, and it did not even compile until commit c7e0b5bf9f ("[ALSA]
Remove xxx_t typedefs: Sequencer") incidentally repaired the type name
it referred to, three years after the git import. Drop the accessor
along with the struct.
This removes a definition from a UAPI header. Since no kernel ever
produced the layout, nothing can have parsed it, but a program that
merely names the type will need to stop.
Suggested-by: Takashi Iwai <tiwai@suse.de>
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260812141506.4016387-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
hda_bus_match() has an unreachable 'return 1' after an if/else that
covers both branches. Remove the superfluous return and simplify the
control flow by dropping the else branch.
hdac_codec_match() uses a redundant if/else to return 1 or 0.
Simplify to a single return statement.
Signed-off-by: Bob Song <songxiebing@kylinos.cn>
Link: https://patch.msgid.link/20260812033007.633564-1-songxiebing@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The fixed audio formats for the PreSonus AudioBox USB specify a discrete
rate mask but leave nr_rates at zero and rate_table unset. find_format()
therefore rejects every requested rate, preventing the playback and
capture streams from being opened.
Add the advertised 44100 and 48000 Hz rates to both streams and report
their 24 significant bits.
Fixes: 34fe4a9df2 ("ALSA: usb-audio: Add quirk for PreSonus AudioBox USB")
Cc: stable@vger.kernel.org
Signed-off-by: Trevor Vorhees <vorhees-work@proton.me>
Link: https://patch.msgid.link/20260811-audiobox-usb-fix-v1-1-13c8b7f071ea@proton.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The bounce_error_event() embeds the failed event in the bounce payload
by pointing data.ext.ptr at it. When that event is a queued
variable-length event, its own data.ext.ptr holds the address of its
first extension cell, put there by snd_seq_event_dup(). The payload
goes out verbatim through snd_seq_expand_var_event(), so the address
reaches userspace.
That is the same address commit 705dd6dcbc ("ALSA: seq: Clear
variable event pointer on read") removed from the event header. The
read path still clears it there, just above the call that expands the
payload.
Embed a sanitised copy instead, treated exactly as snd_seq_read()
treats the header. A stack copy is enough because delivery is
synchronous and snd_seq_event_dup() copies before returning.
An unprivileged client reaches this by setting SNDRV_SEQ_FILTER_BOUNCE,
queueing a variable-length event to a port that does not exist and
reading the bounce back. Eight bytes on 64-bit, from its own pool.
Fixes: efc86691e4 ("ALSA: seq: Fix kernel heap address leak in bounce_error_event()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260811131835.3837024-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The ThinkPad X1 Carbon 6th Gen (ALC285, SSID 17aa:225c) has no physical
Line Out jack. The 3.5mm headphone jack is wired to the headphone DAC,
but the ALSA HDA driver names the corresponding control as
"Line Out Playback Volume" (node 0x02).
PipeWire's ALSA Card Profile (ACP) silences "Line Out" when headphones
are activated, which incorrectly mutes the headphone output.
Add a quirk to rename the control to "Headphone Playback Volume" via
alc285_lenovo_dac_rename().
Tested on openSUSE Tumbleweed (kernel 7.1.5):
- Control renamed successfully, no name collision with "Headphone Playback Switch"
- Headphone output works across multiple PipeWire/WirePlumber restarts
and port switches
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221522
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Tested-by: Branislav Klocok <branislav.klocok@orava.sk>
Link: https://patch.msgid.link/20260811062734.400512-1-zhangheng@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Replace manual ioremap() calls with pcim_iomap() which uses devres
for automatic cleanup. This eliminates the need for manual iounmap()
in both the error path of asihpi_adapter_probe() and the
asihpi_adapter_remove() function.
The pcim_iomap() helper is cleaner and less error-prone since it
handles unmapping automatically when the PCI device is released.
Assisted-by: opencode/big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20260811042122.44923-1-rosenp@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The Lenovo Legion Pro 5 16ADR10 (codec SSID 0x17aa:0x3926) suffers from
distorted/crackling speaker output, as only one speaker pin is driven
without proper COEF/amp initialization.
Add HDA_CODEC_QUIRK applying ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN
to enable both speaker pins and proper amp initialization, restoring
clean audio output at all volume levels.
Tested: Both internal speaker pairs are now driven correctly and
distortion is gone; headphone output remains unaffected.
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221595
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Tested-by: Efe Yılmaz <efe.tcyilmaz@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260811024902.134457-3-zhangheng@kylinos.cn
The UMP sequencer client protects its output rawmidi file (out_rfile)
with an rwlock (output_lock). seq_ump_process_event(), the port's
event_input callback, reads out_rfile.output under read_lock on every
delivered UMP event, while the open/close paths (serialized by
ump->open_mutex) publish and clear out_rfile under write_lock.
Output is opened/closed only on the subscribe/use lifecycle while
delivery happens per event, so this is another read-mostly hot path.
Convert it to RCU and drop the rwlock. out_rfile is an embedded struct
rather than a pointer, so instead of restructuring it, add an
RCU-protected shadow of the substream (out_substream) for the reader;
out_rfile itself becomes writer-only state accessed solely under
open_mutex. The reader now runs lock-free under rcu_read_lock() via
rcu_dereference(), and open publishes the substream with
rcu_assign_pointer().
On close the substream is cleared with rcu_assign_pointer(NULL) and the
rawmidi is released only after synchronize_rcu(), so no reader in the
delivery path can still be writing to the substream when
snd_rawmidi_kernel_release() runs.
Dropping write_lock_irqsave() from the writers is safe: they run in
process context under open_mutex, and the sole atomic reader now uses
RCU, which is IRQ-safe.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260810133711.42483-6-tiwai@suse.de
Each virmidi device keeps a list of its opened input files (filelist)
protected by both an rwlock (filelist_lock) and a rw_semaphore
(filelist_sem). snd_virmidi_dev_receive_event() walks the list on the
sequencer event input path -- read_lock() when the event is delivered in
atomic context, down_read() otherwise -- decoding each incoming event
into the file's rawmidi buffer. The writers (input open/close) take both
locks to add/remove entries.
This is another typical dual-lock read-mostly pattern as the port
subscriber list: files are opened/closed rarely while the receive
callback runs per event. Let's convert the traversal to RCU and drop
the rwlock; the existing filelist_sem keeps serializing the writers.
The atomic input path now runs lock-free under rcu_read_lock(), and
both readers share a single list_for_each_entry_rcu() (valid under the
rwsem via lockdep_is_held()). The writers switch to
list_add_tail_rcu() / list_del_rcu().
snd_virmidi_input_close() freed the entry (parser and struct)
immediately after list_del. A concurrent lockless reader in the atomic
path may still be dereferencing it, so the close path now waits for an
RCU grace period after list_del_rcu() before freeing; synchronize_rcu()
is used rather than kfree_rcu() because the parser must also be released
after the grace period, not just the struct. Non-atomic readers are
already excluded by the down_write, so only the atomic RCU readers need
the grace period.
Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260810133711.42483-5-tiwai@suse.de
The sequencer keeps a global table of clients (clienttab[]) indexed by
client id, protected by the global clients_lock spinlock. The lookup
snd_seq_client_use_ptr() reads a slot and takes a use_lock reference on
the client, and this runs on the event delivery hot path: every
dispatched event resolves its destination (and often source) client
through it. The spinlock's only job on the read side is to make the
"pointer is non-NULL" test and the reference increment indivisible with
respect to the writer that nulls the slot and then drains the refcount.
Clients come and go rarely but delivery happens constantly, so this is
yet another read-mostly case as the port and subscriber lists.
Convert the table to RCU: the read side now runs lock-free under
rcu_read_lock() and takes the use_lock reference via
rcu_dereference(), removing contention on the single global spinlock
from the delivery path. The writers keep clients_lock (still needed
to serialize slot allocation) and publish / unpublish via
rcu_assign_pointer(); creation and destruction remain serialized at a
higher level by register_mutex.
As with the ports, the client is not freed via kfree_rcu(): its lifetime
is governed by the use_lock refcount drained in seq_free_client1().
list_del under the old spinlock excluded a concurrent lookup from taking
a new reference once the slot was nulled; rcu_assign_pointer(NULL) offers
no such exclusion, so a reader still holding the old pointer can grab a
reference after the unpublish. seq_free_client1() therefore calls
synchronize_rcu() after nulling the slot and before snd_use_lock_sync():
once the grace period elapses no new reference can appear, and the
existing drain then frees the client safely.
clienttablock[] keeps its slot-reservation role (create/free are
serialized by register_mutex); its read on the lookup path only gates
module autoload, so a lockless read is harmless. Dropping the spinlock
from the read path is safe: clients_lock is now taken only by the
process-context writers, and the sole atomic reader uses RCU, which is
IRQ-safe.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260810133711.42483-4-tiwai@suse.de
Each sequencer client keeps a list of its ports (ports_list_head)
protected by both an rwlock (ports_lock) and a mutex (ports_mutex).
The rwlock is taken read-side on the event delivery hot path:
snd_seq_port_use_ptr() walks the list to resolve a port on every
dispatched event, while the mutex serializes port creation/deletion.
Ports change rarely but delivery happens constantly, so this is the
another read-mostly case as the port subscriber list. Convert the
port list traversal to RCU and drop the rwlock entirely; the existing
ports_mutex keeps serializing the writers. The atomic delivery path
(snd_seq_port_use_ptr(), snd_seq_port_query_nearest()) now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.
The writers switch to list_add_tail_rcu()/list_del_rcu().
snd_seq_insert_port() now stores the port number and name before
publishing the node so RCU readers only ever observe a fully
initialized port. One drawback is that snd_seq_delete_all_ports()
drops the O(1) splice trick and unlinks each port individually,
though: the splice repointed the last port's ->next away from the list
head, which would send a concurrent lockless reader off the end of the
list.
Unlike the subscriber objects, ports are not freed via kfree_rcu():
port_delete() must drain outstanding use_lock references (and run
private_free()) synchronously. The rwlock previously guaranteed that
no reader could take a new use_lock reference once the port was
unlinked -- list_del under write_lock excluded snd_use_lock_use()
under read_lock. list_del_rcu() offers no such exclusion, so a reader
still traversing the list can grab a reference after the unlink.
port_delete() therefore calls synchronize_rcu() after the port has
been unlinked and before snd_use_lock_sync(): once the grace period
elapses no new reference can appear, and the existing drain then frees
the port safely.
Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260810133711.42483-3-tiwai@suse.de
Each sequencer port keeps two subscriber groups (c_src and c_dest),
each protected by both an rwlock (list_lock) and a rw_semaphore
(list_mutex). The rwlock is taken read-side in the event delivery hot
path (__deliver_to_subscribers()) for delivering every event to
subscribers, while the mutex serializes subscribe/unsubscribe and
covers the sleepable delivery and query walks.
Subscriptions change rarely but delivery happens constantly, so this is
a textbook read-mostly case. Convert the subscriber list traversal to
RCU and drop the rwlock entirely while keeping the existing list_mutex
for serializing the writers. The atomic delivery path now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.
Along with the conversion to RCU, the subscriber lists are switched
from list_head to hlist so that removal can use hlist_del_init_rcu():
it keeps the ->next pointer intact for concurrent readers while
clearing ->pprev, which lets the double-deletion guard (added in
commit 13d5e5d472) keep detecting an already-removed entry via
hlist_unhashed().
Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe. Port lifetime handling (use_lock/closing drain in
port_delete()) is orthogonal and unchanged.
Note that the conversion to RCU has another merit: it automatically
"fixes" the (rather false) lockdep warnings for the doubly read-locks
of the same subscriber list, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260810133711.42483-2-tiwai@suse.de
Both the front headphone jack and the rear line-out jack play back
at a barely audible volume on the Beelink SER6 Max (ALC897, PCI subsystem
ID 1f66:0202), even with all mixer controls at 0dB. GPIO2 on the
codec gates an external headphone/line amplifier that the generic
parser never enables. Add a fixup that asserts it. Verified fixed
on both jacks.
Signed-off-by: Brian Koebbe <brian@koeb.be>
Link: https://patch.msgid.link/20260810145700.1206010-1-brian@koeb.be
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This is managed by USB core and drivers aren't expected to touch it.
It should only be not NULL on a submitted URB, in which case clearing
defeats the "submitted while active" sanity check in usb_submit_urb()
and may crash the HCD handling the URB and panic the kernel.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Link: https://patch.msgid.link/20260810075728.483c827e.michal.pecio@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
scarlett2_init_notify() used mixer->urb, which
snd_usb_mixer_status_create() allocates for the UAC2 status interrupt
endpoint and mixer.c manages. On a device with that endpoint, the
"already in use" check fires on the status URB and returns 0 for
success without doing anything. No notification URB is submitted, and
cmd_done is left zeroed because it is initialised past that check and
nowhere else. scarlett2_usb_init() then issues SCARLETT2_USB_INIT_1
and wait_for_completion_timeout() would crash adding to the zeroed
wait.head.
Use a separate URB in scarlett2_data, as done for FCP, and initialise
cmd_done in scarlett2_init_private(). mixer.c was also freeing the URB
in snd_usb_mixer_free() and resubmitting it in
snd_usb_mixer_activate(), so scarlett2 must now do both: add
scarlett2_cleanup_urb(), called from private_free and private_suspend,
and a private_resume callback to re-establish the URB after resume.
scarlett2_init_notify() is reached from there, and the URB kill path
in scarlett2_notify() completes cmd_done, leaving a stale count that
would satisfy the next command's wait before the device ACKs. Use
reinit_completion() to clear it.
Also free the URB if the transfer buffer allocation fails, and both if
usb_submit_urb() fails. Move scarlett2_init_notify() up next to
scarlett2_cleanup_urb() so scarlett2_init_private() can reference it
without a forward declaration.
Fixes: 1b65088958 ("ALSA: scarlett2: Implement handling of the ACK notification")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/ffb8ba37d5d605dfdfd8576949d67098651f9349.1786290885.git.g@b4.vu
fcp_init_notify() used mixer->urb, which snd_usb_mixer_status_create()
allocates for the optional UAC2 status interrupt endpoint and mixer.c
kills, resubmits and frees. On a device with that endpoint,
fcp_init_notify()'s "already set up" early return fires on the status
URB and returns success without doing anything. No FCP notification
URB is submitted, and cmd_done is left zeroed because it is
initialised past that early return and nowhere else. fcp_init() then
issues init1_opcode and wait_for_completion_timeout() would crash
adding to the zeroed wait.head. fcp_cleanup_urb() would also kill and
free mixer.c's status URB.
Use a separate URB in fcp_data, and initialise cmd_done in
fcp_init_private() where fcp_data is allocated. fcp_init_notify() is
reached again after suspend via fcp_reinit(), and the URB kill path in
fcp_notify() completes cmd_done, leaving a stale count that would
satisfy the next command's wait before the device ACKs. Use
reinit_completion() to clear it.
Fixes: 46757a3e7d ("ALSA: FCP: Add Focusrite Control Protocol driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/2cad281e6434024ca48a9ecc94fa19d6777e9be7.1786290885.git.g@b4.vu
The BIOS of the F+ FLAPTOP r laptop (Realtek ALC897, SSID 1e63:6d9a)
declares only pin 0x1b, the headphone output of the 3.5 mm combo jack.
Every other external pin is left at 0x411111f0, so the headset mic pin
0x19 is never parsed and no headset mic input exists. The pin is wired
on this board - retasking it makes the headset mic record.
Reuse ALC897_FIXUP_HP_HSMIC_VERB, which already sets the pin config this
machine needs: 0x19 as a headset mic without its own presence detect.
Only 0x1b reports jack presence here, so a mic pin with presence detect
would leave the driver in auto-mic mode waiting for an event that never
arrives.
Without the quirk the generic parser retasks the lone headphone pin as
an input instead. That surfaces as a "Headphone Mic" input which records
only the internal mic bleed, so the headset mic appears present but dead.
Tested on ALT Linux, kernel 6.12, by recording a CTIA headset mic on the
combo jack with the internal mic as a reference.
ALSA info before the patch:
https://alsa-project.org/db/?f=18363eddea933baee100c9bf461d0e5cf74c8de2
ALSA info after the patch:
https://alsa-project.org/db/?f=48ae2cd7aaf1eb0f24639ce83cd38cfd93b25f76
Cc: stable@vger.kernel.org # 6.12.x
Signed-off-by: Ajrat Makhmutov <rauty@altlinux.org>
Link: https://patch.msgid.link/20260808185500.2564948-1-rauty@altlinux.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
set_sample_rate_v2v3() returns early when the clock already reports the
requested rate:
prev_rate = get_sample_rate_v2v3(chip, fmt->iface,
fmt->altsetting, clock);
if (prev_rate == rate)
goto validation;
A device advertising exactly one sample rate always takes this branch, so
it never receives a SET_CUR for CS_SAM_FREQ_CONTROL at all.
The Mackie DLZ Creator XS (0a73:003a, 14 in / 4 out, 48 kHz only) requires
that write. Without it the device drops off the USB bus roughly 0.2-1.8 s
into any stream, clearing its port CONNECTION bit; captured audio is
byte-correct until the instant it vanishes.
USBPcap traces of a cold-booted device on Windows show SET_CUR 48000 issued
unconditionally on every stream start, followed by clean streaming. The
device is otherwise driven with plain class-compliant UAC2 - it also works
on iOS, which cannot load a vendor driver - so no vendor-specific
initialization is involved.
The device is self-powered, so the resulting state survives a USB replug:
initializing it on any host that issues the write leaves it working on
Linux until it is power-cycled, which made the failure look intermittent.
Add a quirk flag rather than dropping the early exit, since the opposite
requirement also exists in-tree: QUIRK_FLAG_FIXED_RATE suppresses rate
setting for single-rate devices (JBL Quantum610/810). The two behaviors
are device-dependent and cannot both be the default.
A/B on identically cold-booted hardware, same kernel, same port, repeated
twice:
without the flag device dropped after 5-6 s, then again after 3-4 s
with the flag 20 s playback followed by 20 s of 14-channel capture,
960000 frames, zero re-enumerations
This change was developed with an AI coding assistant. The assistant did
the trace analysis that located the bug and wrote the patch and this
changelog; the hardware testing, the cold-boot cycles and the decision to
submit were the author's. Several earlier hypotheses it proposed - URB
queue depth, isochronous packet under-allocation, endpoint start ordering -
were disproven by measurement before this one.
The bug was located with usbmon on Linux and USBPcap on Windows, by
diffing an enumeration capture of a cold-booted device on each host.
Verified on physical hardware by the A/B above.
Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: JJ Macalinao <jj@macalinao.org>
Link: https://patch.msgid.link/20260808172726.1107550-1-jj@macalinao.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The cvt_legacy_sysex_to_ump() initialises only the first word of the
output packet and ORs the data bytes into it. The second word is left
alone, and the conversion context is kept across calls, so it still
carries the previous packet's bytes. Those stale bits corrupt the new
data. Any SysEx longer than six data bytes is affected.
A SysEx with the twelve data bytes 01..0c comes out as:
30160102 03040506
30260708 0b0e0f0e
The second packet declares six data bytes and four of them are wrong,
inside the declared length.
The sibling cvt_legacy_cmd_to_ump() already clears the second word. Do
the same here.
Fixes: 0b5288f5fe ("ALSA: ump: Add legacy raw MIDI support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260808014554.3550153-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The GA403UM (SSID 1043:1044) uses the same ALC285 codec + dual CS35L56
I2C amplifier topology as the GA403U and GA403W variants, which already
have quirk entries (1043:1b13, 1043:1024). Without the quirk, the
woofers sit on a separate DAC from the tweeters, so the hardware volume
control only scales part of the speaker system and the headset
microphone pins are not configured.
Apply the existing ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC fixup to the
GA403UM as well.
Signed-off-by: Garrett Blackmon <garrett@blackmon.dev>
Link: https://patch.msgid.link/20260807150708.33785-1-garrett@blackmon.dev
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The HP Spectre x360 2-in-1 Laptop 16-aa0xxx with PCI subsystem ID
0x103c:0x8c17 only gets the CS35L41 amplifier setup from
ALC287_FIXUP_CS35L41_I2C_2, so the speaker-mute and mic-mute keyboard
LEDs do not work.
Use ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX like subsystem ID 0x8c16 so
the mute LEDs work.
Tested on HP Spectre x360 2-in-1 Laptop 16-aa0xxx.
Signed-off-by: Shang En Sim <sim@shangen.org>
Link: https://patch.msgid.link/20260807055139.58707-1-sim@shangen.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Although portman2x4 driver has a check of the given devptr->id value,
it doesn't check for a negative id, which is often given as "none" or
such value when bound via sysfs. This may lead to OOB access for
index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-7-tiwai@suse.de
Although mts64 driver has a check of the given devptr->id value, it
doesn't check for a negative id, which is often given as "none" or
such value when bound via sysfs. This may lead to OOB access for
index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-6-tiwai@suse.de
virmidi driver blindly trusts that the given devptr->id value is
within the proper card index range at probe. It's OK for the devices
the driver itself creates at the module probe time, but if the device
is bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-5-tiwai@suse.de
serial-u16550 driver blindly trusts that the given devptr->id value is
within the proper card index range at probe. It's OK for the devices
the driver itself creates at the module probe time, but if the device
is bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-4-tiwai@suse.de
mpu401 driver blindly trusts that the given devptr->id value is within
the proper card index range at probe. It's OK for the devices the
driver itself creates at the module probe time, but if the device is
bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-3-tiwai@suse.de
aloop driver blindly trusts that the given devptr->id value is within
the proper card index range at probe. It's OK for the devices the
driver itself creates at the module probe time, but if the device is
bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-2-tiwai@suse.de
The ASUS UM6702RA/RC (subsystem 0x1043:0x1ee2) currently has two
duplicate quirk entries: one using HDA_CODEC_QUIRK with
ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1, and another using
SND_PCI_QUIRK with ALC287_FIXUP_CS35L41_I2C_2.
Since these entries cover the same machine, the duplicate is redundant
and should be merged. The correct fixup to keep is
ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1, as it additionally addresses
the issue where the volume cannot be adjusted properly.
Merge the two entries into a single SND_PCI_QUIRK entry with the
appropriate fixup.
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Link: https://patch.msgid.link/20260806054505.43717-2-zhangheng@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The ASUS Strix G615 series (subsystem IDs 0x1043:0x1204 and 0x1043:0x1214)
currently have duplicate quirk entries: one using HDA_CODEC_QUIRK with
ALC287_FIXUP_TAS2781_I2C, and another using SND_PCI_QUIRK with
ALC287_FIXUP_TXNW2781_I2C_ASUS.
Since these entries cover the same machines, the duplicate entries are
redundant and may cause confusion. The correct fixup for these models
should be ALC287_FIXUP_TXNW2781_I2C_ASUS, as the TAS2781 fixup was
likely a mistake.
Merge the two entries into a single SND_PCI_QUIRK entry with the
correct fixup, removing the redundant HDA_CODEC_QUIRK entries.
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Link: https://patch.msgid.link/20260806054505.43717-1-zhangheng@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The mute LED on the HP Laptop 15-dy0xxx (PCI SSID 103c:864f, Realtek
ALC236) does not work, because the machine has no entry in the quirk
table. No fixup is applied, so no mute LED classdev is registered and
nothing ever drives the LED.
The LED is controlled by COEF index 0x07, bit 0. This was verified on
the hardware with hda-verb: setting the bit lights the mute LED and
clearing it turns the LED off.
hda-verb /dev/snd/hwC0D0 0x20 SET_COEF_INDEX 0x07
hda-verb /dev/snd/hwC0D0 0x20 SET_PROC_COEF 0x1 # LED on
hda-verb /dev/snd/hwC0D0 0x20 SET_PROC_COEF 0x200 # LED off
That is exactly what ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 configures, and
the closely related HP Laptop 15-dw0xxx (103c:85f0) already uses it.
Bit 9 (0x200) is set by default on this board and is preserved by the
fixup's read-modify-write.
Tested on an HP Laptop 15-dy0xxx (SKU 7FU54UA#ABA, board 864F,
BIOS F.40).
Signed-off-by: Carl Quist <equalizerjr@gmail.com>
Link: https://lore.kernel.org/CAOtcGaxXndKxTK5MVSEcmF-LUy+V51K7fhE=qvLA+VvW5ZyCNA@mail.gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>