History log of /freebsd-10.0-release/sys/dev/sound/pcm/sound.c
Revision Date Author Comments
(<<< Hide modified files)
(Show modified files >>>)
# 259065 07-Dec-2013 gjb

- Copy stable/10 (r259064) to releng/10.0 as part of the
10.0-RELEASE cycle.
- Update __FreeBSD_version [1]
- Set branch name to -RC1

[1] 10.0-CURRENT __FreeBSD_version value ended at '55', so
start releng/10.0 at '100' so the branch is started with
a value ending in zero.

Approved by: re (implicit)
Sponsored by: The FreeBSD Foundation

# 256281 10-Oct-2013 gjb

Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.

Approved by: re (implicit)
Sponsored by: The FreeBSD Foundation


# 243459 23-Nov-2012 mav

Remove "clone manager: " message from verbose dmesg. It is pointless to
print values that are statically hardcoded few lines above that.


# 231647 14-Feb-2012 mav

Do not handle MOD_SHUTDOWN equally to MOD_UNLOAD in sound kernel module.
MOD_SHUTDOWN is not an end of existence, and there is a life after it.
In particular, code previously called on MOD_SHUTDOWN grabbed lock and
deallocated unit numbering. That caused infinite wait loop if snd_uaudio
tried to destroy its PCM device after that point.

MFC after: 3 days


# 222826 07-Jun-2011 mav

Make automatic hw.snd.default_unit choice a bit more intelligent. Instead
of just setting it to the first registered device, reevaluate it for each
device registered, trying to choose best candidate, unless one was forced.
For now use such preference order: play&rec, play, rec.

As side effect, this should workaround the situation when HDMI audio output
of the video card, usually not connected to anything, becomes default, that
requires manual user intervention to make sound working. If at some point
this won't be enough, we can try to fetch some additional priority flags
from the device driver.


# 217323 12-Jan-2011 mdf

sysctl(9) cleanup checkpoint: amd64 GENERIC builds cleanly.

Commit the rest of the devices.


# 209193 15-Jun-2010 avg

sound/pcm: use non-const string as a value with SYSCTL_STRING

Although the sysctls are marked with CTLFLAG_RD and the values will stay
immutable, current sysctl implementation stores value pointer in
void* type, which means that const qualifier is discarded anyway
and some newer compilers complaint about that.
We can't use de-const trick in sysctl implementation, because in that
case we could miss an opposite situation where a const value is used
with CTLFLAG_RW sysctl.

Complaint from: gcc 4.4, clang
MFC after: 2 weeks


# 193640 07-Jun-2009 ariff

Sound Mega-commit. Expect further cleanup until code freeze.

For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .

Summary of changes includes:

1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.

Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.

Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).

Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.

2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.

Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.

Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/

3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.

4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.

5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.

6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.

Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO

Manual page updates are on the way.

Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.


# 192920 27-May-2009 joel

Slightly adjust copyright text.

Approved by: luigi


# 187030 10-Jan-2009 mav

Import some new constants and structures fields from OSSv4.
Implement some OSSv4 ioctls to make ossinfo tool work and print
something reasonable.


# 186875 07-Jan-2009 mav

Add some new oss_sysinfo structure fields from OSSv4.


# 170893 17-Jun-2007 ariff

Spelling nit due to my lamenglishness.

Noticed by: brueffer


# 170885 17-Jun-2007 ariff

Add sysctl/tunable "hw.snd.default_auto", which is useful (especially
for non-root users) to automatically assign default unit to a newly
attach device like USB audio.


# 170884 17-Jun-2007 ariff

Reassign default unit to a valid unit, be it during attach or detach.
If nothing is available, set to something that is purely ridiculous
so the next valid attach will notice it.

Tested by: chibis


# 170815 16-Jun-2007 ariff

Last (again ?!?) major commit for RELENG_7, featuring total Giant
eradication in/from userland path, countless locking fixes, etc.

- General sleep call through msleep(9) has been converted to condvar(9)
with better consistencies.
- Heavily guard every possible "slow path" entries (open(), close(),
few ioctl()s, sysctls), but once it entering "fast path" (io, interrupt
started), they are free to fly on their own.
- Rearrange locking sequences, resulting better concurrency and
serialization. Large part doesn't even need locking at all, and will be
removed in future. Less clutter, except in few places due to lock
ordering.
- Anonymous mixer object creation/deletion to simplify mixer handling
beyond typical mixer ioctls.
Submitted by: chibis (with modifications)
- Add few mix_[get|set|..] functions to avoid calling mixer_ioctl()
directly using cryptic arguments.
- Locking fixes to avoid possible deadlock with (still under Giant) USB.
- Better simplex/duplex device handling.
- Recover mmap() functionality for recording, which has been lost
since 2.2.x - 3.x (the introduction of newpcm). Full-duplex mmap still
doesn't work (due to VM/page design), but people still can mmap
both by opening each direction separately. mmaped playback is guarantee
to work either way.
- New sysctl: "hw.snd.compat_linux_mmap" to allow PROT_EXEC page
mapping, due to recent changes in linux compatibility layer which
require it. All linux applications that using sound + mmap() (mostly games)
require this to be enabled. Disabled by default.
- Other goodies.. too many, that will increase releng7 shareholder value
and make users of releng6 (and below) cry ;)

* This commit should be atomic. If anything goes wrong (not counting problem
originated from elsewhere), I will not hesitate to revert everything back
within 12 hours. This substantial changes itself not a rocket science
and the process has begun for almost 2 years, and lots of incremental
changes are already in place during that period of time.
* Some issues does occur in snd_emu10kx (note the 'x') due to various
internal locking issues and it is currently being worked on by chibis.

Tested by: chibis (Yuriy Tsibizov), joel, Alexandre Vieira,
many innocent souls...


# 170289 04-Jun-2007 dwmalone

Despite several examples in the kernel, the third argument of
sysctl_handle_int is not sizeof the int type you want to export.
The type must always be an int or an unsigned int.

Remove the instances where a sizeof(variable) is passed to stop
people accidently cut and pasting these examples.

In a few places this was sysctl_handle_int was being used on 64 bit
types, which would truncate the value to be exported. In these
cases use sysctl_handle_quad to export them and change the format
to Q so that sysctl(1) can still print them.


# 170235 03-Jun-2007 ariff

Insert NULL pointer checking around devclass_get_maxunit(pcm_devclass, ..) .
Things can get ugly without it due to uninitialized class. RELENG_6 need
a simmilar, but different treatment as well.

err.. perhaps we should teach devclass_get_maxunit() to return -1 ?

MFC after: 1 day


# 170161 31-May-2007 ariff

Last major commit and updates for RELENG_7:

- Rework the entire pcm_channel structure:
* Remove rarely used link placeholder, instead, make each pcm_channel
as head/link of each own/each other. Unlock - Lock sequence due to
sleep malloc has been reduced.
* Implement "busy" queue which will contain list of busy/active
channels. This greatly reduce locking contention for example while
servicing interrupt for hardware with many channels or when virtual
channels reach its 256 peak channels.

- So I heard you like v chan ... O RLY?
Welcome to Virtual **Record** Channels (vrec, rec vchans, vchans for
recording, Rec-Chan, you decide), the ultimate solutions for your
nagging O_RDWR full-duplex wannabe (note: flash plugins) monopolizing
single record channel causing EBUSY. Vrec works exactly like Vchans
(or, should I rename it to "Vplay" :) , except that it operates on the
opposite direction (recording). Up to 256 vrecs (like vchans) are
possible.

Notes:
* Relocate dev.pcm.%d.{vchans,vchanformat,vchanrate} to each of its
respective node/direction:
dev.pcm.%d.play.* for "play" (cdev = dsp%d.vp%d)
dev.pcm.%d.rec.* for "record" (cdev = dsp%d.vr%d)
* Don't expect that it will magically give you ability to split
"recording source" (eg: 1 channel for cdrom, 1 channel for mic,
etc). Just admit that you only have a *single* recording source /
channel. Please bug your hardware vendor instead :)

- Bump maxautovchans from 4 to 16. For a full-fledged multimedia
desktop/workstation with too many soundservers installed (esound,
artsd, jackd, pulse/polypaudio, ding-dong pling plong mudkip fuh fuh,
etc), 4 seems inadequate. There will be no memory penalty here, since
virtual channels are allocate only by demand.

- Nuke/Rework the entire statically created cdev entries. Everything is
clonable through snd own clone manager which designed to withstand many
kind of abusive devfs droids such as:
* while : ; do /bin/test -e /dev/dsp ; done
* jot 16777216 0 | while read x ; do ls /dev/dsp0.$x ; done
* hundreds (could be thousands) concurrent threads/process opening
"/dev/dsp" (previously, this might result EBUSY even with just
3 contesting threads/procs).
o Reusable clone objects (instead of creating new one like there's no
tomorrow) after certain expiration deadline. The clone allocator will
decide whether to reuse, share, or creating new clone.
o Automatic garbage collector.

- Dynamic unit magic allocator. Maximum attached soundcards can be tuned
using tunable "hw.snd.maxunit" (Default to 512). Minimum is 16, and
maximum is 2048.

- ..other fixes, mostly related to concurrency issues.

joel@ will do the manpage updates on sound(4).

Have fun.


# 167611 15-Mar-2007 ariff

Spring cleanup on irrelevant NULL checking over M_WAITOK allocations.


# 167605 15-Mar-2007 ariff

Remove NULL allocation checking since malloc() is allow to wait.
(I'll fix other places later..)


# 166918 23-Feb-2007 ariff

- Compile time compatibility for pre/post newbus API (intr filter)
changes. This should ease the job of maintaining codebase since much
of the regression tests are done across os versions.
- bus_setup_intr() -> snd_setup_intr().


# 166901 23-Feb-2007 piso

o break newbus api: add a new argument of type driver_filter_t to
bus_setup_intr()

o add an int return code to all fast handlers

o retire INTR_FAST/IH_FAST

For more info: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=465712+0+current/freebsd-current

Reviewed by: many
Approved by: re@


# 166427 02-Feb-2007 joel

Remove dead email address.

Requested by: luigi


# 164614 26-Nov-2006 ariff

Welcome to Once-a-year Sound Mega-Commit. Enjoy numerous updates and fixes
in every sense.

General
-------

- Multichannel safe, endian safe, format safe
* Large part of critical pcm filters such as vchan.c, feeder_rate.c,
feeder_volume.c, feeder_fmt.c and feeder.c has been rewritten so that
using them does not cause the pcm data to be converted to 16bit little
endian.
* Macrosses for accessing pcm data safely are defined within sound.h in
the form of PCM_READ_* / PCM_WRITE_*
* Currently, most of them are probably limited for mono/stereo handling,
but the future addition of true multichannel will be much easier.

- Low latency operation
* Well, this require lot more works to do not just within sound driver,
but we're heading towards right direction. Buffer/block sizing within
channel.c is rewritten to calculate precise allocation for various
combination of sample/data/rate size. As a result, applying correct
SNDCTL_DSP_POLICY value will achive expected latency behaviour simmilar
to what commercial 4front driver do.
* Signal handling fix. ctrl+c of "cat /dev/zero > /dev/dsp" does not
result long delay.
* Eliminate sound truncation if the sound data is too small.
DIY:
1) Download / extract
http://people.freebsd.org/~ariff/lowlatency/shortfiles.tar.gz
2) Do a comparison between "cat state*.au > /dev/dsp" and
"for x in state*.au ; do cat $x > /dev/dsp ; done"
- there should be no "perceivable" differences.
Double close for PR kern/31445.

CAVEAT: Low latency come with (unbearable) price especially for poorly
written applications. Applications that trying to act smarter
by requesting (wrong) blocksize/blockcount will suffer the most.
Fixup samples/patches can be found at:
http://people.freebsd.org/~ariff/ports/

- Switch minimum/maximum sampling rate limit to "1" and "2016000" (48k * 42)
due to closer compatibility with 4front driver.
Discussed with: marcus@ (long time ago?)

- All driver specific sysctls in the form of "hw.snd.pcm%d.*" have been
moved to their own dev sysctl nodes, notably:
hw.snd.pcm%d.vchans -> dev.pcm.%d.vchans
Bump __FreeBSD_version.

Driver specific
---------------

- Ditto for sysctls.

- snd_atiixp, snd_es137x, snd_via8233, snd_hda
* Numerous cleanups and fixes.
* _EXPERIMENTAL_ polling mode support using simple callout_* mechanisme.
This was intended for pure debugging and latency measurement, but proven
good enough in few unexpected and rare cases (such as problematic shared
IRQ with GIANT devices - USB). Polling can be enabled/disabled through
dev.pcm.0.polling. Disabled by default.

- snd_ich
* Fix possible overflow during speed calibration. Delay final
initialization (pcm_setstatus) after calibration finished.
PR: kern/100169
Tested by: Kevin Overman <oberman@es.net>
* Inverted EAPD for few Nec VersaPro.
PR: kern/104715
Submitted by: KAWATA Masahiko <kawata@mta.biglobe.ne.jp>

Thanks to various people, notably Joel Dahl, Yuriy Tsibizov, Kevin Oberman,
those at #freebsd-azalia @ freenode and others for testing.

Joel Dahl will do the manpage update.


# 162588 23-Sep-2006 netchild

MFp4 the sound Google Summer of Code project:

The goal was to sync with the OSSv4 API 4Front Technologies uses in their
proprietary OSS driver. This was successful as far as possible. The part
of the API which is stable is implemented, for the rest there are some
stubs already.

New system ioctls:
- SNDCTL_SYSINFO - obtain audio system info (version, # of audio/midi/
mixer devices, etc.)
- SNDCTL_AUDIOINFO - fetch details about a specific audio device
- SNDCTL_MIXERINFO - fetch details about a specific mixer device

New audio ioctls:
- Sync groups (SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART) which allow
triggered playback/recording on multiple devices (even across processes
simultaneously).
- Peak meters (SNDCTL_DSP_GETIPEAKS/SNDCTL_DSP_GETOPEAKS) - can query
audio drivers for peak levels (needs driver support, disabled for now).
- Per channel playback/recording levels -
SNDCTL_DSP_{GET,SET}{PLAY,REC}VOL. Note that these are still in name
only, just wrapping around the AC97-style mixer at the moment. The next
step is to push them down to the drivers.

Audio ioctls still under development by 4Front (for which stubs may exist
in this commit):
- SNDCTL_GETNAME, SNDCTL_{GET,SET}{SONG,LABEL}
- SNDCTL_DSP_{GET,SET}_CHNORDER
- SNDCTL_MIX_ENUMINFO, SNDCTL_MIX_EXTINFO - (might be documented enough in
the OSS releases to work on this. These ioctls cover the cool "twiddle
any knob on your card" features.)

Missing:
- SNDCTL_DSP_COOKEDMODE -- this ioctl is used to give applications direct
access to a card's buffers, bypassing the feeder architecture. It's
a toughy -- "someone" needs to decide :
(a) if this is desireable, and (b) if it's reasonably feasible.

Updates for driver writers:
So far, only two routines to the channel class (in channel_if.m) are added.
One is for fetching a list of discrete supported playback/recording rates
of a channel, and the other is for fetching peak level info (useful for
drawing peak meters). Interested parties may want to help pushing down
SNDCTL_DSP_{GET,SET}{PLAY,REC}VOL into the drivers.

To use the new stuff you need to rebuild the sound drivers or your kernel
(depending on if you use modules or not) and to install soundcard.h (a
buildworld/installworld handles this).

Sponsored by: Google SoC 2006
Submitted by: ryanb
Many thanks to: 4Front Technologies for their cooperation, explanations
and the nice license of their soundcard.h.


# 160439 17-Jul-2006 netchild

Rename some variables. This fixes some (but not all) problems on the way
for WARNS > 2 cleanlyness.

Submitted by: Yuriy Tsibizov <Yuriy.Tsibizov@gfk.ru>


# 159732 18-Jun-2006 netchild

- Rename hw.snd.unit to hw.snd.default_unit to make the purpose more obvious.
- Enable 4 automatic vchan's by default.
- Add some comments which provide ides/questions for improvement.
- Prefix some temporary sysctl's with an underscore to denote that it is not
an official API but a workaround until the real solution is implemented.


# 157331 31-Mar-2006 ariff

MEGA Fixes / Cleanup
--------------------

- Seal the fate of long standing memory leak (4 years, 7 months) during
pcm_unregister(). While destroying cdevs, scan / detect possible
children and free its SLIST placeholder properly.
- Optimize channel allocation / numbering even further. Do brute cyclic
checking only if the channel numbering screwed.
- Mega vchan create/destroy cleanup:
o Implement pcm_setvchans() so everybody can use it freely instead
of implementing their own, be it through sysctl or channel auto
allocation.
o Increase vchan creation/destruction resiliency:
+ it's possible to increase/decrease total vchans even during
busy playback/recording. Busy channel will be left alone, untouched.
Abusive test sample:
# play whatever...
#
while : ; do
sysctl hw.snd.pcm0.vchans=1
sysctl hw.snd.pcm0.vchans=10
sysctl hw.snd.pcm0.vchans=100
sysctl hw.snd.pcm0.vchans=200
done
# Play something else, leave above loop running frantically.
+ Seal another 4 years old bug where it is possible to destroy (virtual)
channel even when its cdevs being referenced by other process.
The "First Come First Served" nature of dsp_clone() is the main
culprit of this issue, and usually manifest itself as dangling
channel <-> process association. Ensure that all of its cdevs
are free from being referenced before destroying it (through
ORPHAN_CDEVT() macross).

All these fixes (including previous fixes) will be MFCed, later.


# 157022 22-Mar-2006 ariff

We shouldn't really care about the return value of mixer_uninit(),
except EBUSY.


# 156929 21-Mar-2006 ariff

Apply more thorough fixes while dealing with device opening and closing:

- Determine open direction using 'flags', not 'mode'. This bug exist since
past 4 years.
- Don't allow opening the same device twice, be it in a same or different
direction.
- O_RDWR is allowed, provided that it is done by a single open (for example
by mixer(8)) and the underlying hardware support true full-duplex operation.
- Do various paranoid checking in case other process/thread trying to hijack
the same device twice (or more).

MFC after: 5 days


# 156765 16-Mar-2006 ariff

Restore CHN_F_BUSY flag which was removed accidentally in previous commit.


# 156762 16-Mar-2006 ariff

Fix severe 8bit integer overflow during channel creation and destruction,
especially for vchans. It turns out that channel numbering always depend
on d->devcount counter (which keep increasing), while PCMMKMINOR() truncate
everything to 8bit length. At some point the truncation cause the newly
created character device overlapped with the existence one, causing erratic
overall system behaviour and panic. Easily reproduce with something like:

(Luckily, only root can reproduce this)

while : ; do
sysctl hw.snd.pcm0.vchans=200
sysctl hw.snd.pcm0.vchans=100
done

- Enforce channel/chardev numbering within 8bit boundary. Return E2BIG
if necessary.
- Traverse d->channels SLIST and try to reclaim "free" counter during channel
creation. Don't rely on d->devcount at all.
- Destroy vchans in reverse order.

Anyway, this is not the fault of vchans. It is just that vchans are so cute
and begging to be abused ;) . Don't blame her.

Old, hidden bugs.. sigh..

MFC after: 3 days


# 155342 05-Feb-2006 netchild

Convert NULL checks into KASSERT (and move them before the first
dereferencing) since a NULL value would be a bug here.

Note: Both affected functions look very similar. A refactoring may
be beneficial.

CID: 483, 485
Found with: Coverity Prevent(tm)
Discussed with: ariff
MFC after: 5 days


# 150827 02-Oct-2005 netchild

sys/dev/sound/pcm/sndstat.c:
* General spl* cleanup. It doesn't serve any purpose anymore.
* Nuke sndstat_busy(). Addition of sndstat_acquire() /
sndstat_release() for sndstat exclusive access. [1]

sys/dev/sound/pcm/sound.c:
* Remove duplicate SLIST_INIT()
* Use sndstat_acquire() / release() to lock / release the entire
sndstat during pcm_unregister(). This should fix LOR #159 [1]

sys/dev/sound/pcm/sound.h:
* Definition of SD_F_SOFTVOL (part of feeder volume)
* Nuke sndstat_busy(). Addition of sndstat_acquire() /
sndstat_release() for exclusive sndstat access. [1]

Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
LOR: 159 [1]
Discussed with: yongari [1]


# 150061 12-Sep-2005 netchild

- Fix the locking in dsp.c to prevent a LOR (AFAIK not on the LOR page).

- Remove an assertion in sound.c, it's not needed (and causes a panic now).
From the conversation via mail between glebius and Ariff:
---snip---
> Well, but which mutex protects now? Do we own anything else
> in pcm_chnalloc()? I see some queue(4) macros in pcm_chnalloc(),
> they should be protected, shouldn't they?
Queue insertion/removal occur during
1) driver loading (which is pretty much single thread /
sequential) or unloading (mutex protected, bail out if there is
any channel with refcount > 0 or busy).
2) vchan_create()/destroy(), (which is *sigh* quite complicated), but
somehow protected by 'master'/parent channel mutex. Other
thread cannot add/remove vchan (or even continue traversing
that queue) unless it can acquire parent channel mutex.
---snip---

Fix the locking in dsp.c to prevent a LOR (AFAIK not on the LOR page).

Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested with: INVARIANTS[1] and DIAGNOSTICS[2]
Tested by: netchild [1,2], David Reid <david@jetnet.co.uk> [1]


# 149953 10-Sep-2005 netchild

- channel.h
* New definition CHN_F_HAS_VCHAN.
- channel.c
* Use CHN_F_HAS_VCHAN to mark channel with vchan capability instead
of relying on SLIST_EMPTY(&channel->children) == true for better
clarification and future possible usages of children (like
'slave' channel).
* Various fixes, including blocksize / format bps allignment,
better 24bit seeking (mplayer, others).
* Improve format chain building, it's now possible to record something
to a format non-native to the soundcard through various feeder format
converters or to higher sampling rate. This also gains another feature,
like doing vchan mixing on non s16le soundcard such as sb8.
- sound.c
* Increase robustness within various function that handle vchan
creation / termination (these function need a total rewrite, but
that would cause other major rewrite within various places too!).
As far as its robustness can be guaranteed, leave it as is.
* Optimize channel ordering, prefer *real* hardware playback
channels over virtual channels. cat /dev/sndstat should look
better.
* Increase sndstat verbosity to include bufsoft/bufhard allocation.
- vchan.c
* Fix LOR 119.
- http://sources.zabbadoz.net/freebsd/lor.html#119
* Reorder / increase robustness of vchan_create() / destroy().
Enforce destroy_dev() during destroy operation, fix possible
panic / dangling character device.
- http://lists.freebsd.org/pipermail/freebsd-current/2005-May/050308.html
* Tolerate a little bit more during mixing process, this should help
non s16le soundcards.

Note: Recoring in a non-native rate/format may result in overruns. A friendly
application is wavrec from audio/wavplay. The problem is under
investigation.

Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>


# 148587 31-Jul-2005 netchild

* Fix panic during driver unload on second attempt after failure on
first (device busy).
* Fix module unloading for sound.ko itself.

Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested by: multimedia@


# 139749 05-Jan-2005 imp

Start each of the license/copyright comments with /*-, minor shuffle of lines


# 132236 16-Jul-2004 tanimura

Rename the sound device drivers:

- `sound'
The generic sound driver, always required.

- `snd_*'
Device-dependent drivers, named after the sound module names.
Configure accordingly to your hardware.

In addition, rename the `snd_pcm' module to `sound' in order to sync
with the driver names.

Suggested by: cg


# 130188 07-Jun-2004 truckman

Nuke a cryptic and useless diagnostic printf().


# 126367 28-Feb-2004 truckman

Create a new mutex type for virtual channels. This allows us to get
rid of the MTX_DUPOK flag on channel mutexes, which allows witness to
do a better job of lock order checking. Nuke snd_chnmtxcreate() since
it is no longer needed.

Tested by: matk


# 125136 28-Jan-2004 truckman

Change KASSERT() in feed_vchan16() into an explicit test and call to
panic() so that the buffer overflow just beyond this point is always
caught, even when the code is not compiled with INVARIANTS.

Change chn_setblocksize() buffer reallocation code to attempt to avoid
the feed_vchan16() buffer overflow by attempting to always keep the
bufsoft buffer at least as large as the bufhard buffer.

Print a diagnositic message
Danger! %s bufsoft size increasing from %d to %d after CHANNEL_SETBLOCKSIZE()
if our best attempts fail. If feed_vchan16() were to be called by
the interrupt handler while locks are dropped in chn_setblocksize()
to increase the size bufsoft to match the size of bufhard, the panic()
code in feed_vchan16() will be triggered. If the diagnostic message
is printed, it is a warning that a panic is possible if the system
were to see events in an "unlucky" order.

Change the locking code to avoid the need for MTX_RECURSIVE mutexes.

Add the MTX_DUPOK option to the channel mutexes and change the locking
sequence to always lock the parent channel before its children to avoid
the possibility of deadlock.

Actually implement locking assertions for the channel mutexes and fix
the problems found by the resulting assertion violations.

Clean up the locking code in dsp_ioctl().

Allocate the channel buffers using the malloc() M_WAITOK option instead
of M_NOWAIT so that buffer allocation won't fail. Drop locks across
the malloc() calls.

Add/modify KASSERTS() in attempt to detect problems early.

Abuse layering by adding a pointer to the snd_dbuf structure that points
back to the pcm_channel that owns it. This allows sndbuf_resize() to do
proper locking without having to change the its API, which is used by
the hardware drivers.

Don't dereference a NULL pointer when setting hw.snd.maxautovchans
if a hardware driver is not loaded. Noticed by Ryan Sommers
<ryans at gamersimpact.com>.

Tested by: Stefan Ehmann <shoesoft AT gmx.net>
Tested by: matk (Mathew Kanner)
Tested by: Gordon Bergling <gbergling AT 0xfce3.net>


# 124740 20-Jan-2004 matk

Fix a panic when kldloading a sound driver. Do this by replacing the
link-list of dev_t's with named variables. Remove used code.

Approved by: tanimura (mentor)


# 124617 17-Jan-2004 phk

As previously announced: discontinue use of makedev() call in soundcode.

This takes us a lot closer to refcounting dev_t.

This patch originally by cg@ with a few minor changes by me.

It is largely untested, but has been HEADSUP'ed twice, so presumably
people have not found any issues with it.

Submitted by: cg@


# 123277 07-Dec-2003 truckman

The last argument to mtx_init() should be MTX_DEF, not 0. This is not a
functional change since MTX_DEF happens to be defined as 0.


# 119853 07-Sep-2003 cg

update my email address.


# 119096 18-Aug-2003 cg

handle locking when creating or destroying vchans better


# 111119 19-Feb-2003 imp

Back out M_* changes, per decision of the TRB.

Approved by: trb


# 109623 21-Jan-2003 alfred

Remove M_TRYWAIT/M_WAITOK/M_WAIT. Callers should use 0.
Merge M_NOWAIT/M_DONTWAIT into a single flag M_NOWAIT.


# 109236 14-Jan-2003 cognet

Don't call destroy_dev it a channel has children.
vchan creation doesn't lead to /dev entry creation if the new vchan is the
first child of a channel,
This fix a panic that happens when loading a sound driver module, creating
vchans and unloading the driver.

Approved by: cg
MFC after: 3 days


# 107285 26-Nov-2002 cg

(hopefully) fix build breakage some people are seeing

Approved by: re


# 107237 25-Nov-2002 cg

various fixes to eliminate locking warnings

Approved by: re
Reviewed by: orion


# 106420 04-Nov-2002 cognet

Call pcm_chn_destroy() in pcm_killchan() so that channel mutexes are destroyed and struct pcm_channel freed.

Reviewed by: cg
MFC after: 3 days


# 102374 24-Aug-2002 nsayer

Be sure to unregister from sndstat on unregister. Gets rid of phantom
sndstat output after removing uaudio.


# 100654 25-Jul-2002 green

Fix some of the places where sound(4) can sleep with a lock held. (Help
courtesy of fenner).


# 100576 23-Jul-2002 kan

Fix the sound driver vchan support to work when hw.snd.maxautovchans
has been specified through /boot/loader.conf as opposed to setting it
in /etc/sysctl.conf. Only PCMDIR_PLAY channel can be used as a parent
of virtual channel. Do not initialize a new vchan for a given physical
channel if other physical channel already has one created.

PR: 31597
Approved by: obrien (mentor)


# 100478 22-Jul-2002 orion

Move lock in pcm_chn_add() to after malloc.

PR: kern/40157
Submitted by: Dan Lukes <dan@obluda.cz>


# 96928 19-May-2002 peter

Try and solve some cases of labels at end of compound statements that gcc
now objects to (as it should, it is not legal C).


# 95684 28-Apr-2002 cg

add a missing \n to an unregister failure message


# 93814 04-Apr-2002 jhb

Change snd_mtxcreate() to accept a lock type as an extra argument that is
passed to mtx_init().


# 89834 26-Jan-2002 cg

* improve error handling
* be more specific in verbose boot messages
* allow the feeder subsystem to veto pcm* attaching if there is an error
initialising the root feeder
* don't free/malloc a new tmpbuf when resizing a snd_dbuf to the same size as
it currently is
* store the feeder description in the feeder structure instead of mallocing
space for it


# 89774 25-Jan-2002 scottl

Fix code that had rotted behind debugging macros.

Approved by: cg (in principle)
MFC after: 2 weeks


# 89691 23-Jan-2002 cg

improve sndstat output of feederchains so it can be understood without
reading the feeder sourcecode


# 89690 23-Jan-2002 cg

print warnings if a pcm*.buffersize hint is out of range or a non-power-of-2


# 83614 18-Sep-2001 cg

change tracking of channel counts.

add method for retrieving "buffersize" hints for pcm devices, adjusted for
specified minimum, maximum and default values.


# 83476 14-Sep-2001 greid

- Correctly increment the channel refcount in dsp_open() such that it is
no longer possible to unload the driver module while sound is playing
(which resulted in a panic).
- Fix a similar problem with the sndstat device that I found while looking
at the above.
- Append a newline character to error messages in pcm_unregister()

Reviewed by: cg
MFC after: 10 days


# 83089 05-Sep-2001 cg

add a method for recording of specific channels for devices with more than
one hardware record channel. new devices, /dev/dsprX.Y where X is unit
number and Y is channel index.


# 82492 29-Aug-2001 cg

tweaks to reduce latency/pauses in output


# 82479 29-Aug-2001 cg

add some extra diagnostic info to sndstat output.


# 82180 23-Aug-2001 cg

many changes:

* add new channels to the end of the list so channels used in order of
addition

* de-globalise definition of struct snddev_info and provide accessor
functions where necessary.

* move the $FreeBSD$ tag in each .c file into a macro and allow the
/dev/sndstat handler to display these when set to maximum verbosity to aid
debugging.

* allow each device to register its own sndstat handler to reduce the amount
of groping sndstat must do in foreign structs.


# 79141 03-Jul-2001 cg

remove obsolete typedefs.

only define INTR_TYPE_AV if it is not already defined.


# 79116 02-Jul-2001 green

Correct obviously wrong mistakes.


# 79099 02-Jul-2001 mjacob

make it compile again in -current


# 79090 02-Jul-2001 green

Make all this compile on 4.3, modulus sbuf.


# 78895 27-Jun-2001 cg

don't flag the playback hardchan as busy on devices with only one of them.

if a device has vchans already but they are all busy, allocate another one
at open() time, up to a maximum of hw.snd.maxvchans.

when creating/destroying vchans, don't make/remove a devnode for the
first/last one as it replaces a hardchan.


# 78853 26-Jun-2001 cg

add a tunable/sysctl, hw.snd.autovchans. if this is set to a value n where
n > 0, n vchans will be assigned to any devices that subsequently register
with a single playback channel.


# 78670 23-Jun-2001 cg

add defines and ifdefs so this code will compile on 4.x

add spls so this code will work on 4.x


# 78396 17-Jun-2001 cg

use devclass_get_maxunit() correctly


# 78395 17-Jun-2001 cg

revise dsp_clone() to return the first nonbusy channel instead of simply
cycling channel numbers.

remove unused fields from struct snddev_info.


# 78366 16-Jun-2001 peter

Use INTR_TYPE_AV for the interrupt handlers because:
1: most drivers are sensitive to timing, and
2: the handlers are MPSAFE and need a chance to get into the kernel
before some other non-mpsafe handler blocks the ithread on Giant in
shared irq cases.

Reviewed by: cg (in principle)


# 78362 16-Jun-2001 cg

use a global devclass for all drivers - i'm not entirely sure why this
worked before.

mixer, dsp and sndstat are seperate devices - give them their own cdevsws
instead of demuxing requests sent to a single cdevsw.

use the si_drv1/si_drv2 fields in dev_t structures for holding information
specific to an open instance of mixer/dsp.

nuke /dev/{dsp,dspW,audio}[0-9]* links - this functionality is now provided
using cloning.

various locking fixes.


# 78214 14-Jun-2001 cg

various locking fixes, rework open logic and channel registration

PR: kern/28084


# 77989 10-Jun-2001 des

sbuf_new(9) now returns a struct sbuf * instead of an int. If the caller
does not provide a struct sbuf, sbuf_new(9) will allocate one and return
a pointer to it.


# 77900 08-Jun-2001 peter

"Fix" the previous initial attempt at fixing TUNABLE_INT(). This time
around, use a common function for looking up and extracting the tunables
from the kernel environment. This saves duplicating the same function
over and over again. This way typically has an overhead of 8 bytes + the
path string, versus about 26 bytes + the path string.


# 77882 07-Jun-2001 cg

lock sound device when adding/removing channels
implement setblocksize for vchans
don't panic when doing certain ioctls or aborting on a vchan
xmms now works with vchans


# 77853 07-Jun-2001 peter

Back out part of my previous commit. This was a last minute change
and I botched testing. This is a perfect example of how NOT to do
this sort of thing. :-(


# 77843 06-Jun-2001 peter

Make the TUNABLE_*() macros look and behave more consistantly like the
SYSCTL_*() macros. TUNABLE_INT_DECL() was an odd name because it didn't
actually declare the int, which is what the name suggests it would do.


# 77269 27-May-2001 cg

beginnings of virtual playback channel support

instead of using two malloced arrays for storing channel lists, use an
slist. convert the sndstat device to use sbufs and optionally provide more
detail about channel state.

vchans are software mixed playback channels. they are not enabled by this
commit. they use the feeder infrastructure to emulate normal playback
channels in a manner transparent to applications, whilst providing as many
channels are desired, especially suitable for devices with only one hardware
playback channel. in the future they will provide additional features.

those wishing to test this functionality will need to add vchan.c to
sys/conf/files and use 'sysctl -w hw.snd.pcm0.vchans' to enable it.

blocksize and auto-rate selection are not yet supported.


# 74810 26-Mar-2001 phk

Send the remains (such as I have located) of "block major numbers" to
the bit-bucket.


# 74763 24-Mar-2001 cg

mega-commit.

this introduces a new buffering mechanism which results in dramatic
simplification of the channel manager.

as several structures have changed, we take the opportunity to move their
definitions into the source files where they are used, make them private and
de-typedef them.

the sound drivers are updated to use snd_setup_intr instead of
bus_setup_intr, and to comply with the de-typedefed structures.

the ac97, mixer and channel layers have been updated with finegrained
locking, as have some drivers- not all though. the rest will follow soon.


# 74363 16-Mar-2001 cg

don't leak memory allocated for feeders at module unload
kill the fake channel when unregistering


# 74216 13-Mar-2001 cg

fix a panic triggerable by anyone with read/write access to the audio
devices. opening /dev/{dsp,dspW,audio}0 and then opening a different device
from that list and closing it resulted in a panic when any operation is
performed on the first fd.

we prevent this happening by denying the second open unless it uses the same
minor device as the first.

PR: kern/25519


# 73757 05-Mar-2001 cg

nuke the splstack stuff, snd_mtx* will now be no-ops on 4.x


# 73131 27-Feb-2001 cg

add functions for sound drivers to use for locking and setting up interrupt
handlers. these are not yet used, but will allow compatibility for driver
modules from 5.x to 4.x.


# 73127 27-Feb-2001 cg

MFS: 4.x/5.x compatibility #ifdefs


# 70943 11-Jan-2001 jhb

Woops, use the SYSCTL_STATIC_CHILDREN() macro instead of manually
expanding it for _hw_snd.


# 70680 05-Jan-2001 jhb

- Make the 'hwvol_mixer' and 'hwvol_step' variables be specific to a
specific snd_mixer device rather than global across all mixers.
- Add per-mixer mute status and saved mute_level so that the mixer_hwmute()
function can now toggle the mute state when the mute button is pressed.
- Create a dynamic sysctl tree hw.snd.pcmX when a pcm device is registered.
- Move the hw.snd.hwvol_* sysctl's to hw.snd.pcmX.hwvol_* so that they
are now properly device-specific. Eventually when the mixers become
their own devices these sysctl's will move to live under a mixerX tree.
- Change the interface of the hwvol_mixer sysctl so that it reports the
name of the current mixer device instead of the number and is settable
with the name instead of the number.
- Add a new function mixer_hwinit() used to setup the dynamic sysctl's
needed for the hwvol support that can be called by drivers that support
hwvol.

Reviewed by: cg


# 70675 04-Jan-2001 jhb

The 'maxchans' count is one more than the number of channels, so
'chancount' never got up to equaling 'maxchans'. As a result,
pcm_makelinks() was never called, and one always had to set the sysctl to
get the /dev/mixer and other symlinks generated in the DEVFS case. Instead,
change the test in pcm_addchan() to call pcm_makelinks() after the first
channel is initialized, since the aliases are linked to channel 0.

Reviewed by: cg


# 70620 03-Jan-2001 jhb

Rename the loader tunable from hw.sndunit to hw.snd.unit.

Submitted by: cg


# 70617 02-Jan-2001 jhb

Create a new sysctl node 'hw.snd' and move 'hw.sndunit' to
'hw.snd.unit'.

Reviewed by: cg


# 70134 17-Dec-2000 cg

kobjify.

this gives us several benefits, including:

* easier extensibility- new optional methods can be added to
ac97/mixer/channel classes without having to fixup every driver.

* forward compatibility for drivers, provided no new mandatory methods are
added.


# 65487 05-Sep-2000 cg

be more verbose about failed unload attempts


# 65382 02-Sep-2000 cg

update for phk's last devfs commit


# 65340 01-Sep-2000 cg

change mixer api slightly
change channel interface - kobj implementation coming soonish
make pcm_makelinks not panic if modular
add pcm_unregister()

these changes support newpcm kld unloading, but this is only implemented
by ds1.c


# 65207 29-Aug-2000 cg

add devfs support. when devfs is enabled, sysctl hw.sndunit is used to set
which sound unit the /dev/{dsp,mixer,dspW,audio} links point at. this can
also be set from the loader.


# 62483 03-Jul-2000 cg

add module metadata. this is a hack, sound drivers will eventually present a
bus to which pcm, mixer, etc will attach.


# 61886 20-Jun-2000 cg

fix a bug where opening for write would not fail if channel allocation failed

when playing, if we stall for 1s with no data advancing, abort and mark the
channel dead - fail all future operations


# 61344 06-Jun-2000 cg

don't panic if we try to add a channel we said we wouldn't


# 61144 31-May-2000 cg

if a device has no play or no record channels, set its simplex flag.


# 59665 26-Apr-2000 cg

duh, i forgot to change a bitmask, sorry alexander

Submitted by: Alexander Matey <matey@cis.ohio-state.edu>


# 59660 26-Apr-2000 cg

fix minor numbers for multi-channel devices

Submitted by: Alexander Matey <matey@cis.ohio-state.edu>


# 59021 04-Apr-2000 cg

allow /dev/dsp to be opened seperately for reading and writing.


# 58384 20-Mar-2000 cg

update the ac97 layer:
* add a callback for initialising the mixer interface
* support ac97 2.1 variable rate audio feature

fix ac97-using drivers for the above

add suspend/resume support for neomagic


# 56110 16-Jan-2000 cg

fix missing \n in sndstat output


# 55638 09-Jan-2000 cg

modify sndstat output


# 55494 06-Jan-2000 cg

allow mixer-only devices - ie, devices with no play/rec channels


# 55483 05-Jan-2000 cg

don't panic if channel init fails, report and fail gracefully


# 54857 19-Dec-1999 cg

allow (broken) apps to use mixer ioctls on dsp devices. eg: vmware

Submitted by: "Vladimir N. Silyaev" <vsilyaev@mindspring.com>


# 54826 19-Dec-1999 cg

move make_dev operations for audio channels to pcm_addchan(). in theory,
with modifications to MAKEDEV this will allow use of multiple output streams
on cards supporting it, eg trident 4dwave.


# 54460 12-Dec-1999 cg

move channel-swapping support to the hardware driver since it knows the card
state best


# 54212 06-Dec-1999 peter

Update for pnp adjustments regarding NPNP.

Also, optimize out a mess of #if's that were duplicating work already
done by config(8). For example, if a file is marked as
"dev/sound/pci/foo.c optional pcm pci" then it's only added if pcm *and*
pci are present, so #if NPCM > 0 and #if NPCI > 0 are totally redundant.
A bit more work is still needed.

Discussed with: cg (a few weeks ago)


# 54155 05-Dec-1999 cg

fix dma underrun issues
mutate some panics to kasserts
add more spl protection

PR: kern/14990
Partially Submitted by: Vladimir N.Silyaev <vns@delta.odessa.ua>
Reviewed by: dfr


# 53465 20-Nov-1999 cg

repo-copied to make way for newmidi, this commit updates include paths


# 52913 06-Nov-1999 tanimura

The unit of sndstat is fixed to zero.


# 52823 03-Nov-1999 tanimura

Fix for multiple pcm devices.


# 52755 01-Nov-1999 tanimura

Call make_dev() to shut up the warning.

Pointed out by: Donn Miller <dmmiller@cvzoom.net>


# 51769 28-Sep-1999 cg

* add a non-reset device- will not reset the channel on open. you
will have to mknod yourself for now.
* don't eat the first write()
* partial rvplayer fix- don't panic on unaligned writes unless our
feeder chain requires them for downconversion. a fuller fix is
on the way.


# 51658 25-Sep-1999 phk

Remove five now unused fields from struct cdevsw. They should never
have been there in the first place. A GENERIC kernel shrinks almost 1k.

Add a slightly different safetybelt under nostop for tty drivers.

Add some missing FreeBSD tags


# 50733 01-Sep-1999 peter

$Id$ -> $FreeBSD$


# 50724 01-Sep-1999 cg

say hello to newpcm. it is not yet enabled, requiring new pnp code from dfr
to compile successfully. further details will be provided in the commit
enabling newpcm.