100 Commits
Author SHA1 Message Date
Christos Margiolis eb36c35ccf sound tests: Check the return value of close(2)
While here, remove two munmap(2) calls on mappings the tests require to
have failed, since they are practically dead.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D60800
2026-10-27 12:27:32 +01:00
Christos Margiolis 5760c22a05 sound: Let pcm_unregister() tear down a partially initialized device
Since 3107b952f5 ("sound: Merge PCM_ALIVE() with PCM_REGISTERED()"),
pcm_unregister() is gated on PCM_REGISTERED(), so it cannot run unless
pcm_register() has already succeeded, which means drivers will leak
resources if a failure happened prior to this.

Reintroduce PCM_ALIVE(), but test dev rather than the lock. pcm_init()
assigns dev before anything else, so it can tell us whether pcm_init()
has run or not. Make sure to clear it in pcm_unregister() so that a
second call to pcm_unregister() cannot double-free.

While here, publish to sndstat(4) only once pcm_register() has
succeeded.

Reported by:	jah
Fixes:		3107b952f5 ("sound: Merge PCM_ALIVE() with PCM_REGISTERED()")
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	jah, markj
Differential Revision:	https://reviews.freebsd.org/D60801
2026-10-27 12:26:29 +01:00
Christos Margiolis 8dac0bdb4d snd_hda: Identify AMD Audio Coprocessor
This makes the driver attach, but the device is still not usable.

Reported by:	Lukasz Wencki <[email protected]>
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-10-25 11:23:36 +01:00
Christos Margiolis 20381bce4b sound: Remove obsolete comment from sound.h
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-10-08 15:11:21 +02:00
Christos Margiolis 26203cca52 rc.d/mountd: Do not require /etc/exports
mountd exits if it cannot read any exports files. Requiring
/etc/exports, however, unconditionally stops mountd from starting on a
server that exports ZFS datasets only (/etc/zfs/exports).

Let sbin/mountd handle requirements itself, instead of hardcoding
/etc/exports, which is also wrong, because different files can be
specified in mountd_flags.

This patch also works with nfsv4_server_enable="YES", by preserving the
behavior of failing to start if there is no "V4:" line in the exports
file, which is missing by default on ZFS-only exports.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	rmacklem, markj, emaste
Differential Revision:	https://reviews.freebsd.org/D60044
2026-10-07 18:53:28 +02:00
Christos Margiolis 25faf86108 pcm.4: Remove DIAGNOSTICS section
These diagnostics do not exist anymore.

MFC after:	1 week
2026-10-07 09:03:31 +02:00
Christos Margiolis b55b6e1d72 cuse: Rename cuse_server_free() to cuse_server_dtor()
This name is clearer, given that this function is the cdevpriv
destructor callback.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-09-30 11:51:09 +02:00
Christos Margiolis f96c4f45f7 cuse: Assert the server refcount
Assert that the refcount does not underflow before decrementing it, and
that it really is zero by the time the server is freed.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D60043
2026-09-30 11:51:05 +02:00
Christos Margiolis d38ef1aca9 cuse: Implement hot-unload
cuse_kern_uninit() can hang on destroy_dev(), because of threads
sleeping in CUSE_IOCTL_GET_COMMAND, so implement d_purge to wake them up
before calling destroy_dev(). Also do not allow threads to go back to
sleep if the is_closing flag has been set.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D60022
2026-09-30 11:50:41 +02:00
Christos Margiolis fad756fd20 cuse: Use make_dev_s() to create client devices
make_dev_s() sets si_drv1 before the node is published in devfs, which
avoids a race where cuse_client_open() could see it as NULL. It also now
reports finer-grained errors on failure, instead of only ENOMEM.

While here, drop the NULL checks on kern_dev in cuse_server_free_dev(),
since a device is only added to the server's list once it has been
created.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D59874
2026-09-30 11:50:03 +02:00
Christos Margiolis 34b00da59b cuse: Retire unnecessary CUSE_VERSION
No functional change intended.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-09-30 11:49:58 +02:00
Christos Margiolis e923a30ecf cuse: Remove unnecessary semicolon in cuse_convert_error()
No functional change intended.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-09-30 11:49:55 +02:00
Christos Margiolis 40431ec4da cuse: Improve server cleanup
Move cuse_server_unref()'s device cleanup loop into a new
cuse_server_free_devs_locked(), and call it from cuse_server_free()
instead. The cdevpriv destructor now destroys the server's devices
before dropping its reference, which closes the clients using them, so
that the destructor is always the one that takes the last reference.

By the time cuse_server_unref() frees the server, the device list should
be empty, so assert this.

In cuse_kern_uninit(), delete the infinite loop which waits for all open
/dev/cuse instances to exit, and instead call destroy_dev() directly,
which runs their cdevpriv destructor.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D59872
2026-09-30 11:49:52 +02:00
Christos Margiolis 3b3e6473b1 cuse: Create /dev/cuse with MAKEDEV_CHECKNAME
Since we now use make_dev_credf(), make sure to fail kldload if it
returned NULL.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D59863
2026-09-30 11:49:46 +02:00
Christos Margiolis 2fd8d2eb7b cuse: Actually use cuse_modevent()
We can call cuse_kern_init()/cuse_kern_uninit() here, rather than using
SYSINIT/SYSUNINIT.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D59862
2026-09-30 11:49:41 +02:00
Christos Margiolis 872c36cb6f cuse: Fix hang on readv(2) and writev(2) with multiple iovecs
uiomove() leaves an iovec it has just emptied as the current one, so
cuse_client_read() and cuse_client_write() picked it up again on the
next iteration, sent the server a zero-length command, and got zero
bytes back. That left the residual count unchanged, so the loop never
terminated and the call never returned.

Step past empty iovecs at the start of every iteration. This also covers
caller-supplied zero-length iovecs, which hung in the same way

PR:		293489
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib, markj
Differential Revision:	https://reviews.freebsd.org/D59822
2026-09-30 11:49:35 +02:00
Christos Margiolis f492ef8318 Add christos@ to MAINTAINERS and .github/CODEOWNERS
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59912
2026-09-26 15:28:09 +02:00
Christos Margiolis 32137c4106 sound: Retire the version constants
They exist only to fill in MODULE_DEPEND() and MODULE_VERSION(), and
every consumer passed the same value for all three, so the version
range never did anything. Use 1, like the rest of the tree does.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib, emaste
Differential Revision:	https://reviews.freebsd.org/D59873
2026-09-22 19:34:16 +02:00
Christos Margiolis 2793e5498d sound: Use uint8_t instead of legacy u_char
No functional change intended.

MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
2026-09-22 18:11:58 +02:00
Christos Margiolis 17af098383 Revert "virtual_oss(8): Fix cuse.ko check"
parse_options() was moved above cuse_init(), which makes every single
regular virtual_oss invocation which uses cuse_dev_create() fail.

This reverts commit f014795ec3.
2026-09-18 21:56:59 +03:00
Christos Margiolis 47cf9dc786 sound: Lock around mixer_set*() in mixer_init() for consistency
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59110
2026-09-18 21:18:20 +03:00
Christos Margiolis 044ef293a8 sound: Remove unncessary locking in sysctl_hw_snd_hwvol_mixer()
The locking around strlcpy() was because of m->hwvol_mixer, but this is
just an int, so we don't need to lock in this case. Instead lock only
when m->hwvol_mixer is written.

While here, add parentheses around the returns.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59109
2026-09-18 21:18:13 +03:00
Christos Margiolis db62d784f0 sound: Improve some mixer return values and their handling
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59078
2026-09-18 21:18:10 +03:00
Christos Margiolis 6c735475ae sound: Reuse mixer_delete() in mixer_uninit()
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59077
2026-09-18 21:18:01 +03:00
Christos Margiolis 03b59d2e7d sound: Do not set a recording source in mixer_uninit()
We currently set the recording source to SOUND_MIXER_MIC during mixer
deletion. Apart from the fact that this control might not be present on
all devices, it is unnecessary to do that, plus we already set all the
volumes to 0 in the mixer_set() call above.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59076
2026-09-18 21:16:40 +03:00
Christos Margiolis 9548bfa342 sound: Retire mixer_hwvol locked variants
Prior to 9a00e0b8ca ("snd_uaudio: Do not use snd_mixer->lock as
mixer_lock"), there was a need for mixer_hwvol_mute_locked() and
mixer_hwvol_step_locked(), because the unlocked variants would acquire
the lock, but uaudio_hid_rx_callback() would also hold the lock, so this
was a measure to avoid recursion on snd_mixer->lock. Now that
snd_uaudio(4) has a private mixer lock, the locked variants are not only
unnecessary, but wrong, because we now lock the private lock and not the
snd_mixer one, which is what mixer_hwvol_mute_locked() and
mixer_hwvol_step_locked() expect. Retire the locked variants and call
the regular functions instead.

The unlocked variants take the mixer lock, which is now the PCM lock,
and reach uaudio_mixer_ctl_set(), which takes mixer_lock. Calling them
straight from uaudio_hid_rx_callback() would therefore take mixer_lock
and the PCM lock in the opposite order to the mixer ioctl path, so
record what the HID report asked for and perform the volume change at
the end of the callback, with mixer_lock dropped. The USB stack allows a
callback to drop its transfer mutex (see usbdi.9).

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59075
2026-09-18 21:16:03 +03:00
Christos Margiolis 1a31ab15e8 sound: Use snddev_info->lock in place of snd_mixer->lock
snd_mixer and snddev_info have a 1:1 relationship. Now that snd_mixer is
embedded into snddev_info, it makes even more sense for both to share
the PCM lock. The only exceptions to this are MIXER_TYPE_SECONDARY
mixers, which still retain a private lock (snd_mixer->priv_lock),
because they are attached to the device driver, and not snddev_info.
Only snd_emu10kx(4) uses a secondary mixer.

A side-effect of this is that the MIXER_SET_LOCK()/MIXER_SET_UNLOCK()
mess goes away. These macros were used in the mixer_set*() functions to
drop the mixer lock if the driver is Giant-locked and the function can
sleep inside MIXER_SET*() methods, and to avoid an LOR before locking
PCM to guard channel list traversal.

Since mixers now use the PCM lock, drop the channel lock in
chn_syncstate() before calling mix_get(), to avoid an LOR. These lines
were actually already commented out for years.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59074
2026-09-18 21:15:50 +03:00
Christos Margiolis b976154707 sound: Defer macio codec volume writes to a task
tumbler(4), snapper(4) and onyx(4) write the volume over I2C, and
iicbus_transfer() sleeps. This is why mixer_set() drops the mixer lock
around MIXER_SET() for non-MPSAFE drivers, relying on Giant to keep them
serialized.

Store the volume in the softc and let a task do the I2C write with no
lock held, so that the mixer method does not sleep at all. The lock
dropping for non-MPSAFE drivers will be removed in a follow-up patch.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59073
2026-09-18 21:14:29 +03:00
Christos Margiolis a614c07ad4 sound: Embed mixer cdev in snd_mixer
The mixer cdev belongs to the mixer, not to the PCM device, so move it
from snddev_info->mixer_dev into a new snd_mixer->cdev field. snd_mixer
itself is now included in snddev_info.

Also add a MIXER_REGISTERED() macro similar to PCM_REGISTERED().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59071
2026-09-18 21:13:32 +03:00
Christos Margiolis 221babdf9f sound: Simplify how snd_mixer is fetched and how the cdev is created
The primary snd_mixer was reached by accessing the mixer cdev's si_drv1.
This is tedious and ugly, so store the mixer in snddev_info->mixer and
access it directly.

Additionally, create the cdev in a new mixer_make_dev() function (in
similar fashion to dsp_make_dev()) in pcm_register(), when everything is
initialized, instead of risking potential races because mixer_init()
(called before pcm_register()) used to create the cdev.

Also add some NULL checks in pcm_register(), to avoid creating a mixer
cdev when the driver (e.g., fdt/audio_soc.c) does not create a mixer in
the first place, and similarly in pcm_unregister().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59070
2026-09-18 21:12:55 +03:00
Christos Margiolis 13fcc9caaf sound: Standardize mixer_init() call order
Device drivers call mixer_init() in a non-standard order - some before
pcm_init(), and some after pcm_register(). However, both approaches are
potentially risky, and logically weak, since pcm_register() is supposed
to be the function that finalizes sound(4) attach.

Standardize the call ordering by moving all mixer_init() calls after
pcm_init(). This is also necessary for a follow-up patch, which expects
pcm_init() to have run first and initialized the PCM lock.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D59069
2026-09-18 21:12:42 +03:00
Christos Margiolis 694923501f snd_uaudio: Read the UAC2 sample rate back after setting it
Some devices only apply a new sample rate once it has been read back,
and produce no sound at all otherwise.

PR:		294803
Reported by:	[email protected]
Tested by:	[email protected]
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Reviewed by:	emaste
Differential Revision:	https://reviews.freebsd.org/D59616
2026-09-15 15:12:43 +03:00
Christos Margiolis a7258157e1 snd_emu10kx: Make sure the block count and size cover the whole buffer
The playback voices always loop over the whole EMU_PLAY_BUFSZ buffer,
but emupchan_setblocksize() only recorded the new block size and left
the block count as it was set up by emu_vinit(). The blocks then no
longer covered the whole buffer, and the part they left out was played
without ever being written to, which became audible as distortion once
playback started going through a virtual channel.

Resize the buffer, so that the block count and size always cover it.

Fixes:		02d4eeabfd ("sound: Allocate vchans on-demand")
PR:		287687
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D59444
2026-09-07 17:48:21 +03:00
Christos Margiolis 358fe149f5 snd_dummy: Bump primary channel count
Makes it easier to test scenarios involving more than 1 primary channels
per direction.

Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D59085
2026-09-07 16:04:22 +03:00
Christos Margiolis 5e02679f03 sound: Prefer idle primary channels when allocating
dsp_chn_alloc() stopped at the first primary channel that was either
idle or already had vchans. Since the list is walked in order, the first
channel matched both conditions once it had been used, so every client
after the first was stacked onto it as a vchan and the remaining primary
channels were never allocated at all.

This is invisible on devices with a single primary channel, but not on
those which provide several. snd_emu10kx(4), for instance, registers
four primary channels for its front device, each able to run with its
own rate.

Look for an idle primary channel first, and only fall back to sharing
one that already has vchans when there is none left.

Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D59084
2026-09-07 16:04:09 +03:00
Christos Margiolis b5c1ab6c8f snd_hdsp*: malloc(9) with M_WAITOK
Perform the allocations outside the lock section so that we can use
M_WAITOK. Holding the lock here is actually not really necessary and we
could just as well remove it, but keep it for consistency.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D59079
2026-08-22 15:48:50 +03:00
Christos Margiolis f4d953bea7 bhyve: Do not panic on invalid input in HDA emulation
The emulated HDA controller passed values taken from guest registers and
from guest memory straight into assert(), so a guest could abort bhyve
with values the emulation did not expect. Reject them instead.

In case the guest asked to start something and it failed, clear the
corresponding run/enable bit.

PR:		256379, 256381, 256382, 256383, 256384, 256385, 256386, 256498
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Reviewed by:	bnovkov, jhb
Differential Revision:	https://reviews.freebsd.org/D59082
2026-08-22 15:48:32 +03:00
Christos Margiolis 5c3bc8ab42 snd_uaudio: Use uDWord for the UAC2 sample rate
uaudio20_set_speed() split the sample rate into bytes by hand. Use
uDWord and USETDW() instead.

No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D59066
2026-08-21 17:02:19 +03:00
Christos Margiolis f0778a6f9b bcm2835_audio: Remove wrong chn_intr()
chn_trigger() calls bcmchan_trigger() with the channel lock held.
However, bcmchan_trigger() calls chn_intr(), which also tries to lock,
which results in a lock recursion panic. chn_intr() is meant to be
called by the interrupt handler and not inside CHANNEL_TRIGGER()
methods. Remove the call altogether, the bcm2835_worker_play_start()
call that comes after is enough.

Fixes:		69cab2d1bf ("Fix locking in bcm2835_audio driver")
Reported by:	Marco Devesas Campos <[email protected]>
Tested by:	Marco Devesas Campos <[email protected]>
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D59055
2026-08-21 03:47:03 +03:00
Christos Margiolis 3e67b90c55 snd_uaudio: Define USB IDs in usbdevs
No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2026-08-12 00:02:42 +03:00
Christos Margiolis a753ca9c3f sound: Retire sndcard_func
sndcard_func is used as an ivar which passes around device info to the
PCM and MIDI children in snd_csa(4) and snd_emu10kx(4). Simplify this
and retire the need for sndcard_func, by 1) making an ivar only what
used to be stored in sndcard_func->varinfo, 2) replacing
sndcard_func->func with a child comparison, where needed, for instance
in csa_detach().

sndcard_func is harmless in reality, but there is no reason to have the
additional complexity. This way we also avoid the structure allocations.

Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2026-08-11 23:56:55 +03:00
Christos Margiolis afe56ee246 sound: Use unsigned long instead of legacy u_long
No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-08-11 21:35:27 +03:00
Christos Margiolis 2a2705a637 sound: Add missing newline in dsp_make_dev()'s device_printf()
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-07-27 18:52:09 +03:00
Christos Margiolis a46c92aad1 sound: Propagate error value from dsp_make_dev()
It is better to propagate it to pcm_register(), and later to the device
drivers, than to simply ignore it and return ENXIO.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-07-27 17:31:30 +03:00
Christos Margiolis 95439b803f sound: Stop using legacy u_int types
No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-07-27 01:16:47 +03:00
Christos Margiolis 954001a9dd snd_uaudio: Initialize mixer_lock with MTX_RECURSE
Fixes:		fc9dc84823 ("snd_uaudio: Lock usbd_transfer_start() in uaudio_mixer_ctl_set()")
PR:		296682
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2026-07-15 00:16:28 +03:00
Christos Margiolis 815dc35b7b sound: Pass format and speed as arguments to sndbuf_create()
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-07-08 21:18:49 +03:00
Christos Margiolis 69c4e2b68a sound: Remove dead code in dsp_ioctl()
Sponsored by;	The FreeBSD Foundation
MFC after:	1 week
2026-07-08 21:11:54 +03:00
Christos Margiolis 72acd1720a sound: Use sx_assert instead of KASSERT(sx_xlocked())
It's redundant.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-27 17:26:53 +03:00
Christos Margiolis a3d65cde77 sound: Rename SD_F_EQ_ENABLED to SD_F_EQ
No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-24 16:54:41 +03:00
Christos Margiolis ede0236d3b sound: Retire unused SD_F_EQ_PC
This flag is neither set anywhere, nor is there a way to set it from
userland, so it is effectively useless, and currently the effect is that
EQ can only be enabled for primary playback channels.

Retire the flag and keep this behavior, and think later whether we want
to allow virtual channels to get their own EQ feeder as well.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-24 16:47:05 +03:00
Christos Margiolis f6b3bd1f33 sound tests: Remove trailing PROT_EXEC
Fixes:		730eaf4664 ("sound tests: Add PROT_EXEC rejection test")
Reported by:	Oliver Pinter <[email protected]>
Sponsored by:	The FreeBSD Foundation
MFC after:	6 days
2026-06-21 15:19:14 +03:00
Christos Margiolis 730eaf4664 sound tests: Add PROT_EXEC rejection test
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj, kib
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
2026-06-20 22:04:50 +03:00
Christos Margiolis 47efa81282 sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()
We drop the channel lock to execute cdev_pager_allocate(). By the time
we pick up the lock again, CHN_F_MMAP_INVALID might be set, so make sure
we fail and free the vm handle.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj, kib
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
2026-06-20 22:04:50 +03:00
Christos Margiolis 0c8147ae3b sound: Re-arrange a calculation in dsp_mmap_single()
This makes it easier to read. No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj, kib
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
2026-06-20 22:04:50 +03:00
Christos Margiolis bbb37ddf36 sound: Use and lock only the appropriate channel in dsp_mmap_single()
dsp_mmap_single() mmaps one of the channels associated with a
dsp_cdevpriv, based on the nprot argument. PROT_WRITE and
PROT_READ|PROT_WRITE select the output channel for mmaping, and
PROT_READ the input one. Instead of locking and modifying the flags of
all dsp_cdevpriv channels, do it only for the one we actually use.

While here, retire the now unused dsp_lock_chans() and
dsp_unlock_chans().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj, kib
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
2026-06-20 22:04:49 +03:00
Christos Margiolis f70a687bb0 sound: Retire SD_F_VPC and related settings
VPC is enabled by default, and the only way to turn it off is through a
loader hint. That being said, there is no benefit to turning it off in
the first place, because VPC provides more fine-grained volume control,
as well as access to the SNDCTL_DSP_[SET|GET][REC|PLAY]VOL ioctls and
dsp_ioctl_channel().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-20 20:32:21 +03:00
Christos Margiolis 7f2d790824 groups.7: Document audio group
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	emaste
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/35
2026-06-15 18:03:55 +03:00
Christos Margiolis a6aa95eba6 sound: Create all device nodes with GID_AUDIO
Commit 6024e3f99a ("Add audio group") introduced GID_AUDIO, initially
for virtual_oss(8) loopback devices. Now make all of them with
GID_AUDIO.

Relnotes:	yes
Sponsored by:	The FreeBSD Foundation
Reviewed by:	emaste
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/35
2026-06-15 18:03:48 +03:00
Christos Margiolis de2a136602 mixer(8): Retire deprecated control values
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-13 19:29:40 +03:00
Christos Margiolis 93a234a694 virtual_oss(8): Make sndstat FD global
There is no reason to have per-profile copies, plus this way we open
/dev/sndstat multiple times if more than 1 profile is created.

Also close the FD on exit to avoid leaking.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	jrm
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/41
2026-06-11 11:30:29 +02:00
Christos Margiolis 0bd5ef6b43 virtual_oss(8): Properly cleanup cuse(3)
virtual_oss(8) does not currently keep track of the cuse(3) it creates,
nor does it destroy any of them on exit, except for the control device.
This is harmless if virtual_oss(8) is killed after all audio streams
have been shut down, but if it's killed during I/O, the process hangs
and/or goes into uninterruptible sleep state.

To fix this, have pointers to all cuse(3) devices, and explicitly
destroy them on exit. Also make sure we don't leak memory in
dup_profile().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	jrm
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/41
2026-06-11 11:30:22 +02:00
Christos Margiolis 1bb8212df1 sound: Check for offset overflow in dsp_mmap_single()
Approved by:	so
Security:	FreeBSD-SA-26:27.sound
Security:	CVE-2026-45258
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
2026-06-09 19:13:21 +00:00
Christos Margiolis 439b219fed devd/snd.conf: Handle absent control device properly
If virtual_oss is not enabled when these rules run on startup, dmesg
will show the following messages:

Starting devd.
virtual_oss_cmd: Could not open control device: /dev/vdsp.ctl: No such file or directory
virtual_oss_cmd: Could not open control device: /dev/vdsp.ctl: No such file or directory

Reported by:	olce, Mark Millard <[email protected]>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-09 17:10:58 +02:00
Christos Margiolis 4f7092eeb2 virtual_oss_cmd(8): Improve error messages
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-06-02 15:00:45 +02:00
Christos Margiolis eb5aa5c337 bsdinstall: Add virtual_oss service option
Since virtual_oss is now part of base, there is no reason not to provide
an installer option to enable it, and make it more visible to new users,
who might also benefit from the devd rules in /etc/devd/snd.conf, which
use virtual_oss, as well as 8532b4a436 ("rc: virtual_oss: Create a
loopback device in the default configuration").

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	ivy
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/31
2026-06-02 14:05:05 +02:00
Christos Margiolis 453de99b38 virtual_oss(8): Fix buffer overflow in voss_compressor() call
This particular calls swaps the samples and maxchan arguments, which can
cause a buffer overflow in p_ch_chain if maxchan exceeds its bounds
(VMAX_CHAN).

Reported by:	Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	emaste
2026-05-28 16:46:01 +02:00
Christos Margiolis 9fb5642142 sound: Centralize and improve hot-swapping
Introduce pcm_hotswap(), which is responsible for sending devctl
SND/CONN notifications.

There are two user-visible improvements with this patch:

First, in pcm_unregister(), instead of just sending a SND/CONN/NODEV
notification when all devices have detached, we also switch to the new
default device if the previously default one has detached, but there are
more left.

Second, in pcm_register(), if the device happens to also be the new
default device, we hot-swap to it. Additionally, if hw.snd.default_auto
is set to 2, then we will essentially be hot-swapping to the newest
attached device.

The latter is especially useful for laptops like the Framework 16, which
comes with a built-in snd_hda(4) speaker-microphone-only device, and
headphones can work with the Framework Audio Expansion Card, which does
not extend the snd_hda(4) device, but is in fact a separate
snd_uaudio(4) device. To achieve automatic audio redirection between
headphones and speakers in this case, there has to be a way to switch
between different devices. The way the Audio Expansion Card works is by
having snd_uaudio(4) attach to it when the headphones are plugged, and
detach when unplugged, so this patch, along with hw.snd.default_auto=2,
can pick up those attach events and switch automatically. Combined with
the pcm_unregister() update, it becomes possible to switch back and
forth between headphones and speakers.

While here, be more robust and lock around snd_unit reads.

In collaboration with:	jrm
Sponsored by:		The FreeBSD Foundation
MFC after:		1 week
2026-05-28 16:08:20 +02:00
Christos Margiolis b2677d002e rc: virtual_oss: Handle absent pidfile properly
Instead of throwing errors from the programs that use it, print a
warning if the file does not exist.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	0mp, jrm
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/33
2026-05-28 16:06:06 +02:00
Christos Margiolis 803f686938 rc: virtual_oss: Wait for process to exit
Sometimes virtual_oss processes do not exit immediatelly. If we do not
wait for the processes to fully exit before returning from
virtual_oss_stop(), then the service restart operation might call
virtual_oss_start() too early and fail, because it will think the
service wasn't stopped and is still running.

Reported by:	jrm
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	0mp, jrm
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/33
2026-05-28 16:06:06 +02:00
Christos Margiolis a576e5140e rc: virtual_oss: Define some variables in rc.conf
They will now be part of /etc/defaults/rc.conf and be accessible by
sysrc(8).

Fixes:		70e27ecba5 ("virtual_oss: Introduce virtual_oss_default_control_device rc variable")
PR:		295560
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	0mp, jrm
Pull-Reqeust:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/33
2026-05-28 16:06:06 +02:00
Christos Margiolis fc9dc84823 snd_uaudio: Lock usbd_transfer_start() in uaudio_mixer_ctl_set()
This section would be previously locked by sound(4)'s mixer lock (see
e87654db5a ("snd_uaudio: Stop using mixer_get_lock()")), but
snd_uaudio(4) no longer uses it. This particular code path was missed
during testing, because my sound card does not reach it.

Fixes:		9a00e0b8ca ("snd_uaudio: Do not use snd_mixer->lock as mixer_lock")
Reported by:	netchild
Tested by:	netchild
Sponsored by:	The FreeBSD Foundation
MFC after:	6 days
2026-05-28 15:02:01 +02:00
Christos Margiolis 773bbfc573 sound: Update mixer.c LICENSE header
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis 64ebbb1d74 sound: Retire MIXER_SIZE and use correct size in DEFINE_CLASS
I am not sure why this hack was needed, but the size should be
sizeof(struct snd_mixer). Unfortunately, we have to expose snd_mixer,
but it should be better than relying on a hack.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis 5589a7499a sound: Retire snd_mixer->enuminfo
Instead of caching this when mix_setrecdevs() is called (which many
drivers never call), calculate it when we need it. After all, it is
quite rare that this structure is used by applications.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis 7485519d56 sound: Do not lock before destroying snd_mixer->lock
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis 6a3a42c57c sound: Retire unused mixer_get_lock()
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis 1e72608a3c sound: Remove all remaining uses of mixer_get_lock()
These functions are called from sound(4) through MIXER_SET() in
mixer_set(), but nothing mixer-related is used or needs to be locked in
these cases.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:12 +02:00
Christos Margiolis e87654db5a snd_uaudio: Stop using mixer_get_lock()
There is no reason to lock snd_mixer->lock here, since the only thing we
are doing with snd_mixer is to call mix_getdevinfo() and mix_get_dev(),
which are one-line getters, which are needed to eventually call
uaudio_get_child_index_by_dev().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis 9a00e0b8ca snd_uaudio: Do not use snd_mixer->lock as mixer_lock
In similar fashion to c234740c9d ("snd_uaudio: Do not use
pcm_channel->lock to protect uaudio_chan"), stop this layering
violation, and introduce a snd_uaudio(4)-internal mixer_lock.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis 22730c4b10 sound: Remove unused "from" mixer_ioctl_cmd() argument
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis 8e804f3dd6 sound: Retire unused hw.snd.vpc_mixer_bypass
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis f61e65e1b2 sound: Retire mixer_ioctl_channel()
This function never succeeds when it is not called from the same process
that has opened the file descriptor (e.g., mixer(8)). The reason is that
the CHN_FOREACH() loop tries to match the pid of each channel with the
pid of the process performing the ioctl, which will not be the same,
unless it's the same process that both opened the channel and performed
the ioctl.

In the case that the same process opens the channels and performs the
ioctl, however, we still do not need to worry, because mixer_ioctl_cmd()
essentially does the same thing anyway. Additionally, this scenario
should be quite rare, given that most applications do not open both
/dev/dsp* and /dev/mixer*, and in fact, it is actively encouraged by the
official OSSv4 specification not to do that.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis e8ea97602c sound: Retire M_MIXER
Even though harmless, it is not really useful, as there is essentially
only one allocation with M_MIXER.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/18
2026-05-27 17:32:11 +02:00
Christos Margiolis dfa52e8ed5 sound: Update feeder_eq.c LICENSE header
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 8b8dbc6bbe sndctl(8): Implement EQ controls
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 98a62ccab6 pcm.4: Document dev.pcm.%d.eq*
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 3a3cb16ad4 sound: Retire hint.pcm.%d.eq_preamp
It wasn't documented in the first place, but it is easier to just use
the sysctl.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 88bc1d7325 sound: Retire EQ states
The SD_F_EQ_ENABLED does the same thing, and is actually what we test
against in order to create the EQ feeder.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis f5d6e5cb5c sound: Retire FEEDEQ_DISABLE
We can do this more efficiently by just using the SD_F_EQ* flags. In
fact, the dev.pcm.%d.eq handler will (un)set SD_F_EQ_ENABLED and this is
what we actually test with when choosing to creating the EQ feeder or
not, so setting the state to FEEDEQ_DISABLE does not really an effect in
the first place.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 6f130b220d sound: Remove dead EQ FEEDEQ_DISABLE code
If EQ is disabled, we never reach those code paths in the first place.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis 54a03b44ae sound: Retire FEEDEQ_BYPASS
In effect, this is the same as the disable state. There is a comment
that says the bypass state skips EQ altogether, which is what the
disable should be. The disable state according to the comment disables
EQ but keeps the EQ preamp (dev.pcm.%d.eq_preamp), however after testing
it seems that the preamp does not really take effect, because with EQ
disabled, feeder_eq is non existent, so we never execute any EQ code in
the first place.

Make things simpler and clearer and have 2 states; enable and disable,
and do what they should do intuitively.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis a0011c74f8 sound: Expose EQ by default
The dev.pcm.%d.eq* sysctls and mixer "bass" and "treble" controls are
exposed only if hint.pcm.%d.eq is set. However, there is no good reason
why we shouldn't at least expose the controls, and let the user
enable/disable/bypass equalization through the sysctl.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/15
2026-05-27 17:27:11 +02:00
Christos Margiolis c6cefcbbbb snd_hda: Patch Dell WYSE 7040
https://forums.freebsd.org/threads/dell-wyse-7040-thin-client-intel-i5-6500te-built-in-sound-alc255-mini-how-to.102656/

Reported by:	razif (on the forum)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2026-05-26 12:32:56 +02:00
Christos Margiolis 3a3b054591 sound: Remove SV_ABI_LINUX ifdef
This ifdef does not do anything, SV_ABI_LINUX is a flag.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	ivy, brooks
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/37
2026-05-22 13:03:09 +02:00
Christos Margiolis 8532b4a436 rc: virtual_oss: Create a loopback device in the default configuration
The loopback device allows us to record desktop sound by reading from
it, or even use it as an input device, for example during a call.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	emaste
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/16
2026-05-21 19:37:34 +02:00
Christos Margiolis 5f904cb1b0 virtual_oss(8): Create loopback devices with GID_AUDIO
Make sure the user is part of the audio group to avoid unintended
snooping of loopback audio by unprivileged users.

While here, retire voss_dsp_perm, since we don't use the same value
everywhere now.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	emaste
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/26
2026-05-21 19:32:43 +02:00
Christos Margiolis 6024e3f99a Add audio group
To be initially used by virtual_oss(8) loopback devices.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	emaste
Pull-Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/26
2026-05-21 19:32:42 +02:00
Christos Margiolis 9354e204f5 sound: Force-disable hw.snd.compat_linux_mmap by default
Eventually this hack will be removed, so start by disabling it by
default.

Sponsored by:	The FreeBSD Foundation
MFC after:	12 months
Reviewed by:	emaste
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/29
2026-05-15 17:08:11 +02:00
Christos Margiolis b9c10eeb38 sound: Improve hw.snd.compat_linux_mmap
- Reject PROT_EXEC in all cases when Linux support is not compiled in.
- Define sysctl only when Linux support is compiled in.
- Document better.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	emaste
Pull Request:	https://ron-dev.freebsd.org/FreeBSD/src/pulls/29
2026-05-15 17:08:11 +02:00