Merge git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa

* git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa: (124 commits)
  [ALSA] version 1.0.11rc4
  [PATCH] Intruduce DMA_28BIT_MASK
  [ALSA] hda-codec - Add support for ASUS P4GPL-X
  [ALSA] hda-codec - Add support for HP nx9420 laptop
  [ALSA] Fix memory leaks in error path of control.c
  [ALSA] AMD Au1x00: AC'97 controller is memory mapped
  [ALSA] AMD Au1x00: fix DMA init/cleanup
  [ALSA] hda-codec - Fix generic auto-configurator
  [ALSA] hda-codec - Fix BIOS auto-configuration
  [ALSA] Fixes typos in Audiophile-USB.txt
  [ALSA] ice1712 - typo fixes for dxr_enable module option
  [ALSA] AMD Au1x00: make driver build after cleanup
  [ALSA] ice1712 - Fix wrong value types for enum items
  [ALSA] fix resource leak in usbmixer
  [ALSA] Fix gus_pcm dereference before NULL
  [ALSA] Fix seq_clientmgr dereferences before NULL check
  [ALSA] hda-codec - Fix for Samsung R65 and ASUS A6J
  [ALSA] hda-codec - Add support for VAIO FE550G and SZ110
  [ALSA] usb-audio: add Maya44 mixer control names
  [ALSA] usb-audio: add Casio PL-40R support
  ...
This commit is contained in:
Linus Torvalds 2006-03-22 10:59:20 -08:00
commit 1c2e02750b
202 changed files with 4941 additions and 2757 deletions

View File

@ -513,6 +513,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-ens1371
------------------
@ -526,6 +528,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-es968
----------------
@ -671,6 +675,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
model - force the model name
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
single_cmd - Use single immediate commands to communicate with
codecs (for debugging only)
This module supports one card and autoprobe.
@ -694,13 +700,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
asus 3-jack
uniwill 3-jack
F1734 2-jack
lg LG laptop (m1 express dual)
test for testing/debugging purpose, almost all controls can be
adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
auto auto-config reading BIOS (default)
ALC260
hp HP machines
fujitsu Fujitsu S7020
acer Acer TravelMate
basic fixed pin assignment (old default model)
auto auto-config reading BIOS (default)
ALC262
fujitsu Fujitsu Laptop
basic fixed pin assignment w/o SPDIF
auto auto-config reading BIOS (default)
ALC882/883/885
3stack-dig 3-jack with SPDIF I/O
6stck-dig 6-jack digital with SPDIF I/O
auto auto-config reading BIOS (default)
ALC861
3stack 3-jack
3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack with SPDIF I/O
auto auto-config reading BIOS (default)
CMI9880
minimal 3-jack in back
@ -710,6 +737,28 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
allout 5-jack in back, 2-jack in front, SPDIF out
auto auto-config reading BIOS (default)
AD1981
basic 3-jack (default)
hp HP nx6320
AD1986A
6stack 6-jack, separate surrounds (default)
3stack 3-stack, shared surrounds
laptop 2-channel only (FSC V2060, Samsung M50)
laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
AD1988
6stack 6-jack
6stack-dig ditto with SPDIF
3stack 3-jack
3stack-dig ditto with SPDIF
laptop 3-jack with hp-jack automute
laptop-dig ditto with SPDIF
auto auto-confgi reading BIOS (default)
STAC7661(?)
vaio Setup for VAIO FE550G/SZ110
If the default configuration doesn't work and one of the above
matches with your device, report it together with the PCI
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
@ -723,6 +772,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
(Usually SD_LPLIB register is more accurate than the
position buffer.)
NB: If you get many "azx_get_response timeout" messages at
loading, it's likely a problem of interrupts (e.g. ACPI irq
routing). Try to boot with options like "pci=noacpi". Also, you
can try "single_cmd=1" module option. This will switch the
communication method between HDA controller and codecs to the
single immediate commands instead of CORB/RIRB. Basically, the
single command mode is provided only for BIOS, and you won't get
unsolicited events, too. But, at least, this works independently
from the irq. Remember this is a last resort, and should be
avoided as much as possible...
The power-management is supported.
Module snd-hdsp
@ -802,6 +862,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
------------------
Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
* MidiMan M Audio Revolution 5.1
* MidiMan M Audio Revolution 7.1
* AMP Ltd AUDIO2000
* TerraTec Aureon 5.1 Sky
@ -810,6 +871,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
* TerraTec Phase 22
* TerraTec Phase 28
* AudioTrak Prodigy 7.1
* AudioTrak Prodigy 7.1LT
* AudioTrak Prodigy 192
* Pontis MS300
* Albatron K8X800 Pro II
@ -820,9 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
* Shuttle SN25P
model - Use the given board model, one of the following:
revo71, amp2000, prodigy71, prodigy192, aureon51,
aureon71, universe, k8x800, phase22, phase28, ms300,
av710
revo51, revo71, amp2000, prodigy71, prodigy71lt,
prodigy192, aureon51, aureon71, universe,
k8x800, phase22, phase28, ms300, av710
This module supports multiple cards and autoprobe.
@ -1353,6 +1415,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
vid - Vendor ID for the device (optional)
pid - Product ID for the device (optional)
device_setup - Device specific magic number (optional)
- Influence depends on the device
- Default: 0x0000
This module supports multiple devices, autoprobe and hotplugging.

View File

@ -0,0 +1,333 @@
Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2
========================================================
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
This document is a guide to using the M-Audio Audiophile USB (tm) device with
ALSA and JACK.
1 - Audiophile USB Specs and correct usage
==========================================
This part is a reminder of important facts about the functions and limitations
of the device.
The device has 4 audio interfaces, and 2 MIDI ports:
* Analog Stereo Input (Ai)
- This port supports 2 pairs of line-level audio inputs (1/4" TS and RCA)
- When the 1/4" TS (jack) connectors are connected, the RCA connectors
are disabled
* Analog Stereo Output (Ao)
* Digital Stereo Input (Di)
* Digital Stereo Output (Do)
* Midi In (Mi)
* Midi Out (Mo)
The internal DAC/ADC has the following caracteristics:
* sample depth of 16 or 24 bits
* sample rate from 8kHz to 96kHz
* Two ports can't use different sample depths at the same time.Moreover, the
Audiophile USB documentation gives the following Warning: "Please exit any
audio application running before switching between bit depths"
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
activated at the same time depending on the audio mode selected:
* 16-bit/48kHz ==> 4 channels in/ 4 channels out
- Ai+Ao+Di+Do
* 24-bit/48kHz ==> 4 channels in/2 channels out,
or 2 channels in/4 channels out
- Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do
* 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only)
- Ai or Ao or Di or Do
Important facts about the Digital interface:
--------------------------------------------
* The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough,
though I haven't tested it under linux
- Note that in this setup only the Do interface can be enabled
* Apart from recording an audio digital stream, enabling the Di port is a way
to synchronize the device to an external sample clock
- As a consequence, the Di port must be enable only if an active Digital
source is connected
- Enabling Di when no digital source is connected can result in a
synchronization error (for instance sound played at an odd sample rate)
2 - Audiophile USB support in ALSA
==================================
2.1 - MIDI ports
----------------
The Audiophile USB MIDI ports will be automatically supported once the
following modules have been loaded:
* snd-usb-audio
* snd-seq
* snd-seq-midi
No additionnal setting is required.
2.2 - Audio ports
-----------------
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
module. This module can work in a default mode (without any device-specific
parameter), or in an advanced mode with the device-specific parameter called
"device_setup".
2.2.1 - Default Alsa driver mode
The default behaviour of the snd-usb-audio driver is to parse the device
capabilities at startup and enable all functions inside the device (including
all ports at any sample rates and any sample depths supported). This approach
has the advantage to let the driver easily switch from sample rates/depths
automatically according to the need of the application claiming the device.
In this case the Audiophile ports are mapped to alsa pcm devices in the
following way (I suppose the device's index is 1):
* hw:1,0 is Ao in playback and Di in capture
* hw:1,1 is Do in playback and Ai in capture
* hw:1,2 is Do in AC3/DTS passthrough mode
You must note as well that the device uses Big Endian byte encoding so that
supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
24-bits depth mode. One exception is the hw:1,2 port which is Little Endian
compliant and thus uses S16_LE.
Examples:
* playing a S24_3BE encoded raw file to the Ao port
% aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw
* recording a S24_3BE encoded raw file from the Ai port
% arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw
* playing a S16_BE encoded raw file to the Do port
% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
If you're happy with the default Alsa driver setup and don't experience any
issue with this mode, then you can skip the following chapter.
2.2.2 - Advanced module setup
Due to the hardware constraints described above, the device initialization made
by the Alsa driver in default mode may result in a corrupted state of the
device. For instance, a particularly annoying issue is that the sound captured
from the Ai port sounds distorted (as if boosted with an excessive high volume
gain).
For people having this problem, the snd-usb-audio module has a new module
parameter called "device_setup".
2.2.2.1 - Initializing the working mode of the Audiohile USB
As far as the Audiohile USB device is concerned, this value let the user
specify:
* the sample depth
* the sample rate
* whether the Di port is used or not
Here is a list of supported device_setup values for this device:
* device_setup=0x00 (or omitted)
- Alsa driver default mode
- maintains backward compatibility with setups that do not use this
parameter by not introducing any change
- results sometimes in corrupted sound as decribed earlier
* device_setup=0x01
- 16bits 48kHz mode with Di disabled
- Ai,Ao,Do can be used at the same time
- hw:1,0 is not available in capture mode
- hw:1,2 is not available
* device_setup=0x11
- 16bits 48kHz mode with Di enabled
- Ai,Ao,Di,Do can be used at the same time
- hw:1,0 is available in capture mode
- hw:1,2 is not available
* device_setup=0x09
- 24bits 48kHz mode with Di disabled
- Ai,Ao,Do can be used at the same time
- hw:1,0 is not available in capture mode
- hw:1,2 is not available
* device_setup=0x19
- 24bits 48kHz mode with Di enabled
- 3 ports from {Ai,Ao,Di,Do} can be used at the same time
- hw:1,0 is available in capture mode and an active digital source must be
connected to Di
- hw:1,2 is not available
* device_setup=0x0D or 0x10
- 24bits 96kHz mode
- Di is enabled by default for this mode but does not need to be connected
to an active source
- Only 1 port from {Ai,Ao,Di,Do} can be used at the same time
- hw:1,0 is available in captured mode
- hw:1,2 is not available
* device_setup=0x03
- 16bits 48kHz mode with only the Do port enabled
- AC3 with DTS passthru (not tested)
- Caution with this setup the Do port is mapped to the pcm device hw:1,0
2.2.2.2 - Setting and switching configurations with the device_setup parameter
The parameter can be given:
* By manually probing the device (as root):
# modprobe -r snd-usb-audio
# modprobe snd-usb-audio index=1 device_setup=0x09
* Or while configuring the modules options in your modules configuration file
- For Fedora distributions, edit the /etc/modprobe.conf file:
alias snd-card-1 snd-usb-audio
options snd-usb-audio index=1 device_setup=0x09
IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
-------------------------------------------
* You may need to _first_ intialize the module with the correct device_setup
parameter and _only_after_ turn on the Audiophile USB device
* This is especially true when switching the sample depth:
- first trun off the device
- de-register the snd-usb-audio module
- change the device_setup parameter (by either manually reprobing the module
or changing modprobe.conf)
- turn on the device
2.2.2.3 - Audiophile USB's device_setup structure
If you want to understand the device_setup magic numbers for the Audiophile
USB, you need some very basic understanding of binary computation. However,
this is not required to use the parameter and you may skip thi section.
The device_setup is one byte long and its structure is the following:
+---+---+---+---+---+---+---+---+
| b7| b6| b5| b4| b3| b2| b1| b0|
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | Di|24B|96K|DTS|SET|
+---+---+---+---+---+---+---+---+
Where:
* b0 is the "SET" bit
- it MUST be set if device_setup is initialized
* b1 is the "DTS" bit
- it is set only for Digital output with DTS/AC3
- this setup is not tested
* b2 is the Rate selection flag
- When set to "1" the rate range is 48.1-96kHz
- Otherwise the sample rate range is 8-48kHz
* b3 is the bit depth selection flag
- When set to "1" samples are 24bits long
- Otherwise they are 16bits long
- Note that b2 implies b3 as the 96kHz mode is only supported for 24 bits
samples
* b4 is the Digital input flag
- When set to "1" the device assumes that an active digital source is
connected
- You shouldn't enable Di if no source is seen on the port (this leads to
synchronization issues)
- b4 is implied by b2 (since only one port is enabled at a time no synch
error can occur)
* b5 to b7 are reserved for future uses, and must be set to "0"
- might become Ao, Do, Ai, for b7, b6, b4 respectively
Caution:
* there is no check on the value you will give to device_setup
- for instance choosing 0x05 (16bits 96kHz) will fail back to 0x09 since
b2 implies b3. But _there_will_be_no_warning_ in /var/log/messages
* Hardware constraints due to the USB bus limitation aren't checked
- choosing b2 will prepare all interfaces for 24bits/96kHz but you'll
only be able to use one at the same time
2.2.3 - USB implementation details for this device
You may safely skip this section if you're not interrested in driver
development.
This section describes some internals aspect of the device and summarize the
data I got by usb-snooping the windows and linux drivers.
The M-Audio Audiophile USB has 7 USB Interfaces:
a "USB interface":
* USB Interface nb.0
* USB Interface nb.1
- Audio Control function
* USB Interface nb.2
- Analog Output
* USB Interface nb.3
- Digital Output
* USB Interface nb.4
- Analog Input
* USB Interface nb.5
- Digital Input
* USB Interface nb.6
- MIDI interface compliant with the MIDIMAN quirk
Each interface has 5 altsettings (AltSet 1,2,3,4,5) except:
* Interface 3 (Digital Out) has an extra Alset nb.6
* Interface 5 (Digital In) does not have Alset nb.3 and 5
Here is a short description of the AltSettings capabilities:
* AltSettings 1 corresponds to
- 24-bit depth, 48.1-96kHz sample mode
- Adaptive playback (Ao and Do), Synch capture (Ai), or Asynch capture (Di)
* AltSettings 2 corresponds to
- 24-bit depth, 8-48kHz sample mode
- Asynch capture and playback (Ao,Ai,Do,Di)
* AltSettings 3 corresponds to
- 24-bit depth, 8-48kHz sample mode
- Synch capture (Ai) and Adaptive playback (Ao,Do)
* AltSettings 4 corresponds to
- 16-bit depth, 8-48kHz sample mode
- Asynch capture and playback (Ao,Ai,Do,Di)
* AltSettings 5 corresponds to
- 16-bit depth, 8-48kHz sample mode
- Synch capture (Ai) and Adaptive playback (Ao,Do)
* AltSettings 6 corresponds to
- 16-bit depth, 8-48kHz sample mode
- Synch playback (Do), audio format type III IEC1937_AC-3
In order to ensure a correct intialization of the device, the driver
_must_know_ how the device will be used:
* if DTS is choosen, only Interface 2 with AltSet nb.6 must be
registered
* if 96KHz only AltSets nb.1 of each interface must be selected
* if samples are using 24bits/48KHz then AltSet 2 must me used if
Digital input is connected, and only AltSet nb.3 if Digital input
is not connected
* if samples are using 16bits/48KHz then AltSet 4 must me used if
Digital input is connected, and only AltSet nb.5 if Digital input
is not connected
When device_setup is given as a parameter to the snd-usb-audio module, the
parse_audio_enpoint function uses a quirk called
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
corresponding to device_setup from being registered in the driver.
3 - Audiophile USB and Jack support
===================================
This section deals with support of the Audiophile USB device in Jack.
The main issue regarding this support is that the device is Big Endian
compliant.
3.1 - Using the plug alsa plugin
--------------------------------
Jack doesn't directly support big endian devices. Thus, one way to have support
for this device with Alsa is to use the Alsa "plug" converter.
For instance here is one way to run Jack with 2 playback channels on Ao and 2
capture channels from Ai:
% jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
However you may see the following warning message:
"You appear to be using the ALSA software "plug" layer, probably a result of
using the "default" ALSA device. This is less efficient than it could be.
Consider using a hardware device instead rather than using the plug layer."
3.2 - Patching alsa to use direct pcm device
-------------------------------------------
A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
However it has not been included in the CVS tree.
You can find it at the following URL:
http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687&
atid=425939
After having applied the patch you can run jackd with the following command
line:
% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1

View File

@ -1834,7 +1834,7 @@
mychip_set_sample_format(chip, runtime->format);
mychip_set_sample_rate(chip, runtime->rate);
mychip_set_channels(chip, runtime->channels);
mychip_set_dma_setup(chip, runtime->dma_area,
mychip_set_dma_setup(chip, runtime->dma_addr,
chip->buffer_size,
chip->period_size);
return 0;
@ -3388,7 +3388,7 @@ struct _snd_pcm_runtime {
.name = "PCM Playback Switch",
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.private_values = 0xffff,
.private_value = 0xffff,
.info = my_control_info,
.get = my_control_get,
.put = my_control_put
@ -3449,7 +3449,7 @@ struct _snd_pcm_runtime {
</para>
<para>
The <structfield>private_values</structfield> field contains
The <structfield>private_value</structfield> field contains
an arbitrary long integer value for this record. When using
generic <structfield>info</structfield>,
<structfield>get</structfield> and

View File

@ -157,14 +157,14 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
{
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
return 0;
}
static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
{
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;

View File

@ -63,7 +63,7 @@ struct cx88_audio_dev {
/* audio controls */
int irq;
snd_card_t *card;
struct snd_card *card;
spinlock_t reg_lock;
@ -82,7 +82,7 @@ struct cx88_audio_dev {
struct cx88_buffer *buf;
long opened;
snd_pcm_substream_t *substream;
struct snd_pcm_substream *substream;
};
typedef struct cx88_audio_dev snd_cx88_card_t;
@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
static struct snd_card *snd_cx88_cards[SNDRV_CARDS];
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
@ -320,7 +320,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
/*
* Digital hardware definition
*/
static snd_pcm_hardware_t snd_cx88_digital_hw = {
static struct snd_pcm_hardware snd_cx88_digital_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@ -342,16 +342,16 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = {
/*
* audio pcm capture runtime free
*/
static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime)
{
}
/*
* audio pcm capture open callback
*/
static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
if (test_and_set_bit(0, &chip->opened))
@ -380,7 +380,7 @@ static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
/*
* audio close callback
*/
static int snd_cx88_close(snd_pcm_substream_t *substream)
static int snd_cx88_close(struct snd_pcm_substream *substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
@ -393,8 +393,8 @@ static int snd_cx88_close(snd_pcm_substream_t *substream)
/*
* hw_params callback
*/
static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
struct snd_pcm_hw_params * hw_params)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
struct cx88_buffer *buf;
@ -453,7 +453,7 @@ static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
/*
* hw free callback
*/
static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
static int snd_cx88_hw_free(struct snd_pcm_substream * substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
@ -469,7 +469,7 @@ static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
/*
* prepare callback
*/
static int snd_cx88_prepare(snd_pcm_substream_t *substream)
static int snd_cx88_prepare(struct snd_pcm_substream *substream)
{
return 0;
}
@ -478,7 +478,7 @@ static int snd_cx88_prepare(snd_pcm_substream_t *substream)
/*
* trigger callback
*/
static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
int err;
@ -505,10 +505,10 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
/*
* pointer callback
*/
static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
if (chip->read_count) {
chip->read_count -= snd_pcm_lib_period_bytes(substream);
@ -525,7 +525,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
/*
* operators
*/
static snd_pcm_ops_t snd_cx88_pcm_ops = {
static struct snd_pcm_ops snd_cx88_pcm_ops = {
.open = snd_cx88_pcm_open,
.close = snd_cx88_close,
.ioctl = snd_pcm_lib_ioctl,
@ -542,7 +542,7 @@ static snd_pcm_ops_t snd_cx88_pcm_ops = {
static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
{
int err;
snd_pcm_t *pcm;
struct snd_pcm *pcm;
err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
if (err < 0)
@ -557,7 +557,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
/****************************************************************************
CONTROL INTERFACE
****************************************************************************/
static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *info)
{
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
info->count = 1;
@ -568,7 +569,8 @@ static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i
}
/* OK - TODO: test it */
static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *value)
{
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
struct cx88_core *core=chip->core;
@ -579,7 +581,8 @@ static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
}
/* OK - TODO: test it */
static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *value)
{
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
struct cx88_core *core=chip->core;
@ -595,7 +598,7 @@ static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
return v != old_control;
}
static snd_kcontrol_new_t snd_cx88_capture_volume = {
static struct snd_kcontrol_new snd_cx88_capture_volume = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Volume",
.info = snd_cx88_capture_volume_info,
@ -641,7 +644,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip)
/*
* Component Destructor
*/
static void snd_cx88_dev_free(snd_card_t * card)
static void snd_cx88_dev_free(struct snd_card * card)
{
snd_cx88_card_t *chip = card->private_data;
@ -654,8 +657,9 @@ static void snd_cx88_dev_free(snd_card_t * card)
*/
static int devno;
static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
snd_cx88_card_t **rchip)
static int __devinit snd_cx88_create(struct snd_card *card,
struct pci_dev *pci,
snd_cx88_card_t **rchip)
{
snd_cx88_card_t *chip;
struct cx88_core *core;
@ -726,7 +730,7 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
static int __devinit cx88_audio_initdev(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
snd_card_t *card;
struct snd_card *card;
snd_cx88_card_t *chip;
int err;

View File

@ -71,7 +71,7 @@ MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
*/
typedef struct snd_card_saa7134 {
snd_card_t *card;
struct snd_card *card;
spinlock_t mixer_lock;
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
@ -95,10 +95,10 @@ typedef struct snd_card_saa7134_pcm {
spinlock_t lock;
snd_pcm_substream_t *substream;
struct snd_pcm_substream *substream;
} snd_card_saa7134_pcm_t;
static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];
/*
@ -251,10 +251,10 @@ static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
*
*/
static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
int cmd)
{
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
struct saa7134_dev *dev=pcm->dev;
int err = 0;
@ -332,9 +332,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
*
*/
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
int bswap, sign;
u32 fmt, control;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
@ -421,9 +421,10 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
*
*/
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
static snd_pcm_uframes_t
snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
struct saa7134_dev *dev=pcm->dev;
@ -441,7 +442,7 @@ static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t *
* ALSA hardware capabilities definition
*/
static snd_pcm_hardware_t snd_card_saa7134_capture =
static struct snd_pcm_hardware snd_card_saa7134_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@ -464,7 +465,7 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
.periods_max = 1024,
};
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
{
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
@ -481,8 +482,8 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
*
*/
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
struct snd_pcm_hw_params * hw_params)
{
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev;
@ -561,7 +562,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
*
*/
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
{
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev;
@ -587,7 +588,7 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
*
*/
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
{
return 0;
}
@ -602,9 +603,9 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
*
*/
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = substream->runtime;
snd_card_saa7134_pcm_t *pcm;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev = saa7134->dev;
@ -640,7 +641,7 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
* ALSA capture callbacks definition
*/
static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
.open = snd_card_saa7134_capture_open,
.close = snd_card_saa7134_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@ -661,7 +662,7 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
{
snd_pcm_t *pcm;
struct snd_pcm *pcm;
int err;
if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
@ -679,7 +680,8 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
.get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
.private_value = addr }
static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_info * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@ -688,7 +690,8 @@ static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
return 0;
}
static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_value * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
@ -698,7 +701,8 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
return 0;
}
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_value * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
int change, addr = kcontrol->private_value;
@ -729,7 +733,8 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
.get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
.private_value = addr }
static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_info * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 2;
@ -738,7 +743,8 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
return 0;
}
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_value * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
int addr = kcontrol->private_value;
@ -751,7 +757,8 @@ static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
return 0;
}
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
struct snd_ctl_elem_value * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
int change, addr = kcontrol->private_value;
@ -828,7 +835,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
return change;
}
static snd_kcontrol_new_t snd_saa7134_controls[] = {
static struct snd_kcontrol_new snd_saa7134_controls[] = {
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
@ -847,7 +854,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
{
snd_card_t *card = chip->card;
struct snd_card *card = chip->card;
unsigned int idx;
int err;
@ -861,7 +868,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
return 0;
}
static void snd_saa7134_free(snd_card_t * card)
static void snd_saa7134_free(struct snd_card * card)
{
snd_card_saa7134_t *chip = card->private_data;
@ -888,7 +895,7 @@ static void snd_saa7134_free(snd_card_t * card)
static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
{
snd_card_t *card;
struct snd_card *card;
snd_card_saa7134_t *chip;
int err;

View File

@ -397,7 +397,7 @@ struct saa7134_dmasound {
unsigned int read_offset;
unsigned int read_count;
void * priv_data;
snd_pcm_substream_t *substream;
struct snd_pcm_substream *substream;
};
/* IR input */

View File

@ -6,8 +6,8 @@
#include <sound/pcm.h>
typedef struct {
int (*startup)(snd_pcm_substream_t *, void *);
void (*shutdown)(snd_pcm_substream_t *, void *);
int (*startup)(struct snd_pcm_substream *, void *);
void (*shutdown)(struct snd_pcm_substream *, void *);
void (*suspend)(void *);
void (*resume)(void *);
void *priv;

View File

@ -20,6 +20,7 @@ enum dma_data_direction {
#define DMA_31BIT_MASK 0x000000007fffffffULL
#define DMA_30BIT_MASK 0x000000003fffffffULL
#define DMA_29BIT_MASK 0x000000001fffffffULL
#define DMA_28BIT_MASK 0x000000000fffffffULL
#include <asm/dma-mapping.h>

View File

@ -433,6 +433,12 @@ struct snd_ac97_bus {
struct snd_info_entry *proc;
};
/* static resolution table */
struct snd_ac97_res_table {
unsigned short reg; /* register */
unsigned short bits; /* resolution bitmask */
};
struct snd_ac97_template {
void *private_data;
void (*private_free) (struct snd_ac97 *ac97);
@ -440,8 +446,7 @@ struct snd_ac97_template {
unsigned short num; /* number of codec: 0 = primary, 1 = secondary */
unsigned short addr; /* physical address of codec [0-3] */
unsigned int scaps; /* driver capabilities */
unsigned int limited_regs; /* allow limited registers only */
DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
const struct snd_ac97_res_table *res_table; /* static resolution */
};
struct snd_ac97 {
@ -456,20 +461,20 @@ struct snd_ac97 {
struct snd_info_entry *proc_regs;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
struct semaphore reg_mutex;
struct semaphore page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
struct mutex reg_mutex;
struct mutex page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
unsigned short num; /* number of codec: 0 = primary, 1 = secondary */
unsigned short addr; /* physical address of codec [0-3] */
unsigned int id; /* identification of codec */
unsigned short caps; /* capabilities (register 0) */
unsigned short ext_id; /* extended feature identification (register 28) */
unsigned short ext_mid; /* extended modem ID (register 3C) */
const struct snd_ac97_res_table *res_table; /* static resolution */
unsigned int scaps; /* driver capabilities */
unsigned int flags; /* specific code */
unsigned int rates[6]; /* see AC97_RATES_* defines */
unsigned int spdif_status;
unsigned short regs[0x80]; /* register cache */
unsigned int limited_regs; /* allow limited registers only */
DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
union { /* vendor specific code */
struct {

View File

@ -154,7 +154,7 @@ struct snd_ad1848 {
#endif
spinlock_t reg_lock;
struct semaphore open_mutex;
struct mutex open_mutex;
};
/* exported functions */

View File

@ -71,7 +71,7 @@ struct snd_ak4531 {
void (*private_free) (struct snd_ak4531 *ak4531);
/* --- */
unsigned char regs[0x20];
struct semaphore reg_mutex;
struct mutex reg_mutex;
};
int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,

View File

@ -23,7 +23,7 @@
*/
#include <linux/sched.h> /* wake_up() */
#include <asm/semaphore.h> /* struct semaphore */
#include <linux/mutex.h> /* struct mutex */
#include <linux/rwsem.h> /* struct rw_semaphore */
#include <linux/workqueue.h> /* struct workqueue_struct */
#include <linux/pm.h> /* pm_message_t */
@ -137,7 +137,7 @@ struct snd_card {
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
struct semaphore power_lock; /* power lock */
struct mutex power_lock; /* power lock */
wait_queue_head_t power_sleep;
#endif
@ -150,12 +150,12 @@ struct snd_card {
#ifdef CONFIG_PM
static inline void snd_power_lock(struct snd_card *card)
{
down(&card->power_lock);
mutex_lock(&card->power_lock);
}
static inline void snd_power_unlock(struct snd_card *card)
{
up(&card->power_lock);
mutex_unlock(&card->power_lock);
}
static inline unsigned int snd_power_get_state(struct snd_card *card)

View File

@ -248,8 +248,8 @@ struct snd_cs4231 {
unsigned int c_dma_size;
spinlock_t reg_lock;
struct semaphore mce_mutex;
struct semaphore open_mutex;
struct mutex mce_mutex;
struct mutex open_mutex;
int (*rate_constraint) (struct snd_pcm_runtime *runtime);
void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr);

View File

@ -1711,7 +1711,7 @@ struct snd_cs46xx {
int current_gpio;
#endif
#ifdef CONFIG_SND_CS46XX_NEW_DSP
struct semaphore spos_mutex;
struct mutex spos_mutex;
struct dsp_spos_instance * dsp_spos_instance;

View File

@ -33,6 +33,7 @@
#include <sound/pcm-indirect.h>
#include <sound/timer.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <asm/io.h>
/* ------------------- DEFINES -------------------- */
@ -1022,7 +1023,7 @@ struct snd_emu10k1_fx8010 {
int gpr_size; /* size of allocated GPR controls */
int gpr_count; /* count of used kcontrols */
struct list_head gpr_ctl; /* GPR controls */
struct semaphore lock;
struct mutex lock;
struct snd_emu10k1_fx8010_pcm pcm[8];
spinlock_t irq_lock;
struct snd_emu10k1_fx8010_irq *irq_handlers;
@ -1122,7 +1123,6 @@ struct snd_emu10k1 {
spinlock_t reg_lock;
spinlock_t emu_lock;
spinlock_t voice_lock;
struct semaphore ptb_lock;
struct snd_emu10k1_voice voices[NUM_G];
struct snd_emu10k1_voice p16v_voices[4];

View File

@ -113,7 +113,7 @@ struct snd_emux {
struct snd_emux_voice *voices; /* Voices (EMU 'channel') */
int use_time; /* allocation counter */
spinlock_t voice_lock; /* Lock for voice access */
struct semaphore register_mutex;
struct mutex register_mutex;
int client; /* For the sequencer client */
int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */
struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS];

View File

@ -209,7 +209,7 @@ struct snd_gf1_mem {
struct snd_gf1_bank_info banks_16[4];
struct snd_gf1_mem_block *first;
struct snd_gf1_mem_block *last;
struct semaphore memory_mutex;
struct mutex memory_mutex;
};
struct snd_gf1_dma_block {
@ -467,8 +467,8 @@ struct snd_gus_card {
spinlock_t dma_lock;
spinlock_t pcm_volume_level_lock;
spinlock_t uart_cmd_lock;
struct semaphore dma_mutex;
struct semaphore register_mutex;
struct mutex dma_mutex;
struct mutex register_mutex;
};
/* I/O functions for GF1/InterWave chip - gus_io.c */

View File

@ -60,7 +60,7 @@ struct snd_hwdep {
void *private_data;
void (*private_free) (struct snd_hwdep *hwdep);
struct semaphore open_mutex;
struct mutex open_mutex;
int used;
unsigned int dsp_loaded;
unsigned int exclusive: 1;

View File

@ -55,7 +55,7 @@ struct snd_i2c_bus {
struct snd_card *card; /* card which I2C belongs to */
char name[32]; /* some useful label */
struct semaphore lock_mutex;
struct mutex lock_mutex;
struct snd_i2c_bus *master; /* master bus when SCK/SCL is shared */
struct list_head buses; /* master: slave buses sharing SCK/SCL, slave: link list */
@ -84,17 +84,17 @@ int snd_i2c_device_free(struct snd_i2c_device *device);
static inline void snd_i2c_lock(struct snd_i2c_bus *bus)
{
if (bus->master)
down(&bus->master->lock_mutex);
mutex_lock(&bus->master->lock_mutex);
else
down(&bus->lock_mutex);
mutex_lock(&bus->lock_mutex);
}
static inline void snd_i2c_unlock(struct snd_i2c_bus *bus)
{
if (bus->master)
up(&bus->master->lock_mutex);
mutex_unlock(&bus->master->lock_mutex);
else
up(&bus->lock_mutex);
mutex_unlock(&bus->lock_mutex);
}
int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);

View File

@ -84,7 +84,7 @@ struct snd_info_entry {
void *private_data;
void (*private_free)(struct snd_info_entry *entry);
struct proc_dir_entry *p;
struct semaphore access;
struct mutex access;
};
#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)

View File

@ -61,7 +61,7 @@ struct snd_mixer_oss {
unsigned int active_index);
void *private_data_recsrc;
void (*private_free_recsrc)(struct snd_mixer_oss *mixer);
struct semaphore reg_mutex;
struct mutex reg_mutex;
struct snd_info_entry *proc_entry;
int oss_dev_alloc;
/* --- */

View File

@ -53,6 +53,7 @@
#include "driver.h"
#include <linux/time.h>
#include <linux/mutex.h>
#include "core.h"
#include "hwdep.h"
#include "timer.h"
@ -312,7 +313,7 @@ struct snd_opl3 {
int sys_timer_status; /* system timer run status */
spinlock_t sys_timer_lock; /* Lock for system timer access */
#endif
struct semaphore access_mutex; /* locking */
struct mutex access_mutex; /* locking */
};
/* opl3.c */

View File

@ -420,7 +420,7 @@ struct snd_pcm {
char id[64];
char name[80];
struct snd_pcm_str streams[2];
struct semaphore open_mutex;
struct mutex open_mutex;
wait_queue_head_t open_wait;
void *private_data;
void (*private_free) (struct snd_pcm *pcm);

View File

@ -56,8 +56,10 @@ struct snd_pcm_oss_runtime {
size_t mmap_bytes;
char *buffer; /* vmallocated period */
size_t buffer_used; /* used length from period buffer */
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
struct snd_pcm_plugin *plugin_first;
struct snd_pcm_plugin *plugin_last;
#endif
unsigned int prev_hw_ptr_interrupt;
};
@ -73,7 +75,7 @@ struct snd_pcm_oss_substream {
struct snd_pcm_oss_stream {
struct snd_pcm_oss_setup *setup_list; /* setup list */
struct semaphore setup_mutex;
struct mutex setup_mutex;
struct snd_info_entry *proc_entry;
};

View File

@ -26,7 +26,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <asm/semaphore.h>
#include <linux/mutex.h>
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
#include "seq_device.h"
@ -130,7 +130,7 @@ struct snd_rawmidi {
void *private_data;
void (*private_free) (struct snd_rawmidi *rmidi);
struct semaphore open_mutex;
struct mutex open_mutex;
wait_queue_head_t open_wait;
struct snd_info_entry *dev;

View File

@ -158,7 +158,7 @@ struct snd_sb_csp {
struct snd_kcontrol *qsound_switch;
struct snd_kcontrol *qsound_space;
struct semaphore access_mutex; /* locking */
struct mutex access_mutex; /* locking */
};
int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);

View File

@ -64,7 +64,7 @@ struct snd_seq_kinstr_list {
spinlock_t lock;
spinlock_t ops_lock;
struct semaphore ops_mutex;
struct mutex ops_mutex;
unsigned long ops_flags;
};

View File

@ -93,7 +93,7 @@ struct snd_sf_list {
int sample_locked; /* locked time for sample */
struct snd_sf_callback callback; /* callback functions */
int presets_locked;
struct semaphore presets_mutex;
struct mutex presets_mutex;
spinlock_t lock;
struct snd_util_memhdr *memhdr;
};

View File

@ -1,5 +1,7 @@
#ifndef __SOUND_UTIL_MEM_H
#define __SOUND_UTIL_MEM_H
#include <linux/mutex.h>
/*
* Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
*
@ -40,7 +42,7 @@ struct snd_util_memhdr {
int nblocks; /* # of allocated blocks */
unsigned int used; /* used memory size */
int block_extra_size; /* extra data size of chunk */
struct semaphore block_mutex; /* lock */
struct mutex block_mutex; /* lock */
};
/*

View File

@ -1,3 +1,3 @@
/* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "1.0.11rc2"
#define CONFIG_SND_DATE " (Wed Jan 04 08:57:20 2006 UTC)"
#define CONFIG_SND_VERSION "1.0.11rc4"
#define CONFIG_SND_DATE " (Wed Mar 22 10:27:24 2006 UTC)"

View File

@ -206,7 +206,7 @@ struct vx_core {
int audio_monitor[4]; /* playback hw-monitor level */
unsigned char audio_monitor_active[4]; /* playback hw-monitor mute/unmute */
struct semaphore mixer_mutex;
struct mutex mixer_mutex;
const struct firmware *firmware[4]; /* loaded firmware data */
};

View File

@ -269,9 +269,10 @@ struct snd_ymfpci_pcm {
enum snd_ymfpci_pcm_type type;
struct snd_pcm_substream *substream;
struct snd_ymfpci_voice *voices[2]; /* playback only */
unsigned int running: 1;
unsigned int output_front: 1;
unsigned int output_rear: 1;
unsigned int running: 1,
output_front: 1,
output_rear: 1,
swap_rear: 1;
unsigned int update_pcm_vol;
u32 period_size; /* cached from runtime->period_size */
u32 buffer_size; /* cached from runtime->buffer_size */
@ -344,6 +345,7 @@ struct snd_ymfpci {
struct snd_kcontrol *spdif_pcm_ctl;
int mode_dup4ch;
int rear_opened;
int rear_swap;
int spdif_opened;
struct {
u16 left;
@ -376,7 +378,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap);
int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
#endif /* __SOUND_YMFPCI_H */

View File

@ -73,7 +73,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
if (ac97->num >= 4)
return;
down(&aaci->ac97_sem);
mutex_lock(&aaci->ac97_sem);
aaci_ac97_select_codec(aaci, ac97);
@ -91,7 +91,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
v = readl(aaci->base + AACI_SLFR);
} while (v & (SLFR_1TXB|SLFR_2TXB));
up(&aaci->ac97_sem);
mutex_unlock(&aaci->ac97_sem);
}
/*
@ -105,7 +105,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
if (ac97->num >= 4)
return ~0;
down(&aaci->ac97_sem);
mutex_lock(&aaci->ac97_sem);
aaci_ac97_select_codec(aaci, ac97);
@ -145,7 +145,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
v = ~0;
}
up(&aaci->ac97_sem);
mutex_unlock(&aaci->ac97_sem);
return v;
}
@ -783,7 +783,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
card->shortname, dev->res.start, dev->irq[0]);
aaci = card->private_data;
init_MUTEX(&aaci->ac97_sem);
mutex_init(&aaci->ac97_sem);
spin_lock_init(&aaci->lock);
aaci->card = card;
aaci->dev = dev;

View File

@ -227,7 +227,7 @@ struct aaci {
unsigned int fifosize;
/* AC'97 */
struct semaphore ac97_sem;
struct mutex ac97_sem;
ac97_bus_t *ac97_bus;
u32 maincr;

View File

@ -25,7 +25,7 @@
#include <sound/initval.h>
#include <asm/irq.h>
#include <asm/semaphore.h>
#include <linux/mutex.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/audio.h>
@ -33,7 +33,7 @@
#include "pxa2xx-pcm.h"
static DECLARE_MUTEX(car_mutex);
static DEFINE_MUTEX(car_mutex);
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
static volatile long gsr_bits;
@ -52,7 +52,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg
unsigned short val = -1;
volatile u32 *reg_addr;
down(&car_mutex);
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
@ -79,7 +79,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg
/* but we've just started another cycle... */
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
out: up(&car_mutex);
out: mutex_unlock(&car_mutex);
return val;
}
@ -87,7 +87,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne
{
volatile u32 *reg_addr;
down(&car_mutex);
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
@ -101,7 +101,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
__FUNCTION__, reg, GSR | gsr_bits);
up(&car_mutex);
mutex_unlock(&car_mutex);
}
static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)

View File

@ -73,6 +73,15 @@ config SND_PCM_OSS
To compile this driver as a module, choose M here: the module
will be called snd-pcm-oss.
config SND_PCM_OSS_PLUGINS
bool "OSS PCM (digital audio) API - Include plugin system"
depends on SND_PCM_OSS
default y
help
If you disable this option, the ALSA's OSS PCM API will not
support conversion of channels, formats and rates. It will
behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
config SND_SEQUENCER_OSS
bool "OSS Sequencer API"
depends on SND && SND_SEQUENCER
@ -130,6 +139,15 @@ config SND_SUPPORT_OLD_API
Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
or older).
config SND_VERBOSE_PROCFS
bool "Verbose procfs contents"
depends on SND
default y
help
Say Y here to include code for verbose procfs contents (provides
usefull information to developers when a problem occurs). On the
other side, it makes the ALSA subsystem larger.
config SND_VERBOSE_PRINTK
bool "Verbose printk"
depends on SND

View File

@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
{
struct snd_ctl_elem_id id;
unsigned int idx;
int err = -EINVAL;
snd_assert(card != NULL, return -EINVAL);
if (! kcontrol)
return -EINVAL;
snd_assert(kcontrol->info != NULL, return -EINVAL);
return err;
snd_assert(card != NULL, goto error);
snd_assert(kcontrol->info != NULL, goto error);
id = kcontrol->id;
down_write(&card->controls_rwsem);
if (snd_ctl_find_id(card, &id)) {
up_write(&card->controls_rwsem);
snd_ctl_free_one(kcontrol);
snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
id.iface,
id.device,
id.subdevice,
id.name,
id.index);
return -EBUSY;
err = -EBUSY;
goto error;
}
if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
up_write(&card->controls_rwsem);
snd_ctl_free_one(kcontrol);
return -ENOMEM;
err = -ENOMEM;
goto error;
}
list_add_tail(&kcontrol->list, &card->controls);
card->controls_count += kcontrol->count;
@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
return 0;
error:
snd_ctl_free_one(kcontrol);
return err;
}
/**
@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
result = snd_ctl_elem_info(ctl, &info);
snd_power_lock(ctl->card);
result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
if (result >= 0)
result = snd_ctl_elem_info(ctl, &info);
snd_power_unlock(ctl->card);
if (result >= 0)
if (copy_to_user(_info, &info, sizeof(info)))
return -EFAULT;
@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
kfree(control);
return -EFAULT;
}
result = snd_ctl_elem_read(card, control);
snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
if (result >= 0)
result = snd_ctl_elem_read(card, control);
snd_power_unlock(card);
if (result >= 0)
if (copy_to_user(_control, control, sizeof(*control)))
result = -EFAULT;
@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
struct snd_ctl_elem_value __user *_control)
{
struct snd_ctl_elem_value *control;
struct snd_card *card;
int result;
control = kmalloc(sizeof(*control), GFP_KERNEL);
@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
kfree(control);
return -EFAULT;
}
result = snd_ctl_elem_write(file->card, file, control);
card = file->card;
snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
if (result >= 0)
result = snd_ctl_elem_write(card, file, control);
snd_power_unlock(card);
if (result >= 0)
if (copy_to_user(_control, control, sizeof(*control)))
result = -EFAULT;

View File

@ -107,7 +107,13 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
*/
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
goto error;
err = snd_ctl_elem_info(ctl, data);
snd_power_lock(ctl->card);
err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
if (err >= 0)
err = snd_ctl_elem_info(ctl, data);
snd_power_unlock(ctl->card);
if (err < 0)
goto error;
/* restore info to 32bit */
@ -286,9 +292,14 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
goto error;
if ((err = snd_ctl_elem_read(card, data)) < 0)
goto error;
err = copy_ctl_value_to_user(data32, data, type, count);
snd_power_lock(card);
err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
if (err >= 0)
err = snd_ctl_elem_read(card, data);
snd_power_unlock(card);
if (err >= 0)
err = copy_ctl_value_to_user(data32, data, type, count);
error:
kfree(data);
return err;
@ -298,17 +309,23 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
struct snd_ctl_elem_value32 __user *data32)
{
struct snd_ctl_elem_value *data;
struct snd_card *card = file->card;
int err, type, count;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if ((err = copy_ctl_value_from_user(file->card, data, data32, &type, &count)) < 0)
if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
goto error;
if ((err = snd_ctl_elem_write(file->card, file, data)) < 0)
goto error;
err = copy_ctl_value_to_user(data32, data, type, count);
snd_power_lock(card);
err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
if (err >= 0)
err = snd_ctl_elem_write(card, file, data);
snd_power_unlock(card);
if (err >= 0)
err = copy_ctl_value_to_user(data32, data, type, count);
error:
kfree(data);
return err;

View File

@ -25,6 +25,7 @@
#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/minors.h>
@ -36,7 +37,7 @@ MODULE_DESCRIPTION("Hardware dependent layer");
MODULE_LICENSE("GPL");
static LIST_HEAD(snd_hwdep_devices);
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
static int snd_hwdep_free(struct snd_hwdep *hwdep);
static int snd_hwdep_dev_free(struct snd_device *device);
@ -111,7 +112,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
init_waitqueue_entry(&wait, current);
add_wait_queue(&hw->open_wait, &wait);
down(&hw->open_mutex);
mutex_lock(&hw->open_mutex);
while (1) {
if (hw->exclusive && hw->used > 0) {
err = -EBUSY;
@ -128,9 +129,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
} else
break;
set_current_state(TASK_INTERRUPTIBLE);
up(&hw->open_mutex);
mutex_unlock(&hw->open_mutex);
schedule();
down(&hw->open_mutex);
mutex_lock(&hw->open_mutex);
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
@ -147,7 +148,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
hw->ops.release(hw, file);
}
}
up(&hw->open_mutex);
mutex_unlock(&hw->open_mutex);
if (err < 0)
module_put(hw->card->module);
return err;
@ -157,7 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
{
int err = -ENXIO;
struct snd_hwdep *hw = file->private_data;
down(&hw->open_mutex);
mutex_lock(&hw->open_mutex);
if (hw->ops.release) {
err = hw->ops.release(hw, file);
wake_up(&hw->open_wait);
@ -165,7 +166,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
if (hw->used > 0)
hw->used--;
snd_card_file_remove(hw->card, file);
up(&hw->open_mutex);
mutex_unlock(&hw->open_mutex);
module_put(hw->card->module);
return err;
}
@ -272,7 +273,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
if (get_user(device, (int __user *)arg))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_MINOR_HWDEPS) {
if (snd_hwdep_search(card, device))
@ -281,7 +282,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
}
if (device >= SNDRV_MINOR_HWDEPS)
device = -1;
up(&register_mutex);
mutex_unlock(&register_mutex);
if (put_user(device, (int __user *)arg))
return -EFAULT;
return 0;
@ -294,13 +295,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
if (get_user(device, &info->device))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
hwdep = snd_hwdep_search(card, device);
if (hwdep)
err = snd_hwdep_info(hwdep, info);
else
err = -ENXIO;
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
}
@ -375,7 +376,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
return err;
}
init_waitqueue_head(&hwdep->open_wait);
init_MUTEX(&hwdep->open_mutex);
mutex_init(&hwdep->open_mutex);
*rhwdep = hwdep;
return 0;
}
@ -401,9 +402,9 @@ static int snd_hwdep_dev_register(struct snd_device *device)
int err;
char name[32];
down(&register_mutex);
mutex_lock(&register_mutex);
if (snd_hwdep_search(hwdep->card, hwdep->device)) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY;
}
list_add_tail(&hwdep->list, &snd_hwdep_devices);
@ -414,7 +415,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
hwdep->card->number, hwdep->device);
list_del(&hwdep->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
#ifdef CONFIG_SND_OSSEMUL
@ -434,7 +435,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
}
}
#endif
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -443,9 +444,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
struct snd_hwdep *hwdep = device->device_data;
snd_assert(hwdep != NULL, return -ENXIO);
down(&register_mutex);
mutex_lock(&register_mutex);
if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EINVAL;
}
#ifdef CONFIG_SND_OSSEMUL
@ -454,7 +455,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
#endif
snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
list_del(&hwdep->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return snd_hwdep_free(hwdep);
}
@ -469,13 +470,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
struct list_head *p;
struct snd_hwdep *hwdep;
down(&register_mutex);
mutex_lock(&register_mutex);
list_for_each(p, &snd_hwdep_devices) {
hwdep = list_entry(p, struct snd_hwdep, list);
snd_iprintf(buffer, "%02i-%02i: %s\n",
hwdep->card->number, hwdep->device, hwdep->name);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
}
static struct snd_info_entry *snd_hwdep_proc_entry;

View File

@ -31,6 +31,7 @@
#include <sound/version.h>
#include <linux/proc_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/mutex.h>
#include <stdarg.h>
/*
@ -68,7 +69,7 @@ int snd_info_check_reserved_words(const char *str)
return 1;
}
static DECLARE_MUTEX(info_mutex);
static DEFINE_MUTEX(info_mutex);
struct snd_info_private_data {
struct snd_info_buffer *rbuffer;
@ -265,11 +266,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
struct proc_dir_entry *p;
int mode, err;
down(&info_mutex);
mutex_lock(&info_mutex);
p = PDE(inode);
entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
if (entry == NULL || entry->disconnected) {
up(&info_mutex);
mutex_unlock(&info_mutex);
return -ENODEV;
}
if (!try_module_get(entry->module)) {
@ -361,13 +362,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
break;
}
file->private_data = data;
up(&info_mutex);
mutex_unlock(&info_mutex);
if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
(mode == O_RDONLY || mode == O_RDWR)) {
if (entry->c.text.read) {
down(&entry->access);
mutex_lock(&entry->access);
entry->c.text.read(entry, data->rbuffer);
up(&entry->access);
mutex_unlock(&entry->access);
}
}
return 0;
@ -375,7 +376,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
__error:
module_put(entry->module);
__error1:
up(&info_mutex);
mutex_unlock(&info_mutex);
return err;
}
@ -747,7 +748,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name)
}
entry->mode = S_IFREG | S_IRUGO;
entry->content = SNDRV_INFO_CONTENT_TEXT;
init_MUTEX(&entry->access);
mutex_init(&entry->access);
return entry;
}
@ -896,10 +897,10 @@ int snd_info_register(struct snd_info_entry * entry)
snd_assert(entry != NULL, return -ENXIO);
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
down(&info_mutex);
mutex_lock(&info_mutex);
p = snd_create_proc_entry(entry->name, entry->mode, root);
if (!p) {
up(&info_mutex);
mutex_unlock(&info_mutex);
return -ENOMEM;
}
p->owner = entry->module;
@ -908,7 +909,7 @@ int snd_info_register(struct snd_info_entry * entry)
p->size = entry->size;
p->data = entry;
entry->p = p;
up(&info_mutex);
mutex_unlock(&info_mutex);
return 0;
}
@ -929,9 +930,9 @@ int snd_info_unregister(struct snd_info_entry * entry)
snd_assert(entry->p != NULL, return -ENXIO);
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
snd_assert(root, return -ENXIO);
down(&info_mutex);
mutex_lock(&info_mutex);
snd_remove_proc_entry(root, entry->p);
up(&info_mutex);
mutex_unlock(&info_mutex);
snd_info_free_entry(entry);
return 0;
}

View File

@ -28,6 +28,7 @@
#include <sound/info.h>
#include <sound/version.h>
#include <linux/utsname.h>
#include <linux/mutex.h>
#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
@ -35,7 +36,7 @@
* OSS compatible part
*/
static DECLARE_MUTEX(strings);
static DEFINE_MUTEX(strings);
static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT];
static struct snd_info_entry *snd_sndstat_proc_entry;
@ -45,7 +46,7 @@ int snd_oss_info_register(int dev, int num, char *string)
snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO);
snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO);
down(&strings);
mutex_lock(&strings);
if (string == NULL) {
if ((x = snd_sndstat_strings[num][dev]) != NULL) {
kfree(x);
@ -54,12 +55,12 @@ int snd_oss_info_register(int dev, int num, char *string)
} else {
x = kstrdup(string, GFP_KERNEL);
if (x == NULL) {
up(&strings);
mutex_unlock(&strings);
return -ENOMEM;
}
}
snd_sndstat_strings[num][dev] = x;
up(&strings);
mutex_unlock(&strings);
return 0;
}
@ -71,7 +72,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
char *str;
snd_iprintf(buf, "\n%s:", id);
down(&strings);
mutex_lock(&strings);
for (idx = 0; idx < SNDRV_CARDS; idx++) {
str = snd_sndstat_strings[idx][dev];
if (str) {
@ -82,7 +83,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
snd_iprintf(buf, "%i: %s\n", idx, str);
}
}
up(&strings);
mutex_unlock(&strings);
if (ok < 0)
snd_iprintf(buf, " NOT ENABLED IN CONFIG\n");
return ok;

View File

@ -145,7 +145,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
init_waitqueue_head(&card->shutdown_sleep);
INIT_WORK(&card->free_workq, snd_card_free_thread, card);
#ifdef CONFIG_PM
init_MUTEX(&card->power_lock);
mutex_init(&card->power_lock);
init_waitqueue_head(&card->power_sleep);
#endif
/* the control interface cannot be accessed from the user space until */
@ -169,11 +169,44 @@ struct snd_card *snd_card_new(int idx, const char *xid,
return NULL;
}
static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
{
return -ENODEV;
}
static ssize_t snd_disconnect_read(struct file *file, char __user *buf,
size_t count, loff_t *offset)
{
return -ENODEV;
}
static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{
return -ENODEV;
}
static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
{
return POLLERR | POLLNVAL;
}
static long snd_disconnect_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
return -ENODEV;
}
static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
{
return -ENODEV;
}
static int snd_disconnect_fasync(int fd, struct file *file, int on)
{
return -ENODEV;
}
/**
* snd_card_disconnect - disconnect all APIs from the file-operations (user space)
* @card: soundcard structure
@ -224,7 +257,16 @@ int snd_card_disconnect(struct snd_card *card)
memset(f_ops, 0, sizeof(*f_ops));
f_ops->owner = file->f_op->owner;
f_ops->release = file->f_op->release;
f_ops->llseek = snd_disconnect_llseek;
f_ops->read = snd_disconnect_read;
f_ops->write = snd_disconnect_write;
f_ops->poll = snd_disconnect_poll;
f_ops->unlocked_ioctl = snd_disconnect_ioctl;
#ifdef CONFIG_COMPAT
f_ops->compat_ioctl = snd_disconnect_ioctl;
#endif
f_ops->mmap = snd_disconnect_mmap;
f_ops->fasync = snd_disconnect_fasync;
s_f_ops->next = card->s_f_ops;
card->s_f_ops = s_f_ops;

View File

@ -31,7 +31,7 @@
#include <asm/uaccess.h>
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#include <asm/semaphore.h>
#include <linux/mutex.h>
#include <sound/memalloc.h>
#ifdef CONFIG_SBUS
#include <asm/sbus.h>
@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
/*
*/
static DECLARE_MUTEX(list_mutex);
static DEFINE_MUTEX(list_mutex);
static LIST_HEAD(mem_list_head);
/* buffer preservation list */
@ -83,7 +83,7 @@ struct snd_mem_list {
* Hacks
*/
#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
#if defined(__i386__)
/*
* A hack to allocate large buffers via dma_alloc_coherent()
*
@ -141,10 +141,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
#endif /* arch */
#if ! defined(__arm__)
#define NEED_RESERVE_PAGES
#endif
/*
*
* Generic memory allocators
@ -163,20 +159,6 @@ static inline void dec_snd_pages(int order)
snd_allocated_pages -= 1 << order;
}
static void mark_pages(struct page *page, int order)
{
struct page *last_page = page + (1 << order);
while (page < last_page)
SetPageReserved(page++);
}
static void unmark_pages(struct page *page, int order)
{
struct page *last_page = page + (1 << order);
while (page < last_page)
ClearPageReserved(page++);
}
/**
* snd_malloc_pages - allocate pages with the given size
* @size: the size to allocate in bytes
@ -195,10 +177,8 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
snd_assert(gfp_flags != 0, return NULL);
gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
pg = get_order(size);
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
mark_pages(virt_to_page(res), pg);
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
inc_snd_pages(pg);
}
return res;
}
@ -217,7 +197,6 @@ void snd_free_pages(void *ptr, size_t size)
return;
pg = get_order(size);
dec_snd_pages(pg);
unmark_pages(virt_to_page(ptr), pg);
free_pages((unsigned long) ptr, pg);
}
@ -242,12 +221,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
| __GFP_NORETRY /* don't trigger OOM-killer */
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
if (res != NULL) {
#ifdef NEED_RESERVE_PAGES
mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */
#endif
if (res != NULL)
inc_snd_pages(pg);
}
return res;
}
@ -262,9 +237,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
return;
pg = get_order(size);
dec_snd_pages(pg);
#ifdef NEED_RESERVE_PAGES
unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */
#endif
dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
}
@ -440,7 +412,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
snd_assert(dmab, return 0);
down(&list_mutex);
mutex_lock(&list_mutex);
list_for_each(p, &mem_list_head) {
mem = list_entry(p, struct snd_mem_list, list);
if (mem->id == id &&
@ -452,11 +424,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
if (dmab->dev.dev == NULL)
dmab->dev.dev = dev;
kfree(mem);
up(&list_mutex);
mutex_unlock(&list_mutex);
return dmab->bytes;
}
}
up(&list_mutex);
mutex_unlock(&list_mutex);
return 0;
}
@ -477,11 +449,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
mem = kmalloc(sizeof(*mem), GFP_KERNEL);
if (! mem)
return -ENOMEM;
down(&list_mutex);
mutex_lock(&list_mutex);
mem->buffer = *dmab;
mem->id = id;
list_add_tail(&mem->list, &mem_list_head);
up(&list_mutex);
mutex_unlock(&list_mutex);
return 0;
}
@ -493,7 +465,7 @@ static void free_all_reserved_pages(void)
struct list_head *p;
struct snd_mem_list *mem;
down(&list_mutex);
mutex_lock(&list_mutex);
while (! list_empty(&mem_list_head)) {
p = mem_list_head.next;
mem = list_entry(p, struct snd_mem_list, list);
@ -501,7 +473,7 @@ static void free_all_reserved_pages(void)
snd_dma_free_pages(&mem->buffer);
kfree(mem);
}
up(&list_mutex);
mutex_unlock(&list_mutex);
}
@ -522,7 +494,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
int devno;
static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
down(&list_mutex);
mutex_lock(&list_mutex);
len += snprintf(page + len, count - len,
"pages : %li bytes (%li pages per %likB)\n",
pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
@ -537,7 +509,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
" addr = 0x%lx, size = %d bytes\n",
(unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
}
up(&list_mutex);
mutex_unlock(&list_mutex);
return len;
}

View File

@ -20,6 +20,9 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -85,3 +88,5 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -20,6 +20,9 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -132,3 +135,5 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -21,6 +21,9 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -103,7 +106,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
return frames;
}
int conv_index(int src_format, int dst_format)
static int conv_index(int src_format, int dst_format)
{
int src_endian, dst_endian, sign, src_width, dst_width;
@ -156,3 +159,5 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
struct snd_mixer_oss *mixer = entry->private_data;
int i;
down(&mixer->reg_mutex);
mutex_lock(&mixer->reg_mutex);
for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) {
struct slot *p;
@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
else
snd_iprintf(buffer, "\"\" 0\n");
}
up(&mixer->reg_mutex);
mutex_unlock(&mixer->reg_mutex);
}
static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
@ -1134,9 +1134,9 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
cptr = snd_info_get_str(str, cptr, sizeof(str));
if (! *str) {
/* remove the entry */
down(&mixer->reg_mutex);
mutex_lock(&mixer->reg_mutex);
mixer_slot_clear(&mixer->slots[ch]);
up(&mixer->reg_mutex);
mutex_unlock(&mixer->reg_mutex);
continue;
}
snd_info_get_str(idxstr, cptr, sizeof(idxstr));
@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx);
continue;
}
down(&mixer->reg_mutex);
mutex_lock(&mixer->reg_mutex);
slot = (struct slot *)mixer->slots[ch].private_data;
if (slot && slot->assigned &&
slot->assigned->index == idx && ! strcmp(slot->assigned->name, str))
@ -1168,7 +1168,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
kfree(tbl);
}
__unlock:
up(&mixer->reg_mutex);
mutex_unlock(&mixer->reg_mutex);
}
}
@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL);
if (mixer == NULL)
return -ENOMEM;
init_MUTEX(&mixer->reg_mutex);
mutex_init(&mixer->reg_mutex);
sprintf(name, "mixer%i%i", card->number, 0);
if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
card, 0,

View File

@ -22,6 +22,9 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -262,6 +265,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
return frames;
}
static int getput_index(int format)
{
int sign, width, endian;
sign = !snd_pcm_format_signed(format);
width = snd_pcm_format_width(format) / 8 - 1;
if (width < 0 || width > 3) {
snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
width = 0;
}
#ifdef SNDRV_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(format);
#else
endian = snd_pcm_format_little_endian(format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
}
int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
struct snd_pcm_plugin_format *src_format,
struct snd_pcm_plugin_format *dst_format,
@ -306,3 +328,5 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -78,6 +78,7 @@ static inline void snd_leave_user(mm_segment_t fs)
set_fs(fs);
}
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@ -122,6 +123,7 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
}
return 0;
}
#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
{
@ -412,6 +414,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
params_channels(params) / 8;
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
snd_pcm_oss_plugin_clear(substream);
if (!direct) {
/* add necessary plugins */
@ -441,6 +444,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
}
}
}
#endif
err = snd_pcm_oss_period_size(substream, params, sparams);
if (err < 0)
@ -498,11 +502,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
runtime->oss.periods = params_periods(sparams);
oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure);
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
if (runtime->oss.plugin_first) {
err = snd_pcm_plug_alloc(substream, oss_period_size);
if (err < 0)
goto failure;
}
#endif
oss_period_size *= oss_frame_size;
oss_buffer_size = oss_period_size * runtime->oss.periods;
@ -784,6 +790,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t frames, frames1;
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
if (runtime->oss.plugin_first) {
struct snd_pcm_plugin_channel *channels;
size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
@ -800,7 +807,9 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
if (frames1 <= 0)
return frames1;
bytes = frames1 * oss_frame_bytes;
} else {
} else
#endif
{
frames = bytes_to_frames(runtime, bytes);
frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
if (frames1 <= 0)
@ -871,6 +880,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t frames, frames1;
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
char __user *final_dst = (char __user *)buf;
if (runtime->oss.plugin_first) {
struct snd_pcm_plugin_channel *channels;
@ -887,7 +897,9 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
bytes = frames1 * oss_frame_bytes;
if (!in_kernel && copy_to_user(final_dst, buf, bytes))
return -EFAULT;
} else {
} else
#endif
{
frames = bytes_to_frames(runtime, bytes);
frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel);
if (frames1 <= 0)
@ -1631,10 +1643,10 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
const char *ptr, *ptrl;
struct snd_pcm_oss_setup *setup;
down(&pcm->streams[stream].oss.setup_mutex);
mutex_lock(&pcm->streams[stream].oss.setup_mutex);
for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
if (!strcmp(setup->task_name, task_name)) {
up(&pcm->streams[stream].oss.setup_mutex);
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
return setup;
}
}
@ -1650,12 +1662,12 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
}
for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
if (!strcmp(setup->task_name, ptrl)) {
up(&pcm->streams[stream].oss.setup_mutex);
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
return setup;
}
}
__not_found:
up(&pcm->streams[stream].oss.setup_mutex);
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
return NULL;
}
@ -1692,7 +1704,9 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime;
runtime = substream->runtime;
vfree(runtime->oss.buffer);
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
snd_pcm_oss_plugin_clear(substream);
#endif
substream->oss.file = NULL;
substream->oss.oss = 0;
}
@ -1881,7 +1895,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
init_waitqueue_entry(&wait, current);
add_wait_queue(&pcm->open_wait, &wait);
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
while (1) {
err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
iminor(inode), psetup, csetup);
@ -1895,16 +1909,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
} else
break;
set_current_state(TASK_INTERRUPTIBLE);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
schedule();
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
}
}
remove_wait_queue(&pcm->open_wait, &wait);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
if (err < 0)
goto __error;
return err;
@ -1930,9 +1944,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
snd_assert(substream != NULL, return -ENXIO);
pcm = substream->pcm;
snd_pcm_oss_sync(pcm_oss_file);
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
snd_pcm_oss_release_file(pcm_oss_file);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
wake_up(&pcm->open_wait);
module_put(pcm->card->module);
snd_card_file_remove(pcm->card, file);
@ -2246,8 +2260,10 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
if ((err = snd_pcm_oss_change_params(substream)) < 0)
return err;
}
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
if (runtime->oss.plugin_first != NULL)
return -EIO;
#endif
if (area->vm_pgoff != 0)
return -EINVAL;
@ -2277,7 +2293,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
{
struct snd_pcm_str *pstr = entry->private_data;
struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
down(&pstr->oss.setup_mutex);
mutex_lock(&pstr->oss.setup_mutex);
while (setup) {
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
setup->task_name,
@ -2291,7 +2307,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
setup->nosilence ? " no-silence" : "");
setup = setup->next;
}
up(&pstr->oss.setup_mutex);
mutex_unlock(&pstr->oss.setup_mutex);
}
static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
@ -2321,12 +2337,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
struct snd_pcm_oss_setup *setup, *setup1, template;
while (!snd_info_get_line(buffer, line, sizeof(line))) {
down(&pstr->oss.setup_mutex);
mutex_lock(&pstr->oss.setup_mutex);
memset(&template, 0, sizeof(template));
ptr = snd_info_get_str(task_name, line, sizeof(task_name));
if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
snd_pcm_oss_proc_free_setup_list(pstr);
up(&pstr->oss.setup_mutex);
mutex_unlock(&pstr->oss.setup_mutex);
continue;
}
for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
@ -2378,7 +2394,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
}
if (setup)
*setup = template;
up(&pstr->oss.setup_mutex);
mutex_unlock(&pstr->oss.setup_mutex);
}
}

View File

@ -25,6 +25,9 @@
#endif
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
@ -36,26 +39,6 @@
#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin,
unsigned long *dst_vmask,
unsigned long **src_vmask)
{
unsigned long *vmask = plugin->src_vmask;
bitmap_copy(vmask, dst_vmask, plugin->src_format.channels);
*src_vmask = vmask;
return 0;
}
static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin,
unsigned long *src_vmask,
unsigned long **dst_vmask)
{
unsigned long *vmask = plugin->dst_vmask;
bitmap_copy(vmask, src_vmask, plugin->dst_format.channels);
*dst_vmask = vmask;
return 0;
}
/*
* because some cards might have rates "very close", we ignore
* all "resampling" requests within +-5%
@ -193,19 +176,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
snd_pcm_plugin_free(plugin);
return -ENOMEM;
}
plugin->src_vmask = bitmap_alloc(src_format->channels);
if (plugin->src_vmask == NULL) {
snd_pcm_plugin_free(plugin);
return -ENOMEM;
}
plugin->dst_vmask = bitmap_alloc(dst_format->channels);
if (plugin->dst_vmask == NULL) {
snd_pcm_plugin_free(plugin);
return -ENOMEM;
}
plugin->client_channels = snd_pcm_plugin_client_channels;
plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask;
plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask;
*ret = plugin;
return 0;
}
@ -218,8 +189,6 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
plugin->private_free(plugin);
kfree(plugin->buf_channels);
vfree(plugin->buf);
kfree(plugin->src_vmask);
kfree(plugin->dst_vmask);
kfree(plugin);
return 0;
}
@ -429,24 +398,14 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
dstformat.channels);
/* Format change (linearization) */
if ((srcformat.format != dstformat.format ||
!rate_match(srcformat.rate, dstformat.rate) ||
srcformat.channels != dstformat.channels) &&
!snd_pcm_format_linear(srcformat.format)) {
if (snd_pcm_format_linear(dstformat.format))
tmpformat.format = dstformat.format;
else
tmpformat.format = SNDRV_PCM_FORMAT_S16;
switch (srcformat.format) {
case SNDRV_PCM_FORMAT_MU_LAW:
err = snd_pcm_plugin_build_mulaw(plug,
&srcformat, &tmpformat,
&plugin);
break;
default:
if (! rate_match(srcformat.rate, dstformat.rate) &&
! snd_pcm_format_linear(srcformat.format)) {
if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW)
return -EINVAL;
}
pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err);
tmpformat.format = SNDRV_PCM_FORMAT_S16;
err = snd_pcm_plugin_build_mulaw(plug,
&srcformat, &tmpformat,
&plugin);
if (err < 0)
return err;
err = snd_pcm_plugin_append(plugin);
@ -460,35 +419,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
/* channels reduction */
if (srcformat.channels > dstformat.channels) {
int sv = srcformat.channels;
int dv = dstformat.channels;
int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
if (ttable == NULL)
return -ENOMEM;
#if 1
if (sv == 2 && dv == 1) {
ttable[0] = HALF;
ttable[1] = HALF;
} else
#endif
{
int v;
for (v = 0; v < dv; ++v)
ttable[v * sv + v] = FULL;
}
tmpformat.channels = dstformat.channels;
if (rate_match(srcformat.rate, dstformat.rate) &&
snd_pcm_format_linear(dstformat.format))
tmpformat.format = dstformat.format;
err = snd_pcm_plugin_build_route(plug,
&srcformat, &tmpformat,
ttable, &plugin);
kfree(ttable);
err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
if (err < 0) {
snd_pcm_plugin_free(plugin);
if (err < 0)
return err;
}
err = snd_pcm_plugin_append(plugin);
if (err < 0) {
snd_pcm_plugin_free(plugin);
@ -500,18 +435,29 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
/* rate resampling */
if (!rate_match(srcformat.rate, dstformat.rate)) {
if (srcformat.format != SNDRV_PCM_FORMAT_S16) {
/* convert to S16 for resampling */
tmpformat.format = SNDRV_PCM_FORMAT_S16;
err = snd_pcm_plugin_build_linear(plug,
&srcformat, &tmpformat,
&plugin);
if (err < 0)
return err;
err = snd_pcm_plugin_append(plugin);
if (err < 0) {
snd_pcm_plugin_free(plugin);
return err;
}
srcformat = tmpformat;
src_access = dst_access;
}
tmpformat.rate = dstformat.rate;
if (srcformat.channels == dstformat.channels &&
snd_pcm_format_linear(dstformat.format))
tmpformat.format = dstformat.format;
err = snd_pcm_plugin_build_rate(plug,
&srcformat, &tmpformat,
&plugin);
pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err);
if (err < 0) {
snd_pcm_plugin_free(plugin);
if (err < 0)
return err;
}
err = snd_pcm_plugin_append(plugin);
if (err < 0) {
snd_pcm_plugin_free(plugin);
@ -521,56 +467,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
src_access = dst_access;
}
/* channels extension */
if (srcformat.channels < dstformat.channels) {
int sv = srcformat.channels;
int dv = dstformat.channels;
int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
if (ttable == NULL)
return -ENOMEM;
#if 0
{
int v;
for (v = 0; v < sv; ++v)
ttable[v * sv + v] = FULL;
}
#else
{
/* Playback is spreaded on all channels */
int vd, vs;
for (vd = 0, vs = 0; vd < dv; ++vd) {
ttable[vd * sv + vs] = FULL;
vs++;
if (vs == sv)
vs = 0;
}
}
#endif
tmpformat.channels = dstformat.channels;
if (snd_pcm_format_linear(dstformat.format))
tmpformat.format = dstformat.format;
err = snd_pcm_plugin_build_route(plug,
&srcformat, &tmpformat,
ttable, &plugin);
kfree(ttable);
pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
if (err < 0) {
snd_pcm_plugin_free(plugin);
return err;
}
err = snd_pcm_plugin_append(plugin);
if (err < 0) {
snd_pcm_plugin_free(plugin);
return err;
}
srcformat = tmpformat;
src_access = dst_access;
}
/* format change */
if (srcformat.format != dstformat.format) {
tmpformat.format = dstformat.format;
if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW ||
tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
err = snd_pcm_plugin_build_mulaw(plug,
&srcformat, &tmpformat,
&plugin);
@ -595,6 +496,22 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
src_access = dst_access;
}
/* channels extension */
if (srcformat.channels < dstformat.channels) {
tmpformat.channels = dstformat.channels;
err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
if (err < 0)
return err;
err = snd_pcm_plugin_append(plugin);
if (err < 0) {
snd_pcm_plugin_free(plugin);
return err;
}
srcformat = tmpformat;
src_access = dst_access;
}
/* de-interleave */
if (src_access != dst_access) {
err = snd_pcm_plugin_build_copy(plug,
@ -650,92 +567,6 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
return count;
}
static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug,
unsigned long *client_vmask)
{
struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
if (plugin == NULL) {
return 0;
} else {
int schannels = plugin->dst_format.channels;
DECLARE_BITMAP(bs, schannels);
unsigned long *srcmask;
unsigned long *dstmask = bs;
int err;
bitmap_fill(dstmask, schannels);
while (1) {
err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
if (err < 0)
return err;
dstmask = srcmask;
if (plugin->prev == NULL)
break;
plugin = plugin->prev;
}
bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels);
return 0;
}
}
static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug,
struct snd_pcm_plugin_channel *src_channels)
{
struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
unsigned int nchannels = plugin->src_format.channels;
DECLARE_BITMAP(bs, nchannels);
unsigned long *srcmask = bs;
int err;
unsigned int channel;
for (channel = 0; channel < nchannels; channel++) {
if (src_channels[channel].enabled)
set_bit(channel, srcmask);
else
clear_bit(channel, srcmask);
}
err = snd_pcm_plug_playback_channels_mask(plug, srcmask);
if (err < 0)
return err;
for (channel = 0; channel < nchannels; channel++) {
if (!test_bit(channel, srcmask))
src_channels[channel].enabled = 0;
}
return 0;
}
static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug,
struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *client_channels)
{
struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
unsigned int nchannels = plugin->dst_format.channels;
DECLARE_BITMAP(bs, nchannels);
unsigned long *dstmask = bs;
unsigned long *srcmask;
int err;
unsigned int channel;
for (channel = 0; channel < nchannels; channel++) {
if (client_channels[channel].enabled)
set_bit(channel, dstmask);
else
clear_bit(channel, dstmask);
}
while (plugin) {
err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
if (err < 0)
return err;
dstmask = srcmask;
plugin = plugin->prev;
}
plugin = snd_pcm_plug_first(plug);
nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; channel++) {
if (!test_bit(channel, dstmask))
src_channels[channel].enabled = 0;
}
return 0;
}
snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
{
struct snd_pcm_plugin *plugin, *next;
@ -743,9 +574,6 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
int err;
snd_pcm_sframes_t frames = size;
if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0)
return err;
plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
if ((next = plugin->next) != NULL) {
@ -790,10 +618,6 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
return err;
}
frames = err;
if (!plugin->prev) {
if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0)
return err;
}
} else {
dst_channels = dst_channels_final;
}
@ -916,3 +740,5 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of
}
return 0;
}
#endif

View File

@ -22,12 +22,7 @@
*
*/
#include <linux/bitmap.h>
static inline unsigned long *bitmap_alloc(unsigned int nbits)
{
return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL);
}
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#define snd_pcm_plug_stream(plug) ((plug)->stream)
@ -69,12 +64,6 @@ struct snd_pcm_plugin {
snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
snd_pcm_uframes_t frames,
struct snd_pcm_plugin_channel **channels);
int (*src_channels_mask)(struct snd_pcm_plugin *plugin,
unsigned long *dst_vmask,
unsigned long **src_vmask);
int (*dst_channels_mask)(struct snd_pcm_plugin *plugin,
unsigned long *src_vmask,
unsigned long **dst_vmask);
snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
@ -90,8 +79,6 @@ struct snd_pcm_plugin {
char *buf;
snd_pcm_uframes_t buf_frames;
struct snd_pcm_plugin_channel *buf_channels;
unsigned long *src_vmask;
unsigned long *dst_vmask;
char extra_data[0];
};
@ -128,7 +115,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
struct snd_pcm_plugin_format *src_format,
struct snd_pcm_plugin_format *dst_format,
int *ttable,
struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
struct snd_pcm_plugin_format *src_format,
@ -181,15 +167,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
void **bufs, snd_pcm_uframes_t frames,
int in_kernel);
#define ROUTE_PLUGIN_RESOLUTION 16
#else
int getput_index(int format);
int copy_index(int format);
int conv_index(int src_format, int dst_format);
static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; }
void zero_channel(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *dst_channel,
size_t samples);
#endif
#ifdef PLUGIN_DEBUG
#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args)

View File

@ -362,172 +362,6 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_
}
#endif
#if 0
#ifdef GET32_LABELS
/* src_wid src_endswap unsigned */
static void *get32_labels[4 * 2 * 2] = {
&&get32_xxx1_1000, /* 8h -> 32h */
&&get32_xxx1_9000, /* 8h ^> 32h */
&&get32_xxx1_1000, /* 8s -> 32h */
&&get32_xxx1_9000, /* 8s ^> 32h */
&&get32_xx12_1200, /* 16h -> 32h */
&&get32_xx12_9200, /* 16h ^> 32h */
&&get32_xx12_2100, /* 16s -> 32h */
&&get32_xx12_A100, /* 16s ^> 32h */
&&get32_x123_1230, /* 24h -> 32h */
&&get32_x123_9230, /* 24h ^> 32h */
&&get32_123x_3210, /* 24s -> 32h */
&&get32_123x_B210, /* 24s ^> 32h */
&&get32_1234_1234, /* 32h -> 32h */
&&get32_1234_9234, /* 32h ^> 32h */
&&get32_1234_4321, /* 32s -> 32h */
&&get32_1234_C321, /* 32s ^> 32h */
};
#endif
#ifdef GET32_END
while (0) {
get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END;
get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END;
get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END;
get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END;
get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END;
get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END;
get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END;
get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END;
get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END;
get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END;
get32_1234_1234: sample = as_u32(src); goto GET32_END;
get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END;
get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END;
get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END;
}
#endif
#endif
#ifdef PUT_U32_LABELS
/* dst_wid dst_endswap unsigned */
static void *put_u32_labels[4 * 2 * 2] = {
&&put_u32_1234_xxx9, /* u32h -> s8h */
&&put_u32_1234_xxx1, /* u32h -> u8h */
&&put_u32_1234_xxx9, /* u32h -> s8s */
&&put_u32_1234_xxx1, /* u32h -> u8s */
&&put_u32_1234_xx92, /* u32h -> s16h */
&&put_u32_1234_xx12, /* u32h -> u16h */
&&put_u32_1234_xx29, /* u32h -> s16s */
&&put_u32_1234_xx21, /* u32h -> u16s */
&&put_u32_1234_x923, /* u32h -> s24h */
&&put_u32_1234_x123, /* u32h -> u24h */
&&put_u32_1234_329x, /* u32h -> s24s */
&&put_u32_1234_321x, /* u32h -> u24s */
&&put_u32_1234_9234, /* u32h -> s32h */
&&put_u32_1234_1234, /* u32h -> u32h */
&&put_u32_1234_4329, /* u32h -> s32s */
&&put_u32_1234_4321, /* u32h -> u32s */
};
#endif
#ifdef PUT_U32_END
while (0) {
put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END;
put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END;
put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END;
put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END;
put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END;
put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END;
put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END;
put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END;
put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END;
put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END;
put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END;
put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END;
put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END;
put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END;
}
#endif
#ifdef GET_U_LABELS
/* width endswap unsigned*/
static void *get_u_labels[4 * 2 * 2] = {
&&get_u_s8, /* s8 -> u8 */
&&get_u_u8, /* u8 -> u8 */
&&get_u_s8, /* s8 -> u8 */
&&get_u_u8, /* u8 -> u8 */
&&get_u_s16h, /* s16h -> u16h */
&&get_u_u16h, /* u16h -> u16h */
&&get_u_s16s, /* s16s -> u16h */
&&get_u_u16s, /* u16s -> u16h */
&&get_u_s24h, /* s24h -> u32h */
&&get_u_u24h, /* u24h -> u32h */
&&get_u_s24s, /* s24s -> u32h */
&&get_u_u24s, /* u24s -> u32h */
&&get_u_s32h, /* s32h -> u32h */
&&get_u_u32h, /* u32h -> u32h */
&&get_u_s32s, /* s32s -> u32h */
&&get_u_u32s, /* u32s -> u32h */
};
#endif
#ifdef GET_U_END
while (0) {
get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END;
get_u_u8: sample = as_u8(src); goto GET_U_END;
get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END;
get_u_u16h: sample = as_u16(src); goto GET_U_END;
get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END;
get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END;
get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END;
get_u_u24h: sample = as_u32(src); goto GET_U_END;
get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END;
get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END;
get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END;
get_u_u32h: sample = as_u32(src); goto GET_U_END;
get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END;
get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END;
}
#endif
#if 0
#ifdef PUT_LABELS
/* width endswap unsigned */
static void *put_labels[4 * 2 * 2] = {
&&put_s8, /* s8 -> s8 */
&&put_u8, /* u8 -> s8 */
&&put_s8, /* s8 -> s8 */
&&put_u8, /* u8 -> s8 */
&&put_s16h, /* s16h -> s16h */
&&put_u16h, /* u16h -> s16h */
&&put_s16s, /* s16s -> s16h */
&&put_u16s, /* u16s -> s16h */
&&put_s24h, /* s24h -> s32h */
&&put_u24h, /* u24h -> s32h */
&&put_s24s, /* s24s -> s32h */
&&put_u24s, /* u24s -> s32h */
&&put_s32h, /* s32h -> s32h */
&&put_u32h, /* u32h -> s32h */
&&put_s32s, /* s32s -> s32h */
&&put_u32s, /* u32s -> s32h */
};
#endif
#ifdef PUT_END
put_s8: as_s8(dst) = sample; goto PUT_END;
put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END;
put_s16h: as_s16(dst) = sample; goto PUT_END;
put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END;
put_s16s: as_s16(dst) = swab16(sample); goto PUT_END;
put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END;
put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END;
put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END;
put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END;
put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END;
put_s32h: as_s32(dst) = sample; goto PUT_END;
put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END;
put_s32s: as_s32(dst) = swab32(sample); goto PUT_END;
put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END;
#endif
#endif
#undef as_u8
#undef as_u16
#undef as_u32

View File

@ -20,6 +20,9 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -47,7 +50,6 @@ struct rate_priv {
unsigned int pitch;
unsigned int pos;
rate_f func;
int get, put;
snd_pcm_sframes_t old_src_frames, old_dst_frames;
struct rate_channel channels[0];
};
@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
unsigned int pos = 0;
signed int val;
signed short S1, S2;
char *src, *dst;
signed short *src, *dst;
unsigned int channel;
int src_step, dst_step;
int src_frames1, dst_frames1;
struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
struct rate_channel *rchannels = data->channels;
#define GET_S16_LABELS
#define PUT_S16_LABELS
#include "plugin_ops.h"
#undef GET_S16_LABELS
#undef PUT_S16_LABELS
void *get = get_s16_labels[data->get];
void *put = put_s16_labels[data->put];
signed short sample = 0;
for (channel = 0; channel < plugin->src_format.channels; channel++) {
pos = data->pos;
@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
continue;
}
dst_channels[channel].enabled = 1;
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
src = (signed short *)src_channels[channel].area.addr +
src_channels[channel].area.first / 8 / 2;
dst = (signed short *)dst_channels[channel].area.addr +
dst_channels[channel].area.first / 8 / 2;
src_step = src_channels[channel].area.step / 8 / 2;
dst_step = dst_channels[channel].area.step / 8 / 2;
src_frames1 = src_frames;
dst_frames1 = dst_frames;
while (dst_frames1-- > 0) {
@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
pos &= R_MASK;
S1 = S2;
if (src_frames1-- > 0) {
goto *get;
#define GET_S16_END after_get
#include "plugin_ops.h"
#undef GET_S16_END
after_get:
S2 = sample;
S2 = *src;
src += src_step;
}
}
@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
val = -32768;
else if (val > 32767)
val = 32767;
sample = val;
goto *put;
#define PUT_S16_END after_put
#include "plugin_ops.h"
#undef PUT_S16_END
after_put:
*dst = val;
dst += dst_step;
pos += data->pitch;
}
@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
unsigned int pos = 0;
signed int val;
signed short S1, S2;
char *src, *dst;
signed short *src, *dst;
unsigned int channel;
int src_step, dst_step;
int src_frames1, dst_frames1;
struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
struct rate_channel *rchannels = data->channels;
#define GET_S16_LABELS
#define PUT_S16_LABELS
#include "plugin_ops.h"
#undef GET_S16_LABELS
#undef PUT_S16_LABELS
void *get = get_s16_labels[data->get];
void *put = put_s16_labels[data->put];
signed short sample = 0;
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
pos = data->pos;
@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
continue;
}
dst_channels[channel].enabled = 1;
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
src = (signed short *)src_channels[channel].area.addr +
src_channels[channel].area.first / 8 / 2;
dst = (signed short *)dst_channels[channel].area.addr +
dst_channels[channel].area.first / 8 / 2;
src_step = src_channels[channel].area.step / 8 / 2;
dst_step = dst_channels[channel].area.step / 8 / 2;
src_frames1 = src_frames;
dst_frames1 = dst_frames;
while (dst_frames1 > 0) {
S1 = S2;
if (src_frames1-- > 0) {
goto *get;
#define GET_S16_END after_get
#include "plugin_ops.h"
#undef GET_S16_END
after_get:
S2 = sample;
S1 = *src;
src += src_step;
}
if (pos & ~R_MASK) {
@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
val = -32768;
else if (val > 32767)
val = 32767;
sample = val;
goto *put;
#define PUT_S16_END after_put
#include "plugin_ops.h"
#undef PUT_S16_END
after_put:
*dst = val;
dst += dst_step;
dst_frames1--;
}
@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
snd_assert(src_format->channels > 0, return -ENXIO);
snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO);
snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO);
snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
snd_assert(src_format->rate != dst_format->rate, return -ENXIO);
err = snd_pcm_plugin_build(plug, "rate conversion",
@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
if (err < 0)
return err;
data = (struct rate_priv *)plugin->extra_data;
data->get = getput_index(src_format->format);
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
data->put = getput_index(dst_format->format);
snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL);
if (src_format->rate < dst_format->rate) {
data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
data->func = resample_expand;
@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Attenuated route Plug-In
* Route Plug-In
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*
@ -20,502 +20,93 @@
*/
#include <sound/driver.h>
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
#include <linux/slab.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include "pcm_plugin.h"
/* The best possible hack to support missing optimization in gcc 2.7.2.3 */
#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0
#define div(a) a /= ROUTE_PLUGIN_RESOLUTION
#elif ROUTE_PLUGIN_RESOLUTION == 16
#define div(a) a >>= 4
#else
#error "Add some code here"
#endif
struct ttable_dst;
typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channel,
struct ttable_dst *ttable, snd_pcm_uframes_t frames);
struct ttable_src {
int channel;
int as_int;
};
struct ttable_dst {
int att; /* Attenuated */
unsigned int nsrcs;
struct ttable_src *srcs;
route_channel_f func;
};
struct route_priv {
enum {R_UINT32=0, R_UINT64=1} sum_type;
int get, put;
int conv;
int src_sample_size;
struct ttable_dst ttable[0];
};
union sum {
u_int32_t as_uint32;
u_int64_t as_uint64;
};
static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channel,
struct ttable_dst *ttable,
snd_pcm_uframes_t frames)
static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
snd_pcm_uframes_t frames, int format)
{
if (dst_channel->wanted)
snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
dst_channel->enabled = 0;
}
static void route_to_channel_from_one(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channel,
struct ttable_dst *ttable,
snd_pcm_uframes_t frames)
{
#define CONV_LABELS
#include "plugin_ops.h"
#undef CONV_LABELS
struct route_priv *data = (struct route_priv *)plugin->extra_data;
void *conv;
const struct snd_pcm_plugin_channel *src_channel = NULL;
unsigned int srcidx;
char *src, *dst;
int src_step, dst_step;
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
src_channel = &src_channels[ttable->srcs[srcidx].channel];
if (src_channel->area.addr != NULL)
break;
}
if (srcidx == ttable->nsrcs) {
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
return;
}
dst_channel->enabled = 1;
conv = conv_labels[data->conv];
src = src_channel->area.addr + src_channel->area.first / 8;
src_step = src_channel->area.step / 8;
dst = dst_channel->area.addr + dst_channel->area.first / 8;
dst_step = dst_channel->area.step / 8;
while (frames-- > 0) {
goto *conv;
#define CONV_END after
#include "plugin_ops.h"
#undef CONV_END
after:
src += src_step;
dst += dst_step;
int dst = 0;
for (; dst < ndsts; ++dst) {
if (dvp->wanted)
snd_pcm_area_silence(&dvp->area, 0, frames, format);
dvp->enabled = 0;
dvp++;
}
}
static void route_to_channel(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel,
struct snd_pcm_plugin_channel *dst_channel,
struct ttable_dst *ttable, snd_pcm_uframes_t frames)
snd_pcm_uframes_t frames, int format)
{
#define GET_U_LABELS
#define PUT_U32_LABELS
#include "plugin_ops.h"
#undef GET_U_LABELS
#undef PUT_U32_LABELS
static void *zero_labels[2] = { &&zero_int32, &&zero_int64 };
/* sum_type att */
static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att,
&&add_int64_noatt, &&add_int64_att,
};
/* sum_type att shift */
static void *norm_labels[2 * 2 * 4] = { NULL,
&&norm_int32_8_noatt,
&&norm_int32_16_noatt,
&&norm_int32_24_noatt,
NULL,
&&norm_int32_8_att,
&&norm_int32_16_att,
&&norm_int32_24_att,
&&norm_int64_0_noatt,
&&norm_int64_8_noatt,
&&norm_int64_16_noatt,
&&norm_int64_24_noatt,
&&norm_int64_0_att,
&&norm_int64_8_att,
&&norm_int64_16_att,
&&norm_int64_24_att,
};
struct route_priv *data = (struct route_priv *)plugin->extra_data;
void *zero, *get, *add, *norm, *put_u32;
int nsrcs = ttable->nsrcs;
char *dst;
int dst_step;
char *srcs[nsrcs];
int src_steps[nsrcs];
struct ttable_src src_tt[nsrcs];
u_int32_t sample = 0;
int srcidx, srcidx1 = 0;
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel];
if (!src_channel->enabled)
continue;
srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8;
src_steps[srcidx1] = src_channel->area.step / 8;
src_tt[srcidx1] = ttable->srcs[srcidx];
srcidx1++;
}
nsrcs = srcidx1;
if (nsrcs == 0) {
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
return;
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames);
return;
}
dst_channel->enabled = 1;
zero = zero_labels[data->sum_type];
get = get_u_labels[data->get];
add = add_labels[data->sum_type * 2 + ttable->att];
norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
put_u32 = put_u32_labels[data->put];
dst = dst_channel->area.addr + dst_channel->area.first / 8;
dst_step = dst_channel->area.step / 8;
while (frames-- > 0) {
struct ttable_src *ttp = src_tt;
union sum sum;
/* Zero sum */
goto *zero;
zero_int32:
sum.as_uint32 = 0;
goto zero_end;
zero_int64:
sum.as_uint64 = 0;
goto zero_end;
zero_end:
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
char *src = srcs[srcidx];
/* Get sample */
goto *get;
#define GET_U_END after_get
#include "plugin_ops.h"
#undef GET_U_END
after_get:
/* Sum */
goto *add;
add_int32_att:
sum.as_uint32 += sample * ttp->as_int;
goto after_sum;
add_int32_noatt:
if (ttp->as_int)
sum.as_uint32 += sample;
goto after_sum;
add_int64_att:
sum.as_uint64 += (u_int64_t) sample * ttp->as_int;
goto after_sum;
add_int64_noatt:
if (ttp->as_int)
sum.as_uint64 += sample;
goto after_sum;
after_sum:
srcs[srcidx] += src_steps[srcidx];
ttp++;
}
/* Normalization */
goto *norm;
norm_int32_8_att:
sum.as_uint64 = sum.as_uint32;
norm_int64_8_att:
sum.as_uint64 <<= 8;
norm_int64_0_att:
div(sum.as_uint64);
goto norm_int;
norm_int32_16_att:
sum.as_uint64 = sum.as_uint32;
norm_int64_16_att:
sum.as_uint64 <<= 16;
div(sum.as_uint64);
goto norm_int;
norm_int32_24_att:
sum.as_uint64 = sum.as_uint32;
norm_int64_24_att:
sum.as_uint64 <<= 24;
div(sum.as_uint64);
goto norm_int;
norm_int32_8_noatt:
sum.as_uint64 = sum.as_uint32;
norm_int64_8_noatt:
sum.as_uint64 <<= 8;
goto norm_int;
norm_int32_16_noatt:
sum.as_uint64 = sum.as_uint32;
norm_int64_16_noatt:
sum.as_uint64 <<= 16;
goto norm_int;
norm_int32_24_noatt:
sum.as_uint64 = sum.as_uint32;
norm_int64_24_noatt:
sum.as_uint64 <<= 24;
goto norm_int;
norm_int64_0_noatt:
norm_int:
if (sum.as_uint64 > (u_int32_t)0xffffffff)
sample = (u_int32_t)0xffffffff;
else
sample = sum.as_uint64;
goto after_norm;
after_norm:
/* Put sample */
goto *put_u32;
#define PUT_U32_END after_put_u32
#include "plugin_ops.h"
#undef PUT_U32_END
after_put_u32:
dst += dst_step;
}
}
static int route_src_channels_mask(struct snd_pcm_plugin *plugin,
unsigned long *dst_vmask,
unsigned long **src_vmask)
{
struct route_priv *data = (struct route_priv *)plugin->extra_data;
int schannels = plugin->src_format.channels;
int dchannels = plugin->dst_format.channels;
unsigned long *vmask = plugin->src_vmask;
int channel;
struct ttable_dst *dp = data->ttable;
bitmap_zero(vmask, schannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
unsigned int src;
struct ttable_src *sp;
if (!test_bit(channel, dst_vmask))
continue;
sp = dp->srcs;
for (src = 0; src < dp->nsrcs; src++, sp++)
set_bit(sp->channel, vmask);
}
*src_vmask = vmask;
return 0;
}
static int route_dst_channels_mask(struct snd_pcm_plugin *plugin,
unsigned long *src_vmask,
unsigned long **dst_vmask)
{
struct route_priv *data = (struct route_priv *)plugin->extra_data;
int dchannels = plugin->dst_format.channels;
unsigned long *vmask = plugin->dst_vmask;
int channel;
struct ttable_dst *dp = data->ttable;
bitmap_zero(vmask, dchannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
unsigned int src;
struct ttable_src *sp;
sp = dp->srcs;
for (src = 0; src < dp->nsrcs; src++, sp++) {
if (test_bit(sp->channel, src_vmask)) {
set_bit(channel, vmask);
break;
}
}
}
*dst_vmask = vmask;
return 0;
}
static void route_free(struct snd_pcm_plugin *plugin)
{
struct route_priv *data = (struct route_priv *)plugin->extra_data;
unsigned int dst_channel;
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
kfree(data->ttable[dst_channel].srcs);
}
}
static int route_load_ttable(struct snd_pcm_plugin *plugin,
const int *src_ttable)
{
struct route_priv *data;
unsigned int src_channel, dst_channel;
const int *sptr;
struct ttable_dst *dptr;
if (src_ttable == NULL)
return 0;
data = (struct route_priv *)plugin->extra_data;
dptr = data->ttable;
sptr = src_ttable;
plugin->private_free = route_free;
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
int t = 0;
int att = 0;
int nsrcs = 0;
struct ttable_src srcs[plugin->src_format.channels];
for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
if (*sptr != 0) {
srcs[nsrcs].channel = src_channel;
srcs[nsrcs].as_int = *sptr;
if (*sptr != FULL)
att = 1;
t += *sptr;
nsrcs++;
}
sptr++;
}
dptr->att = att;
dptr->nsrcs = nsrcs;
if (nsrcs == 0)
dptr->func = route_to_channel_from_zero;
else if (nsrcs == 1 && !att)
dptr->func = route_to_channel_from_one;
else
dptr->func = route_to_channel;
if (nsrcs > 0) {
int srcidx;
dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL);
for(srcidx = 0; srcidx < nsrcs; srcidx++)
dptr->srcs[srcidx] = srcs[srcidx];
} else
dptr->srcs = NULL;
dptr++;
}
return 0;
snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format);
}
static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
{
struct route_priv *data;
int src_nchannels, dst_nchannels;
int dst_channel;
struct ttable_dst *ttp;
int nsrcs, ndsts, dst;
struct snd_pcm_plugin_channel *dvp;
int format;
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
if (frames == 0)
return 0;
data = (struct route_priv *)plugin->extra_data;
src_nchannels = plugin->src_format.channels;
dst_nchannels = plugin->dst_format.channels;
nsrcs = plugin->src_format.channels;
ndsts = plugin->dst_format.channels;
#ifdef CONFIG_SND_DEBUG
{
int src_channel;
for (src_channel = 0; src_channel < src_nchannels; ++src_channel) {
snd_assert(src_channels[src_channel].area.first % 8 == 0 ||
src_channels[src_channel].area.step % 8 == 0,
return -ENXIO);
}
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
snd_assert(dst_channels[dst_channel].area.first % 8 == 0 ||
dst_channels[dst_channel].area.step % 8 == 0,
return -ENXIO);
}
}
#endif
ttp = data->ttable;
format = plugin->dst_format.format;
dvp = dst_channels;
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
ttp->func(plugin, src_channels, dvp, ttp, frames);
dvp++;
ttp++;
if (nsrcs <= 1) {
/* expand to all channels */
for (dst = 0; dst < ndsts; ++dst) {
copy_area(src_channels, dvp, frames, format);
dvp++;
}
return frames;
}
return frames;
}
int getput_index(int format)
{
int sign, width, endian;
sign = !snd_pcm_format_signed(format);
width = snd_pcm_format_width(format) / 8 - 1;
if (width < 0 || width > 3) {
snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
width = 0;
for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {
copy_area(src_channels, dvp, frames, format);
dvp++;
src_channels++;
}
#ifdef SNDRV_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(format);
#else
endian = snd_pcm_format_little_endian(format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
if (dst < ndsts)
zero_areas(dvp, ndsts - dst, frames, format);
return frames;
}
int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
struct snd_pcm_plugin_format *src_format,
struct snd_pcm_plugin_format *dst_format,
int *ttable,
struct snd_pcm_plugin **r_plugin)
{
struct route_priv *data;
struct snd_pcm_plugin *plugin;
int err;
snd_assert(r_plugin != NULL, return -ENXIO);
*r_plugin = NULL;
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
snd_assert(snd_pcm_format_linear(src_format->format) != 0 &&
snd_pcm_format_linear(dst_format->format) != 0,
return -ENXIO);
snd_assert(src_format->format == dst_format->format, return -ENXIO);
err = snd_pcm_plugin_build(plug, "attenuated route conversion",
src_format, dst_format,
sizeof(struct route_priv) +
sizeof(data->ttable[0]) * dst_format->channels,
&plugin);
err = snd_pcm_plugin_build(plug, "route conversion",
src_format, dst_format, 0, &plugin);
if (err < 0)
return err;
data = (struct route_priv *)plugin->extra_data;
data->get = getput_index(src_format->format);
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
data->put = getput_index(dst_format->format);
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
data->conv = conv_index(src_format->format, dst_format->format);
if (snd_pcm_format_width(src_format->format) == 32)
data->sum_type = R_UINT64;
else
data->sum_type = R_UINT32;
data->src_sample_size = snd_pcm_format_width(src_format->format) / 8;
if ((err = route_load_ttable(plugin, ttable)) < 0) {
snd_pcm_plugin_free(plugin);
return err;
}
plugin->transfer = route_transfer;
plugin->src_channels_mask = route_src_channels_mask;
plugin->dst_channels_mask = route_dst_channels_mask;
*r_plugin = plugin;
return 0;
}
#endif

View File

@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/pcm.h>
@ -35,7 +36,7 @@ MODULE_LICENSE("GPL");
static LIST_HEAD(snd_pcm_devices);
static LIST_HEAD(snd_pcm_notify_list);
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
static int snd_pcm_free(struct snd_pcm *pcm);
static int snd_pcm_dev_free(struct snd_device *device);
@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
if (get_user(device, (int __user *)arg))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_PCM_DEVICES) {
if (snd_pcm_search(card, device))
@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
}
if (device == SNDRV_PCM_DEVICES)
device = -1;
up(&register_mutex);
mutex_unlock(&register_mutex);
if (put_user(device, (int __user *)arg))
return -EFAULT;
return 0;
@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
return -EINVAL;
if (get_user(subdevice, &info->subdevice))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
pcm = snd_pcm_search(card, device);
if (pcm == NULL) {
err = -ENXIO;
@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
}
err = snd_pcm_info_user(substream, info);
_error:
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
}
return -ENOIOCTLCMD;
}
#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
#define READY(v) [SNDRV_PCM_READY_##v] = #v
@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format)
return snd_pcm_format_names[format];
}
#ifdef CONFIG_PROC_FS
static char *snd_pcm_stream_names[] = {
STREAM(PLAYBACK),
STREAM(CAPTURE),
@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state)
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
#include <linux/soundcard.h>
static const char *snd_pcm_oss_format_name(int format)
{
switch (format) {
@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
struct snd_pcm_substream *substream, *prev;
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
init_MUTEX(&pstr->oss.setup_mutex);
mutex_init(&pstr->oss.setup_mutex);
#endif
pstr->stream = stream;
pstr->pcm = pcm;
@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
snd_pcm_free(pcm);
return err;
}
init_MUTEX(&pcm->open_mutex);
mutex_init(&pcm->open_mutex);
init_waitqueue_head(&pcm->open_wait);
if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
snd_pcm_free(pcm);
@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
struct snd_pcm *pcm = device->device_data;
snd_assert(pcm != NULL && device != NULL, return -ENXIO);
down(&register_mutex);
mutex_lock(&register_mutex);
if (snd_pcm_search(pcm->card, pcm->device)) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY;
}
list_add_tail(&pcm->list, &snd_pcm_devices);
@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
pcm, str)) < 0)
{
list_del(&pcm->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_register(pcm);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
struct snd_pcm_substream *substream;
int cidx;
down(&register_mutex);
mutex_lock(&register_mutex);
list_del_init(&pcm->list);
for (cidx = 0; cidx < 2; cidx++)
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_disconnect(pcm);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
struct snd_pcm *pcm = device->device_data;
snd_assert(pcm != NULL, return -ENXIO);
down(&register_mutex);
mutex_lock(&register_mutex);
list_del(&pcm->list);
for (cidx = 0; cidx < 2; cidx++) {
devtype = -1;
@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
notify = list_entry(list, struct snd_pcm_notify, list);
notify->n_unregister(pcm);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return snd_pcm_free(pcm);
}
@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
struct list_head *p;
snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
down(&register_mutex);
mutex_lock(&register_mutex);
if (nfree) {
list_del(&notify->list);
list_for_each(p, &snd_pcm_devices)
@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
list_for_each(p, &snd_pcm_devices)
notify->n_register(list_entry(p, struct snd_pcm, list));
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
struct list_head *p;
struct snd_pcm *pcm;
down(&register_mutex);
mutex_lock(&register_mutex);
list_for_each(p, &snd_pcm_devices) {
pcm = list_entry(p, struct snd_pcm, list);
snd_iprintf(buffer, "%02i-%02i: %s : %s",
@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
snd_iprintf(buffer, "\n");
}
up(&register_mutex);
mutex_unlock(&register_mutex);
}
static struct snd_info_entry *snd_pcm_proc_entry = NULL;
@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream);
EXPORT_SYMBOL(snd_pcm_notify);
EXPORT_SYMBOL(snd_pcm_open_substream);
EXPORT_SYMBOL(snd_pcm_release_substream);
EXPORT_SYMBOL(snd_pcm_format_name);
/* pcm_native.c */
EXPORT_SYMBOL(snd_pcm_link_rwlock);
#ifdef CONFIG_PM

View File

@ -2112,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
}
init_waitqueue_entry(&wait, current);
add_wait_queue(&pcm->open_wait, &wait);
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
while (1) {
err = snd_pcm_open_file(file, pcm, stream, &pcm_file);
if (err >= 0)
@ -2125,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
} else
break;
set_current_state(TASK_INTERRUPTIBLE);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
schedule();
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
}
}
remove_wait_queue(&pcm->open_wait, &wait);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
if (err < 0)
goto __error;
return err;
@ -2160,9 +2160,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
pcm = substream->pcm;
snd_pcm_drop(substream);
fasync_helper(-1, file, 0, &substream->runtime->fasync);
down(&pcm->open_mutex);
mutex_lock(&pcm->open_mutex);
snd_pcm_release_file(pcm_file);
up(&pcm->open_mutex);
mutex_unlock(&pcm->open_mutex);
wake_up(&pcm->open_wait);
module_put(pcm->card->module);
snd_card_file_remove(pcm->card, file);
@ -2539,6 +2539,14 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
return snd_pcm_drain(substream);
case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_drop(substream);
case SNDRV_PCM_IOCTL_PAUSE:
{
int res;
snd_pcm_stream_lock_irq(substream);
res = snd_pcm_pause(substream, (int)(unsigned long)arg);
snd_pcm_stream_unlock_irq(substream);
return res;
}
}
snd_printd("unknown ioctl = 0x%x\n", cmd);
return -ENOTTY;
@ -2619,14 +2627,6 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
__put_user(result, _frames);
return result < 0 ? result : 0;
}
case SNDRV_PCM_IOCTL_PAUSE:
{
int res;
snd_pcm_stream_lock_irq(substream);
res = snd_pcm_pause(substream, (int)(unsigned long)arg);
snd_pcm_stream_unlock_irq(substream);
return res;
}
}
return snd_pcm_common_ioctl1(substream, cmd, arg);
}

View File

@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/wait.h>
@ -57,7 +58,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device);
static int snd_rawmidi_dev_unregister(struct snd_device *device);
static LIST_HEAD(snd_rawmidi_devices);
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
{
@ -237,9 +238,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
if (rfile)
rfile->input = rfile->output = NULL;
down(&register_mutex);
mutex_lock(&register_mutex);
rmidi = snd_rawmidi_search(card, device);
up(&register_mutex);
mutex_unlock(&register_mutex);
if (rmidi == NULL) {
err = -ENODEV;
goto __error1;
@ -249,7 +250,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
goto __error1;
}
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
down(&rmidi->open_mutex);
mutex_lock(&rmidi->open_mutex);
if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) {
err = -ENXIO;
@ -359,7 +360,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
soutput = NULL;
}
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
if (rfile) {
rfile->rmidi = rmidi;
rfile->input = sinput;
@ -374,7 +375,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
snd_rawmidi_runtime_free(soutput);
module_put(rmidi->card->module);
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
__error1:
return err;
}
@ -422,7 +423,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
}
init_waitqueue_entry(&wait, current);
add_wait_queue(&rmidi->open_wait, &wait);
down(&rmidi->open_mutex);
mutex_lock(&rmidi->open_mutex);
while (1) {
subdevice = -1;
down_read(&card->controls_rwsem);
@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
} else
break;
set_current_state(TASK_INTERRUPTIBLE);
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
schedule();
down(&rmidi->open_mutex);
mutex_lock(&rmidi->open_mutex);
if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
snd_card_file_remove(card, file);
kfree(rawmidi_file);
}
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
return err;
}
@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
snd_assert(rfile != NULL, return -ENXIO);
snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO);
rmidi = rfile->rmidi;
down(&rmidi->open_mutex);
mutex_lock(&rmidi->open_mutex);
if (rfile->input != NULL) {
substream = rfile->input;
rfile->input = NULL;
@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
}
rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--;
}
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
module_put(rmidi->card->module);
return 0;
}
@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
struct snd_rawmidi_substream *substream;
struct list_head *list;
down(&register_mutex);
mutex_lock(&register_mutex);
rmidi = snd_rawmidi_search(card, info->device);
up(&register_mutex);
mutex_unlock(&register_mutex);
if (!rmidi)
return -ENXIO;
if (info->stream < 0 || info->stream > 1)
@ -818,7 +819,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
if (get_user(device, (int __user *)argp))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_RAWMIDI_DEVICES) {
if (snd_rawmidi_search(card, device))
@ -827,7 +828,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
}
if (device == SNDRV_RAWMIDI_DEVICES)
device = -1;
up(&register_mutex);
mutex_unlock(&register_mutex);
if (put_user(device, (int __user *)argp))
return -EFAULT;
return 0;
@ -1314,7 +1315,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
rmidi = entry->private_data;
snd_iprintf(buffer, "%s\n\n", rmidi->name);
down(&rmidi->open_mutex);
mutex_lock(&rmidi->open_mutex);
if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
substream = list_entry(list, struct snd_rawmidi_substream, list);
@ -1355,7 +1356,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
}
}
}
up(&rmidi->open_mutex);
mutex_unlock(&rmidi->open_mutex);
}
/*
@ -1436,7 +1437,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
}
rmidi->card = card;
rmidi->device = device;
init_MUTEX(&rmidi->open_mutex);
mutex_init(&rmidi->open_mutex);
init_waitqueue_head(&rmidi->open_wait);
if (id != NULL)
strlcpy(rmidi->id, id, sizeof(rmidi->id));
@ -1507,9 +1508,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
return -ENOMEM;
down(&register_mutex);
mutex_lock(&register_mutex);
if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY;
}
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
@ -1519,14 +1520,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
&snd_rawmidi_f_ops, rmidi, name)) < 0) {
snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
list_del(&rmidi->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
if (rmidi->ops && rmidi->ops->dev_register &&
(err = rmidi->ops->dev_register(rmidi)) < 0) {
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
list_del(&rmidi->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
#ifdef CONFIG_SND_OSSEMUL
@ -1553,7 +1554,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
}
}
#endif /* CONFIG_SND_OSSEMUL */
up(&register_mutex);
mutex_unlock(&register_mutex);
sprintf(name, "midi%d", rmidi->device);
entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
if (entry) {
@ -1583,9 +1584,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
{
struct snd_rawmidi *rmidi = device->device_data;
down(&register_mutex);
mutex_lock(&register_mutex);
list_del_init(&rmidi->list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -1594,7 +1595,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
struct snd_rawmidi *rmidi = device->device_data;
snd_assert(rmidi != NULL, return -ENXIO);
down(&register_mutex);
mutex_lock(&register_mutex);
list_del(&rmidi->list);
if (rmidi->proc_entry) {
snd_info_unregister(rmidi->proc_entry);
@ -1616,7 +1617,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
if (rmidi->ops && rmidi->ops->dev_unregister)
rmidi->ops->dev_unregister(rmidi);
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
up(&register_mutex);
mutex_unlock(&register_mutex);
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
if (rmidi->seq_dev) {
snd_device_free(rmidi->card, rmidi->seq_dev);

View File

@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/initval.h>
@ -124,7 +125,7 @@ module_exit(alsa_seq_oss_exit)
* ALSA minor device interface
*/
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
static int
odev_open(struct inode *inode, struct file *file)
@ -136,9 +137,9 @@ odev_open(struct inode *inode, struct file *file)
else
level = SNDRV_SEQ_OSS_MODE_SYNTH;
down(&register_mutex);
mutex_lock(&register_mutex);
rc = snd_seq_oss_open(file, level);
up(&register_mutex);
mutex_unlock(&register_mutex);
return rc;
}
@ -153,9 +154,9 @@ odev_release(struct inode *inode, struct file *file)
snd_seq_oss_drain_write(dp);
down(&register_mutex);
mutex_lock(&register_mutex);
snd_seq_oss_release(dp);
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -224,13 +225,13 @@ register_device(void)
{
int rc;
down(&register_mutex);
mutex_lock(&register_mutex);
if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
NULL, 0,
&seq_oss_f_ops, NULL,
SNDRV_SEQ_OSS_DEVNAME)) < 0) {
snd_printk(KERN_ERR "can't register device seq\n");
up(&register_mutex);
mutex_unlock(&register_mutex);
return rc;
}
if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
@ -239,24 +240,24 @@ register_device(void)
SNDRV_SEQ_OSS_DEVNAME)) < 0) {
snd_printk(KERN_ERR "can't register device music\n");
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
up(&register_mutex);
mutex_unlock(&register_mutex);
return rc;
}
debug_printk(("device registered\n"));
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
static void
unregister_device(void)
{
down(&register_mutex);
mutex_lock(&register_mutex);
debug_printk(("device unregistered\n"));
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)
snd_printk(KERN_ERR "error unregister device music\n");
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
snd_printk(KERN_ERR "error unregister device seq\n");
up(&register_mutex);
mutex_unlock(&register_mutex);
}
/*
@ -270,12 +271,12 @@ static struct snd_info_entry *info_entry;
static void
info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
{
down(&register_mutex);
mutex_lock(&register_mutex);
snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
snd_seq_oss_system_info_read(buf);
snd_seq_oss_synth_info_read(buf);
snd_seq_oss_midi_info_read(buf);
up(&register_mutex);
mutex_unlock(&register_mutex);
}

View File

@ -67,7 +67,7 @@
#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
static DEFINE_SPINLOCK(clients_lock);
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
/*
* client table
@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
client->type = NO_CLIENT;
snd_use_lock_init(&client->use_lock);
rwlock_init(&client->ports_lock);
init_MUTEX(&client->ports_mutex);
mutex_init(&client->ports_mutex);
INIT_LIST_HEAD(&client->ports_list_head);
/* find free slot in the client table */
@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client)
static void seq_free_client(struct snd_seq_client * client)
{
down(&register_mutex);
mutex_lock(&register_mutex);
switch (client->type) {
case NO_CLIENT:
snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
@ -306,7 +306,7 @@ static void seq_free_client(struct snd_seq_client * client)
snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
client->number, client->type);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
snd_seq_system_client_ev_client_exit(client->number);
}
@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
struct snd_seq_client *client;
struct snd_seq_user_client *user;
if (down_interruptible(&register_mutex))
if (mutex_lock_interruptible(&register_mutex))
return -ERESTARTSYS;
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
if (client == NULL) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENOMEM; /* failure code */
}
@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file)
if (user->fifo == NULL) {
seq_free_client1(client);
kfree(client);
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENOMEM;
}
}
usage_alloc(&client_usage, 1);
client->type = USER_CLIENT;
up(&register_mutex);
mutex_unlock(&register_mutex);
c = client->number;
file->private_data = client;
@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
if (queue == NULL)
return -EINVAL;
if (down_interruptible(&queue->timer_mutex)) {
if (mutex_lock_interruptible(&queue->timer_mutex)) {
queuefree(queue);
return -ERESTARTSYS;
}
@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
timer.u.alsa.id = tmr->alsa_id;
timer.u.alsa.resolution = tmr->preferred_resolution;
}
up(&queue->timer_mutex);
mutex_unlock(&queue->timer_mutex);
queuefree(queue);
if (copy_to_user(arg, &timer, sizeof(timer)))
@ -1785,7 +1785,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
q = queueptr(timer.queue);
if (q == NULL)
return -ENXIO;
if (down_interruptible(&q->timer_mutex)) {
if (mutex_lock_interruptible(&q->timer_mutex)) {
queuefree(q);
return -ERESTARTSYS;
}
@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
tmr->preferred_resolution = timer.u.alsa.resolution;
}
result = snd_seq_queue_timer_open(timer.queue);
up(&q->timer_mutex);
mutex_unlock(&q->timer_mutex);
queuefree(q);
} else {
return -EPERM;
@ -1866,8 +1866,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
info.output_pool = cptr->pool->size;
info.output_room = cptr->pool->room;
info.output_free = info.output_pool;
if (cptr->pool)
info.output_free = snd_seq_unused_cells(cptr->pool);
info.output_free = snd_seq_unused_cells(cptr->pool);
if (cptr->type == USER_CLIENT) {
info.input_pool = cptr->data.user.fifo_pool_size;
info.input_free = info.input_pool;
@ -2230,7 +2229,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
return -EINVAL;
if (down_interruptible(&register_mutex))
if (mutex_lock_interruptible(&register_mutex))
return -ERESTARTSYS;
if (card) {
@ -2243,7 +2242,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
/* empty write queue as default */
client = seq_create_client1(client_index, 0);
if (client == NULL) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY; /* failure code */
}
usage_alloc(&client_usage, 1);
@ -2256,7 +2255,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
va_end(args);
client->type = KERNEL_CLIENT;
up(&register_mutex);
mutex_unlock(&register_mutex);
/* make others aware this new client */
snd_seq_system_client_ev_client_start(client->number);
@ -2464,7 +2463,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
{
struct list_head *l;
down(&client->ports_mutex);
mutex_lock(&client->ports_mutex);
list_for_each(l, &client->ports_list_head) {
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n",
@ -2476,7 +2475,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: ");
snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
}
up(&client->ports_mutex);
mutex_unlock(&client->ports_mutex);
}
@ -2550,16 +2549,16 @@ int __init snd_sequencer_device_init(void)
{
int err;
if (down_interruptible(&register_mutex))
if (mutex_lock_interruptible(&register_mutex))
return -ERESTARTSYS;
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
&snd_seq_f_ops, NULL, "seq")) < 0) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}

View File

@ -58,7 +58,7 @@ struct snd_seq_client {
int num_ports; /* number of ports */
struct list_head ports_list_head;
rwlock_t ports_lock;
struct semaphore ports_mutex;
struct mutex ports_mutex;
int convert32; /* convert 32->64bit */
/* output pool */

View File

@ -45,6 +45,7 @@
#include <sound/initval.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/mutex.h>
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ALSA sequencer device management");
@ -69,7 +70,7 @@ struct ops_list {
struct list_head dev_list; /* list of devices */
int num_devices; /* number of associated devices */
int num_init_devices; /* number of initialized devices */
struct semaphore reg_mutex;
struct mutex reg_mutex;
struct list_head list; /* next driver */
};
@ -77,7 +78,7 @@ struct ops_list {
static LIST_HEAD(opslist);
static int num_ops;
static DECLARE_MUTEX(ops_mutex);
static DEFINE_MUTEX(ops_mutex);
#ifdef CONFIG_PROC_FS
static struct snd_info_entry *info_entry = NULL;
#endif
@ -108,7 +109,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
{
struct list_head *head;
down(&ops_mutex);
mutex_lock(&ops_mutex);
list_for_each(head, &opslist) {
struct ops_list *ops = list_entry(head, struct ops_list, list);
snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
@ -118,7 +119,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
ops->driver & DRIVER_LOCKED ? ",locked" : "",
ops->num_devices);
}
up(&ops_mutex);
mutex_unlock(&ops_mutex);
}
#endif
@ -154,20 +155,20 @@ void snd_seq_device_load_drivers(void)
if (! current->fs->root)
return;
down(&ops_mutex);
mutex_lock(&ops_mutex);
list_for_each(head, &opslist) {
struct ops_list *ops = list_entry(head, struct ops_list, list);
if (! (ops->driver & DRIVER_LOADED) &&
! (ops->driver & DRIVER_REQUESTED)) {
ops->used++;
up(&ops_mutex);
mutex_unlock(&ops_mutex);
ops->driver |= DRIVER_REQUESTED;
request_module("snd-%s", ops->id);
down(&ops_mutex);
mutex_lock(&ops_mutex);
ops->used--;
}
}
up(&ops_mutex);
mutex_unlock(&ops_mutex);
#endif
}
@ -214,10 +215,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
dev->status = SNDRV_SEQ_DEVICE_FREE;
/* add this device to the list */
down(&ops->reg_mutex);
mutex_lock(&ops->reg_mutex);
list_add_tail(&dev->list, &ops->dev_list);
ops->num_devices++;
up(&ops->reg_mutex);
mutex_unlock(&ops->reg_mutex);
unlock_driver(ops);
@ -246,10 +247,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
return -ENXIO;
/* remove the device from the list */
down(&ops->reg_mutex);
mutex_lock(&ops->reg_mutex);
list_del(&dev->list);
ops->num_devices--;
up(&ops->reg_mutex);
mutex_unlock(&ops->reg_mutex);
free_device(dev, ops);
if (dev->private_free)
@ -344,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
return -EBUSY;
}
down(&ops->reg_mutex);
mutex_lock(&ops->reg_mutex);
/* copy driver operators */
ops->ops = *entry;
ops->driver |= DRIVER_LOADED;
@ -355,7 +356,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
init_device(dev, ops);
}
up(&ops->reg_mutex);
mutex_unlock(&ops->reg_mutex);
unlock_driver(ops);
snd_seq_autoload_unlock();
@ -378,17 +379,17 @@ static struct ops_list * create_driver(char *id)
/* set up driver entry */
strlcpy(ops->id, id, sizeof(ops->id));
init_MUTEX(&ops->reg_mutex);
mutex_init(&ops->reg_mutex);
ops->driver = DRIVER_EMPTY;
INIT_LIST_HEAD(&ops->dev_list);
/* lock this instance */
ops->used = 1;
/* register driver entry */
down(&ops_mutex);
mutex_lock(&ops_mutex);
list_add_tail(&ops->list, &opslist);
num_ops++;
up(&ops_mutex);
mutex_unlock(&ops_mutex);
return ops;
}
@ -414,7 +415,7 @@ int snd_seq_device_unregister_driver(char *id)
}
/* close and release all devices associated with this driver */
down(&ops->reg_mutex);
mutex_lock(&ops->reg_mutex);
ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
list_for_each(head, &ops->dev_list) {
struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
@ -425,7 +426,7 @@ int snd_seq_device_unregister_driver(char *id)
if (ops->num_init_devices > 0)
snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
ops->num_init_devices);
up(&ops->reg_mutex);
mutex_unlock(&ops->reg_mutex);
unlock_driver(ops);
@ -443,7 +444,7 @@ static void remove_drivers(void)
{
struct list_head *head;
down(&ops_mutex);
mutex_lock(&ops_mutex);
head = opslist.next;
while (head != &opslist) {
struct ops_list *ops = list_entry(head, struct ops_list, list);
@ -456,7 +457,7 @@ static void remove_drivers(void)
} else
head = head->next;
}
up(&ops_mutex);
mutex_unlock(&ops_mutex);
}
/*
@ -519,16 +520,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
{
struct list_head *head;
down(&ops_mutex);
mutex_lock(&ops_mutex);
list_for_each(head, &opslist) {
struct ops_list *ops = list_entry(head, struct ops_list, list);
if (strcmp(ops->id, id) == 0) {
ops->used++;
up(&ops_mutex);
mutex_unlock(&ops_mutex);
return ops;
}
}
up(&ops_mutex);
mutex_unlock(&ops_mutex);
if (create_if_empty)
return create_driver(id);
return NULL;
@ -536,9 +537,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
static void unlock_driver(struct ops_list *ops)
{
down(&ops_mutex);
mutex_lock(&ops_mutex);
ops->used--;
up(&ops_mutex);
mutex_unlock(&ops_mutex);
}

View File

@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list)
if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
spin_lock_irqsave(&list->ops_lock, list->ops_flags);
} else {
down(&list->ops_mutex);
mutex_lock(&list->ops_mutex);
}
}
@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list)
if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
spin_unlock_irqrestore(&list->ops_lock, list->ops_flags);
} else {
up(&list->ops_mutex);
mutex_unlock(&list->ops_mutex);
}
}
@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void)
return NULL;
spin_lock_init(&list->lock);
spin_lock_init(&list->ops_lock);
init_MUTEX(&list->ops_mutex);
mutex_init(&list->ops_mutex);
list->owner = -1;
return list;
}

View File

@ -32,7 +32,7 @@ Possible options for midisynth module:
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/moduleparam.h>
#include <asm/semaphore.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <sound/seq_kernel.h>
@ -70,7 +70,7 @@ struct seq_midisynth_client {
};
static struct seq_midisynth_client *synths[SNDRV_CARDS];
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
/* handle rawmidi input event (MIDI v1.0 stream) */
static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
@ -308,13 +308,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
ports = 256 / SNDRV_RAWMIDI_DEVICES;
down(&register_mutex);
mutex_lock(&register_mutex);
client = synths[card->number];
if (client == NULL) {
newclient = 1;
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (client == NULL) {
up(&register_mutex);
mutex_unlock(&register_mutex);
kfree(info);
return -ENOMEM;
}
@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
(const char *)info->name : "External MIDI");
if (client->seq_client < 0) {
kfree(client);
up(&register_mutex);
mutex_unlock(&register_mutex);
kfree(info);
return -ENOMEM;
}
@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
client->num_ports++;
if (newclient)
synths[card->number] = client;
up(&register_mutex);
mutex_unlock(&register_mutex);
kfree(info);
kfree(port);
return 0; /* success */
@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
}
kfree(info);
kfree(port);
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENOMEM;
}
@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
struct snd_card *card = dev->card;
int device = dev->device, p, ports;
down(&register_mutex);
mutex_lock(&register_mutex);
client = synths[card->number];
if (client == NULL || client->ports[device] == NULL) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENODEV;
}
ports = client->ports_per_device[device];
@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
synths[card->number] = NULL;
kfree(client);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}

View File

@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
port_subs_info_init(&new_port->c_dest);
num = port >= 0 ? port : 0;
down(&client->ports_mutex);
mutex_lock(&client->ports_mutex);
write_lock_irqsave(&client->ports_lock, flags);
list_for_each(l, &client->ports_list_head) {
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
@ -173,7 +173,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
client->num_ports++;
new_port->addr.port = num; /* store the port number in the port */
write_unlock_irqrestore(&client->ports_lock, flags);
up(&client->ports_mutex);
mutex_unlock(&client->ports_mutex);
sprintf(new_port->name, "port-%d", num);
return new_port;
@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
struct list_head *l;
struct snd_seq_client_port *found = NULL;
down(&client->ports_mutex);
mutex_lock(&client->ports_mutex);
write_lock_irqsave(&client->ports_lock, flags);
list_for_each(l, &client->ports_list_head) {
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
@ -305,7 +305,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
}
}
write_unlock_irqrestore(&client->ports_lock, flags);
up(&client->ports_mutex);
mutex_unlock(&client->ports_mutex);
if (found)
return port_delete(client, found);
else
@ -321,7 +321,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
/* move the port list to deleted_list, and
* clear the port list in the client data.
*/
down(&client->ports_mutex);
mutex_lock(&client->ports_mutex);
write_lock_irqsave(&client->ports_lock, flags);
if (! list_empty(&client->ports_list_head)) {
__list_add(&deleted_list,
@ -341,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
port_delete(client, port);
}
up(&client->ports_mutex);
mutex_unlock(&client->ports_mutex);
return 0;
}

View File

@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
spin_lock_init(&q->owner_lock);
spin_lock_init(&q->check_lock);
init_MUTEX(&q->timer_mutex);
mutex_init(&q->timer_mutex);
snd_use_lock_init(&q->use_lock);
q->queue = -1;
@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
queue = queueptr(queueid);
if (queue == NULL)
return -EINVAL;
down(&queue->timer_mutex);
mutex_lock(&queue->timer_mutex);
if (use) {
if (!test_and_set_bit(client, queue->clients_bitmap))
queue->clients++;
@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
} else {
snd_seq_timer_close(queue);
}
up(&queue->timer_mutex);
mutex_unlock(&queue->timer_mutex);
queuefree(queue);
return 0;
}

View File

@ -54,7 +54,7 @@ struct snd_seq_queue {
/* clients which uses this queue (bitmap) */
DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS);
unsigned int clients; /* users of this queue */
struct semaphore timer_mutex;
struct mutex timer_mutex;
snd_use_lock_t use_lock;
};

View File

@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
return; /* ignored */
}
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0)
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
return;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}
@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
pbuf += res;
count -= res;
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0)
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
return;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}

View File

@ -33,6 +33,7 @@
#include <sound/initval.h>
#include <linux/kmod.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/mutex.h>
#define SNDRV_OS_MINORS 256
@ -61,7 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
int snd_ecards_limit;
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
static DECLARE_MUTEX(sound_mutex);
static DEFINE_MUTEX(sound_mutex);
extern struct class *sound_class;
@ -120,15 +121,15 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
struct snd_minor *mreg;
void *private_data;
if (minor > ARRAY_SIZE(snd_minors))
if (minor >= ARRAY_SIZE(snd_minors))
return NULL;
down(&sound_mutex);
mutex_lock(&sound_mutex);
mreg = snd_minors[minor];
if (mreg && mreg->type == type)
private_data = mreg->private_data;
else
private_data = NULL;
up(&sound_mutex);
mutex_unlock(&sound_mutex);
return private_data;
}
@ -139,7 +140,7 @@ static int snd_open(struct inode *inode, struct file *file)
struct file_operations *old_fops;
int err = 0;
if (minor > ARRAY_SIZE(snd_minors))
if (minor >= ARRAY_SIZE(snd_minors))
return -ENODEV;
mptr = snd_minors[minor];
if (mptr == NULL) {
@ -256,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
preg->f_ops = f_ops;
preg->private_data = private_data;
strcpy(preg->name, name);
down(&sound_mutex);
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
minor = snd_find_free_minor();
#else
@ -265,7 +266,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
minor = -EBUSY;
#endif
if (minor < 0) {
up(&sound_mutex);
mutex_unlock(&sound_mutex);
kfree(preg);
return minor;
}
@ -276,7 +277,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
device = card->dev;
class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
up(&sound_mutex);
mutex_unlock(&sound_mutex);
return 0;
}
@ -297,7 +298,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
struct snd_minor *mptr;
cardnum = card ? card->number : -1;
down(&sound_mutex);
mutex_lock(&sound_mutex);
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
if ((mptr = snd_minors[minor]) != NULL &&
mptr->type == type &&
@ -305,7 +306,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
mptr->device == dev)
break;
if (minor == ARRAY_SIZE(snd_minors)) {
up(&sound_mutex);
mutex_unlock(&sound_mutex);
return -EINVAL;
}
@ -315,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
class_device_destroy(sound_class, MKDEV(major, minor));
snd_minors[minor] = NULL;
up(&sound_mutex);
mutex_unlock(&sound_mutex);
kfree(mptr);
return 0;
}
@ -354,7 +355,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
int minor;
struct snd_minor *mptr;
down(&sound_mutex);
mutex_lock(&sound_mutex);
for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
if (!(mptr = snd_minors[minor]))
continue;
@ -371,7 +372,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
snd_iprintf(buffer, "%3i: : %s\n", minor,
snd_device_type_name(mptr->type));
}
up(&sound_mutex);
mutex_unlock(&sound_mutex);
}
int __init snd_minor_info_init(void)

View File

@ -34,26 +34,27 @@
#include <sound/minors.h>
#include <sound/info.h>
#include <linux/sound.h>
#include <linux/mutex.h>
#define SNDRV_OSS_MINORS 128
static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
static DECLARE_MUTEX(sound_oss_mutex);
static DEFINE_MUTEX(sound_oss_mutex);
void *snd_lookup_oss_minor_data(unsigned int minor, int type)
{
struct snd_minor *mreg;
void *private_data;
if (minor > ARRAY_SIZE(snd_oss_minors))
if (minor >= ARRAY_SIZE(snd_oss_minors))
return NULL;
down(&sound_oss_mutex);
mutex_lock(&sound_oss_mutex);
mreg = snd_oss_minors[minor];
if (mreg && mreg->type == type)
private_data = mreg->private_data;
else
private_data = NULL;
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
return private_data;
}
@ -117,7 +118,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
preg->device = dev;
preg->f_ops = f_ops;
preg->private_data = private_data;
down(&sound_oss_mutex);
mutex_lock(&sound_oss_mutex);
snd_oss_minors[minor] = preg;
minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
switch (minor_unit) {
@ -143,7 +144,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
goto __end;
snd_oss_minors[track2] = preg;
}
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
return 0;
__end:
@ -152,7 +153,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
if (register1 >= 0)
unregister_sound_special(register1);
snd_oss_minors[minor] = NULL;
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
kfree(preg);
return -EBUSY;
}
@ -168,10 +169,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
return 0;
if (minor < 0)
return minor;
down(&sound_oss_mutex);
mutex_lock(&sound_oss_mutex);
mptr = snd_oss_minors[minor];
if (mptr == NULL) {
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
return -ENOENT;
}
unregister_sound_special(minor);
@ -191,7 +192,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
snd_oss_minors[track2] = NULL;
}
snd_oss_minors[minor] = NULL;
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
kfree(mptr);
return 0;
}
@ -229,7 +230,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
int minor;
struct snd_minor *mptr;
down(&sound_oss_mutex);
mutex_lock(&sound_oss_mutex);
for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
if (!(mptr = snd_oss_minors[minor]))
continue;
@ -241,7 +242,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "%3i: : %s\n", minor,
snd_oss_device_type_name(mptr->type));
}
up(&sound_oss_mutex);
mutex_unlock(&sound_oss_mutex);
}

View File

@ -25,6 +25,7 @@
#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <sound/core.h>
@ -70,7 +71,7 @@ struct snd_timer_user {
struct timespec tstamp; /* trigger tstamp */
wait_queue_head_t qchange_sleep;
struct fasync_struct *fasync;
struct semaphore tread_sem;
struct mutex tread_sem;
};
/* list of timers */
@ -82,7 +83,7 @@ static LIST_HEAD(snd_timer_slave_list);
/* lock for slave active lists */
static DEFINE_SPINLOCK(slave_active_lock);
static DECLARE_MUTEX(register_mutex);
static DEFINE_MUTEX(register_mutex);
static int snd_timer_free(struct snd_timer *timer);
static int snd_timer_dev_free(struct snd_device *device);
@ -252,10 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
snd_printd("invalid slave class %i\n", tid->dev_sclass);
return -EINVAL;
}
down(&register_mutex);
mutex_lock(&register_mutex);
timeri = snd_timer_instance_new(owner, NULL);
if (!timeri) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENOMEM;
}
timeri->slave_class = tid->dev_sclass;
@ -263,37 +264,37 @@ int snd_timer_open(struct snd_timer_instance **ti,
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
list_add_tail(&timeri->open_list, &snd_timer_slave_list);
snd_timer_check_slave(timeri);
up(&register_mutex);
mutex_unlock(&register_mutex);
*ti = timeri;
return 0;
}
/* open a master instance */
down(&register_mutex);
mutex_lock(&register_mutex);
timer = snd_timer_find(tid);
#ifdef CONFIG_KMOD
if (timer == NULL) {
up(&register_mutex);
mutex_unlock(&register_mutex);
snd_timer_request(tid);
down(&register_mutex);
mutex_lock(&register_mutex);
timer = snd_timer_find(tid);
}
#endif
if (!timer) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENODEV;
}
if (!list_empty(&timer->open_list_head)) {
timeri = list_entry(timer->open_list_head.next,
struct snd_timer_instance, open_list);
if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY;
}
}
timeri = snd_timer_instance_new(owner, timer);
if (!timeri) {
up(&register_mutex);
mutex_unlock(&register_mutex);
return -ENOMEM;
}
timeri->slave_class = tid->dev_sclass;
@ -302,7 +303,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
timer->hw.open(timer);
list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri);
up(&register_mutex);
mutex_unlock(&register_mutex);
*ti = timeri;
return 0;
}
@ -333,9 +334,9 @@ int snd_timer_close(struct snd_timer_instance *timeri)
spin_lock_irq(&slave_active_lock);
}
spin_unlock_irq(&slave_active_lock);
down(&register_mutex);
mutex_lock(&register_mutex);
list_del(&timeri->open_list);
up(&register_mutex);
mutex_unlock(&register_mutex);
} else {
timer = timeri->timer;
/* wait, until the active callback is finished */
@ -346,7 +347,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
spin_lock_irq(&timer->lock);
}
spin_unlock_irq(&timer->lock);
down(&register_mutex);
mutex_lock(&register_mutex);
list_del(&timeri->open_list);
if (timer && list_empty(&timer->open_list_head) &&
timer->hw.close)
@ -362,7 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
slave->timer = NULL;
spin_unlock_irq(&slave_active_lock);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
}
if (timeri->private_free)
timeri->private_free(timeri);
@ -835,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev)
!timer->hw.resolution && timer->hw.c_resolution == NULL)
return -EINVAL;
down(&register_mutex);
mutex_lock(&register_mutex);
list_for_each(p, &snd_timer_list) {
timer1 = list_entry(p, struct snd_timer, device_list);
if (timer1->tmr_class > timer->tmr_class)
@ -857,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev)
if (timer1->tmr_subdevice < timer->tmr_subdevice)
continue;
/* conflicts.. */
up(&register_mutex);
mutex_unlock(&register_mutex);
return -EBUSY;
}
list_add_tail(&timer->device_list, p);
up(&register_mutex);
mutex_unlock(&register_mutex);
return 0;
}
@ -871,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
struct snd_timer_instance *ti;
snd_assert(timer != NULL, return -ENXIO);
down(&register_mutex);
mutex_lock(&register_mutex);
if (! list_empty(&timer->open_list_head)) {
snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
list_for_each_safe(p, n, &timer->open_list_head) {
@ -881,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
}
}
list_del(&timer->device_list);
up(&register_mutex);
mutex_unlock(&register_mutex);
return snd_timer_free(timer);
}
@ -1065,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
struct snd_timer_instance *ti;
struct list_head *p, *q;
down(&register_mutex);
mutex_lock(&register_mutex);
list_for_each(p, &snd_timer_list) {
timer = list_entry(p, struct snd_timer, device_list);
switch (timer->tmr_class) {
@ -1105,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
}
spin_unlock_irqrestore(&timer->lock, flags);
}
up(&register_mutex);
mutex_unlock(&register_mutex);
}
static struct snd_info_entry *snd_timer_proc_entry = NULL;
@ -1269,7 +1270,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
return -ENOMEM;
spin_lock_init(&tu->qlock);
init_waitqueue_head(&tu->qchange_sleep);
init_MUTEX(&tu->tread_sem);
mutex_init(&tu->tread_sem);
tu->ticks = 1;
tu->queue_size = 128;
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@ -1325,7 +1326,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
if (copy_from_user(&id, _tid, sizeof(id)))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
if (id.dev_class < 0) { /* first item */
if (list_empty(&snd_timer_list))
snd_timer_user_zero_id(&id);
@ -1407,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
snd_timer_user_zero_id(&id);
}
}
up(&register_mutex);
mutex_unlock(&register_mutex);
if (copy_to_user(_tid, &id, sizeof(*_tid)))
return -EFAULT;
return 0;
@ -1432,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file,
tid = ginfo->tid;
memset(ginfo, 0, sizeof(*ginfo));
ginfo->tid = tid;
down(&register_mutex);
mutex_lock(&register_mutex);
t = snd_timer_find(&tid);
if (t != NULL) {
ginfo->card = t->card ? t->card->number : -1;
@ -1451,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file,
} else {
err = -ENODEV;
}
up(&register_mutex);
mutex_unlock(&register_mutex);
if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
err = -EFAULT;
kfree(ginfo);
@ -1467,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file,
if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
return -EFAULT;
down(&register_mutex);
mutex_lock(&register_mutex);
t = snd_timer_find(&gparams.tid);
if (!t) {
err = -ENODEV;
@ -1483,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file,
}
err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
_error:
up(&register_mutex);
mutex_unlock(&register_mutex);
return err;
}
@ -1500,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file,
tid = gstatus.tid;
memset(&gstatus, 0, sizeof(gstatus));
gstatus.tid = tid;
down(&register_mutex);
mutex_lock(&register_mutex);
t = snd_timer_find(&tid);
if (t != NULL) {
if (t->hw.c_resolution)
@ -1517,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file,
} else {
err = -ENODEV;
}
up(&register_mutex);
mutex_unlock(&register_mutex);
if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
err = -EFAULT;
return err;
@ -1532,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file,
int err = 0;
tu = file->private_data;
down(&tu->tread_sem);
mutex_lock(&tu->tread_sem);
if (tu->timeri) {
snd_timer_close(tu->timeri);
tu->timeri = NULL;
@ -1576,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file,
}
__err:
up(&tu->tread_sem);
mutex_unlock(&tu->tread_sem);
return err;
}
@ -1797,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
{
int xarg;
down(&tu->tread_sem);
mutex_lock(&tu->tread_sem);
if (tu->timeri) { /* too late */
up(&tu->tread_sem);
mutex_unlock(&tu->tread_sem);
return -EBUSY;
}
if (get_user(xarg, p)) {
up(&tu->tread_sem);
mutex_unlock(&tu->tread_sem);
return -EFAULT;
}
tu->tread = xarg ? 1 : 0;
up(&tu->tread_sem);
mutex_unlock(&tu->tread_sem);
return 0;
}
case SNDRV_TIMER_IOCTL_GINFO:

View File

@ -669,8 +669,10 @@ static int __init alsa_card_dummy_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_DUMMY_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -240,8 +240,10 @@ static int __init alsa_card_mpu401_init(void)
return err;
devices = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
#ifdef CONFIG_PNP
if (pnp[i])
continue;

View File

@ -358,7 +358,7 @@ int snd_opl3_new(struct snd_card *card,
opl3->hardware = hardware;
spin_lock_init(&opl3->reg_lock);
spin_lock_init(&opl3->timer_lock);
init_MUTEX(&opl3->access_mutex);
mutex_init(&opl3->access_mutex);
if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
snd_opl3_free(opl3);

View File

@ -104,8 +104,10 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
voices, voices,
name);
if (opl3->oss_chset->port < 0) {
int port;
port = opl3->oss_chset->port;
snd_midi_channel_free_set(opl3->oss_chset);
return opl3->oss_chset->port;
return port;
}
return 0;
}
@ -136,10 +138,10 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
arg->oper = oss_callback;
arg->private_data = opl3;
snd_opl3_oss_create_port(opl3);
/* register to OSS synth table */
snd_device_register(opl3->card, dev);
if (snd_opl3_oss_create_port(opl3)) {
/* register to OSS synth table */
snd_device_register(opl3->card, dev);
}
}
/* unregister */

View File

@ -52,13 +52,13 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3)
{
int idx;
down(&opl3->access_mutex);
mutex_lock(&opl3->access_mutex);
if (opl3->used) {
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
return -EBUSY;
}
opl3->used++;
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
snd_opl3_reset(opl3);
@ -91,9 +91,9 @@ void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
snd_opl3_reset(opl3);
down(&opl3->access_mutex);
mutex_lock(&opl3->access_mutex);
opl3->used--;
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
}
static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
@ -207,8 +207,10 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
16, voices,
name);
if (opl3->chset->port < 0) {
int port;
port = opl3->chset->port;
snd_midi_channel_free_set(opl3->chset);
return opl3->chset->port;
return port;
}
return 0;
}
@ -218,7 +220,7 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
{
struct snd_opl3 *opl3;
int client;
int client, err;
char name[32];
int opl_ver;
@ -239,7 +241,11 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
if (client < 0)
return client;
snd_opl3_synth_create_port(opl3);
if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
snd_seq_delete_kernel_client(client);
opl3->seq_client = -1;
return err;
}
/* initialize instrument list */
opl3->ilist = snd_seq_instr_list_new();

View File

@ -76,13 +76,13 @@ int snd_opl3_open(struct snd_hwdep * hw, struct file *file)
{
struct snd_opl3 *opl3 = hw->private_data;
down(&opl3->access_mutex);
mutex_lock(&opl3->access_mutex);
if (opl3->used) {
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
return -EAGAIN;
}
opl3->used++;
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
return 0;
}
@ -179,9 +179,9 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
struct snd_opl3 *opl3 = hw->private_data;
snd_opl3_reset(opl3);
down(&opl3->access_mutex);
mutex_lock(&opl3->access_mutex);
opl3->used--;
up(&opl3->access_mutex);
mutex_unlock(&opl3->access_mutex);
return 0;
}

View File

@ -214,7 +214,7 @@ int snd_opl4_create(struct snd_card *card,
opl4->fm_port = fm_port;
opl4->pcm_port = pcm_port;
spin_lock_init(&opl4->reg_lock);
init_MUTEX(&opl4->access_mutex);
mutex_init(&opl4->access_mutex);
err = snd_opl4_detect(opl4);
if (err < 0) {

View File

@ -182,7 +182,7 @@ struct snd_opl4 {
struct snd_info_entry *proc_entry;
int memory_access;
#endif
struct semaphore access_mutex;
struct mutex access_mutex;
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
int used;

View File

@ -28,13 +28,13 @@ static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
{
struct snd_opl4 *opl4 = entry->private_data;
down(&opl4->access_mutex);
mutex_lock(&opl4->access_mutex);
if (opl4->memory_access) {
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
return -EBUSY;
}
opl4->memory_access++;
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
return 0;
}
@ -43,9 +43,9 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
{
struct snd_opl4 *opl4 = entry->private_data;
down(&opl4->access_mutex);
mutex_lock(&opl4->access_mutex);
opl4->memory_access--;
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
return 0;
}

View File

@ -62,10 +62,10 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i
struct snd_opl4 *opl4 = private_data;
int err;
down(&opl4->access_mutex);
mutex_lock(&opl4->access_mutex);
if (opl4->used) {
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
return -EBUSY;
}
opl4->used++;
@ -73,12 +73,12 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
err = snd_opl4_seq_use_inc(opl4);
if (err < 0) {
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
return err;
}
}
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
snd_opl4_synth_reset(opl4);
return 0;
@ -90,9 +90,9 @@ static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe
snd_opl4_synth_shutdown(opl4);
down(&opl4->access_mutex);
mutex_lock(&opl4->access_mutex);
opl4->used--;
up(&opl4->access_mutex);
mutex_unlock(&opl4->access_mutex);
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
snd_opl4_seq_use_dec(opl4);

View File

@ -789,6 +789,7 @@ static int __init snd_uart16550_create(struct snd_card *card,
if ((err = snd_uart16550_detect(uart)) <= 0) {
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
snd_uart16550_free(uart);
return -ENODEV;
}
@ -989,8 +990,10 @@ static int __init alsa_card_serial_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_SERIAL_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -163,8 +163,10 @@ static int __init alsa_card_virmidi_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -778,7 +778,7 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
chip->type = hw->type;
chip->ops = ops;
tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip);
init_MUTEX(&chip->mixer_mutex);
mutex_init(&chip->mixer_mutex);
chip->card = card;
card->private_data = chip;

View File

@ -427,10 +427,10 @@ static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int codec = kcontrol->id.index;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->output_level[codec][0];
ucontrol->value.integer.value[1] = chip->output_level[codec][1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -438,7 +438,7 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int codec = kcontrol->id.index;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] ||
ucontrol->value.integer.value[1] != chip->output_level[codec][1]) {
vx_set_analog_output_level(chip, codec,
@ -446,10 +446,10 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
ucontrol->value.integer.value[1]);
chip->output_level[codec][0] = ucontrol->value.integer.value[0];
chip->output_level[codec][1] = ucontrol->value.integer.value[1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -502,14 +502,14 @@ static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
chip->audio_source_target = ucontrol->value.enumerated.item[0];
vx_sync_audio_source(chip);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -550,14 +550,14 @@ static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
chip->clock_mode = ucontrol->value.enumerated.item[0];
vx_set_clock(chip, chip->freq);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -587,10 +587,10 @@ static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
int audio = kcontrol->private_value & 0xff;
int capture = (kcontrol->private_value >> 8) & 1;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -600,15 +600,15 @@ static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
int audio = kcontrol->private_value & 0xff;
int capture = (kcontrol->private_value >> 8) & 1;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] ||
ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) {
vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]);
vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -617,10 +617,10 @@ static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -629,17 +629,17 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] ||
ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) {
vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0],
chip->audio_monitor_active[audio]);
vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1],
chip->audio_monitor_active[audio+1]);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -657,10 +657,10 @@ static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_active[audio];
ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -669,15 +669,15 @@ static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]);
vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -686,10 +686,10 @@ static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -698,17 +698,17 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
int audio = kcontrol->private_value & 0xff;
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
ucontrol->value.integer.value[0]);
vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
ucontrol->value.integer.value[1]);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -756,12 +756,12 @@ static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
{
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}
@ -783,14 +783,14 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
(ucontrol->value.iec958.status[1] << 8) |
(ucontrol->value.iec958.status[2] << 16) |
(ucontrol->value.iec958.status[3] << 24);
down(&chip->mixer_mutex);
mutex_lock(&chip->mixer_mutex);
if (chip->uer_bits != val) {
chip->uer_bits = val;
vx_set_iec958_status(chip, val);
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 1;
}
up(&chip->mixer_mutex);
mutex_unlock(&chip->mixer_mutex);
return 0;
}

View File

@ -98,10 +98,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
{
struct snd_pcm_runtime *runtime = subs->runtime;
if (runtime->dma_area) {
vfree(runtime->dma_area);
runtime->dma_area = NULL;
}
vfree(runtime->dma_area);
runtime->dma_area = NULL;
return 0;
}
@ -1254,9 +1253,13 @@ static int vx_init_audio_io(struct vx_core *chip)
/* allocate pipes */
chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL);
chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
if (! chip->playback_pipes || ! chip->capture_pipes)
if (!chip->playback_pipes)
return -ENOMEM;
chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
if (!chip->capture_pipes) {
kfree(chip->playback_pipes);
return -ENOMEM;
}
memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs);
memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins);

View File

@ -291,11 +291,13 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
{
struct cs8427 *chip;
unsigned long end_time;
int data;
int data, aes3input = 0;
snd_assert(cs8427, return);
chip = cs8427->private_data;
snd_i2c_lock(cs8427->bus);
if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == CS8427_RXDAES3INPUT) /* AES3 bit is set */
aes3input = 1;
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
chip->regmap[CS8427_REG_CLOCKSOURCE]);
@ -316,7 +318,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
}
snd_i2c_lock(cs8427->bus);
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
if (aes3input)
chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
chip->regmap[CS8427_REG_CLOCKSOURCE]);
snd_i2c_unlock(cs8427->bus);

View File

@ -88,7 +88,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (bus == NULL)
return -ENOMEM;
init_MUTEX(&bus->lock_mutex);
mutex_init(&bus->lock_mutex);
INIT_LIST_HEAD(&bus->devices);
INIT_LIST_HEAD(&bus->buses);
bus->card = card;

View File

@ -1,4 +1,3 @@
/*
ad1816a.c - lowlevel code for Analog Devices AD1816A chip.
Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
@ -175,7 +174,7 @@ static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
int channel, int cmd)
int channel, int cmd, int iscapture)
{
int error = 0;
@ -184,10 +183,14 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
case SNDRV_PCM_TRIGGER_STOP:
spin_lock(&chip->lock);
cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
if (what & AD1816A_PLAYBACK_ENABLE)
/* if (what & AD1816A_PLAYBACK_ENABLE) */
/* That is not valid, because playback and capture enable
* are the same bit pattern, just to different addresses
*/
if (! iscapture)
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
AD1816A_PLAYBACK_ENABLE, cmd);
if (what & AD1816A_CAPTURE_ENABLE)
else
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
AD1816A_CAPTURE_ENABLE, cmd);
spin_unlock(&chip->lock);
@ -204,14 +207,14 @@ static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
SNDRV_PCM_STREAM_PLAYBACK, cmd);
SNDRV_PCM_STREAM_PLAYBACK, cmd, 0);
}
static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
SNDRV_PCM_STREAM_CAPTURE, cmd);
SNDRV_PCM_STREAM_CAPTURE, cmd, 1);
}
static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream,

View File

@ -187,8 +187,10 @@ static int __init alsa_card_ad1848_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_AD1848_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -387,9 +387,9 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
{
unsigned long flags;
down(&chip->open_mutex);
mutex_lock(&chip->open_mutex);
if (chip->mode & AD1848_MODE_OPEN) {
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return -EAGAIN;
}
snd_ad1848_mce_down(chip);
@ -432,7 +432,7 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = mode;
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return 0;
}
@ -441,9 +441,9 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
{
unsigned long flags;
down(&chip->open_mutex);
mutex_lock(&chip->open_mutex);
if (!chip->mode) {
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return;
}
/* disable IRQ */
@ -471,7 +471,7 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = 0;
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
}
/*
@ -889,7 +889,7 @@ int snd_ad1848_create(struct snd_card *card,
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
init_MUTEX(&chip->open_mutex);
mutex_init(&chip->open_mutex);
chip->card = card;
chip->port = port;
chip->irq = -1;
@ -1202,10 +1202,8 @@ int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int
strlcpy(ctl->id.name, name, sizeof(ctl->id.name));
ctl->id.index = index;
ctl->private_value = value;
if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
snd_ctl_free_one(ctl);
if ((err = snd_ctl_add(chip->card, ctl)) < 0)
return err;
}
return 0;
}

View File

@ -203,8 +203,10 @@ static int __init alsa_card_cs4231_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(SND_CS4231_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -531,7 +531,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
unsigned long flags;
int full_calib = 1;
down(&chip->mce_mutex);
mutex_lock(&chip->mce_mutex);
snd_cs4231_calibrate_mute(chip, 1);
if (chip->hardware == CS4231_HW_CS4231A ||
(chip->hardware & CS4231_HW_CS4232_MASK)) {
@ -560,7 +560,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
snd_cs4231_mce_down(chip);
}
snd_cs4231_calibrate_mute(chip, 0);
up(&chip->mce_mutex);
mutex_unlock(&chip->mce_mutex);
}
static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
@ -570,7 +570,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
unsigned long flags;
int full_calib = 1;
down(&chip->mce_mutex);
mutex_lock(&chip->mce_mutex);
snd_cs4231_calibrate_mute(chip, 1);
if (chip->hardware == CS4231_HW_CS4231A ||
(chip->hardware & CS4231_HW_CS4232_MASK)) {
@ -603,7 +603,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
snd_cs4231_mce_down(chip);
}
snd_cs4231_calibrate_mute(chip, 0);
up(&chip->mce_mutex);
mutex_unlock(&chip->mce_mutex);
}
/*
@ -709,15 +709,15 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
{
unsigned long flags;
down(&chip->open_mutex);
mutex_lock(&chip->open_mutex);
if ((chip->mode & mode) ||
((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) {
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return -EAGAIN;
}
if (chip->mode & CS4231_MODE_OPEN) {
chip->mode |= mode;
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return 0;
}
/* ok. now enable and ack CODEC IRQ */
@ -737,7 +737,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = mode;
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return 0;
}
@ -745,10 +745,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
{
unsigned long flags;
down(&chip->open_mutex);
mutex_lock(&chip->open_mutex);
chip->mode &= ~mode;
if (chip->mode & CS4231_MODE_OPEN) {
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
return;
}
snd_cs4231_calibrate_mute(chip, 1);
@ -785,7 +785,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
snd_cs4231_calibrate_mute(chip, 0);
chip->mode = 0;
up(&chip->open_mutex);
mutex_unlock(&chip->open_mutex);
}
/*
@ -1408,8 +1408,8 @@ static int snd_cs4231_new(struct snd_card *card,
chip->hwshare = hwshare;
spin_lock_init(&chip->reg_lock);
init_MUTEX(&chip->mce_mutex);
init_MUTEX(&chip->open_mutex);
mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex);
chip->card = card;
chip->rate_constraint = snd_cs4231_xrate;
chip->set_playback_format = snd_cs4231_playback_format;
@ -1538,8 +1538,8 @@ int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
return err;
spin_lock_init(&chip->reg_lock);
init_MUTEX(&chip->mce_mutex);
init_MUTEX(&chip->open_mutex);
mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops);

View File

@ -771,9 +771,9 @@ static int __init alsa_card_cs423x_init(void)
if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
return err;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (is_isapnp_selected(i))
if (! enable[i] || is_isapnp_selected(i))
continue;
device = platform_device_register_simple(CS423X_DRIVER,
i, NULL, 0);

View File

@ -644,7 +644,7 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2;
change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)];
snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1);
snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val1);
snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return change;
}
@ -841,7 +841,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
enable = ucontrol->value.integer.value[0] & 1;
down(&chip->mce_mutex);
mutex_lock(&chip->mce_mutex);
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->reg_lock, flags);
val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
@ -854,7 +854,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
snd_cs4236_ctrl_out(chip, 4, val);
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_cs4231_mce_down(chip);
up(&chip->mce_mutex);
mutex_unlock(&chip->mce_mutex);
#if 0
printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",

View File

@ -207,8 +207,10 @@ static int __init alsa_card_es1688_init(void)
return err;
cards = 0;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (! enable[i])
continue;
device = platform_device_register_simple(ES1688_DRIVER,
i, NULL, 0);
if (IS_ERR(device)) {

View File

@ -49,6 +49,10 @@
* - contrarily to some pages in DS_1869.PDF the rates can be set
* independently.
*
* - Zoom Video is implemented by sharing the FM DAC, thus the user can
* have either FM playback or Video playback but not both simultaneously.
* The Video Playback Switch mixer control toggles this choice.
*
* BUGS:
*
* - There is a major trouble I noted:
@ -63,7 +67,16 @@
*
*/
/*
* ES1879 NOTES:
* - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
* seems to be effected (speaker_test plays a lower frequency). Can't find
* anything in the datasheet to account for this, so a Video Playback Switch
* control has been included to allow ZV to be enabled only when necessary.
* Then again on at least one test system the 0x71 bit 6 enable bit is not
* needed for ZV, so maybe the datasheet is entirely wrong here.
*/
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
@ -148,7 +161,7 @@ struct snd_audiodrive {
#define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */
#define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */
#define ES18XX_AUXB 0x0040 /* AuxB mixer control */
#define ES18XX_HWV 0x0080 /* Has hardware volume */
#define ES18XX_HWV 0x0080 /* Has seperate hardware volume mixer controls*/
#define ES18XX_MONO 0x0100 /* Mono_in mixer control */
#define ES18XX_I2S 0x0200 /* I2S mixer control */
#define ES18XX_MUTEREC 0x0400 /* Record source can be muted */
@ -788,9 +801,12 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *r
/* Hardware volume */
if (status & HWV_IRQ) {
int split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
int split = 0;
if (chip->caps & ES18XX_HWV) {
split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
}
if (!split) {
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
@ -939,37 +955,118 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
* MIXER part
*/
/* Record source mux routines:
* Depending on the chipset this mux switches between 4, 5, or 8 possible inputs.
* bit table for the 4/5 source mux:
* reg 1C:
* b2 b1 b0 muxSource
* x 0 x microphone
* 0 1 x CD
* 1 1 0 line
* 1 1 1 mixer
* if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines
* either the play mixer or the capture mixer.
*
* "map4Source" translates from source number to reg bit pattern
* "invMap4Source" translates from reg bit pattern to source number
*/
static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
static char *texts[8] = {
static char *texts4Source[4] = {
"Mic", "CD", "Line", "Master"
};
static char *texts5Source[5] = {
"Mic", "CD", "Line", "Master", "Mix"
};
static char *texts8Source[8] = {
"Mic", "Mic Master", "CD", "AOUT",
"Mic1", "Mix", "Line", "Master"
};
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 8;
if (uinfo->value.enumerated.item > 7)
uinfo->value.enumerated.item = 7;
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
switch (chip->version) {
case 0x1868:
case 0x1878:
uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item > 3)
uinfo->value.enumerated.item = 3;
strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]);
break;
case 0x1887:
case 0x1888:
uinfo->value.enumerated.items = 5;
if (uinfo->value.enumerated.item > 4)
uinfo->value.enumerated.item = 4;
strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]);
break;
case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */
case 0x1879:
uinfo->value.enumerated.items = 8;
if (uinfo->value.enumerated.item > 7)
uinfo->value.enumerated.item = 7;
strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]);
break;
default:
return -EINVAL;
}
return 0;
}
static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3};
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
if (!(chip->version == 0x1869 || chip->version == 0x1879)) {
muxSource = invMap4Source[muxSource];
if (muxSource==3 &&
(chip->version == 0x1887 || chip->version == 0x1888) &&
(snd_es18xx_mixer_read(chip, 0x7a) & 0x08)
)
muxSource = 4;
}
ucontrol->value.enumerated.item[0] = muxSource;
return 0;
}
static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
static unsigned char map4Source[4] = {0, 2, 6, 7};
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
unsigned char val = ucontrol->value.enumerated.item[0];
if (val > 7)
unsigned char retVal = 0;
switch (chip->version) {
/* 5 source chips */
case 0x1887:
case 0x1888:
if (val > 4)
return -EINVAL;
if (val == 4) {
retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08;
val = 3;
} else
retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
/* 4 source chips */
case 0x1868:
case 0x1878:
if (val > 3)
return -EINVAL;
val = map4Source[val];
break;
/* 8 source chips */
case 0x1869:
case 0x1879:
if (val > 7)
return -EINVAL;
break;
default:
return -EINVAL;
return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val;
}
return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
}
static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
@ -1191,19 +1288,22 @@ static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return change;
}
/* Mixer controls
* These arrays contain setup data for mixer controls.
*
* The controls that are universal to all chipsets are fully initialized
* here.
*/
static struct snd_kcontrol_new snd_es18xx_base_controls[] = {
ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0),
ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Source",
@ -1213,19 +1313,37 @@ ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
}
};
static struct snd_kcontrol_new snd_es18xx_mono_in_control =
ES18XX_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0);
static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = {
ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0),
ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
};
/*
* The chipset specific mixer controls
*/
static struct snd_kcontrol_new snd_es18xx_opt_speaker =
ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0);
static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0),
ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
};
static struct snd_kcontrol_new snd_es18xx_opt_1878 =
ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0);
static struct snd_kcontrol_new snd_es18xx_opt_1879[] = {
ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0),
ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
};
static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
};
@ -1270,7 +1388,6 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
};
#if 0
static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
{
int data;
@ -1281,7 +1398,6 @@ static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned ch
spin_unlock_irqrestore(&chip->ctrl_lock, flags);
return data;
}
#endif
static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
unsigned char reg, unsigned char data)
@ -1427,6 +1543,17 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
snd_es18xx_mixer_write(chip, 0x58, 0x94);
snd_es18xx_mixer_write(chip, 0x5a, 0x80);
}
/* Flip the "enable I2S" bits for those chipsets that need it */
switch (chip->version) {
case 0x1879:
//Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow)
//so a Switch control has been added to toggle this 0x71 bit on/off:
//snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40);
/* Note: we fall through on purpose here. */
case 0x1878:
snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40);
break;
}
/* Mute input source */
if (chip->caps & ES18XX_MUTEREC)
mask = 0x10;
@ -1476,11 +1603,14 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
}
outb(0x40, chip->port + 0x04);
udelay(10);
hi = inb(chip->port + 0x05);
udelay(10);
lo = inb(chip->port + 0x05);
if (hi != lo) {
chip->version = hi << 8 | lo;
chip->ctrl_port = inb(chip->port + 0x05) << 8;
udelay(10);
chip->ctrl_port += inb(chip->port + 0x05);
if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) {
@ -1519,22 +1649,22 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
switch (chip->version) {
case 0x1868:
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_HWV;
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL;
break;
case 0x1869:
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV;
break;
case 0x1878:
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL;
break;
case 0x1879:
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
break;
case 0x1887:
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
break;
case 0x1888:
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
break;
default:
snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
@ -1778,10 +1908,6 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
}
}
if (chip->caps & ES18XX_MONO) {
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_mono_in_control, chip))) < 0)
return err;
}
if (chip->caps & ES18XX_RECMIX) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
@ -1819,6 +1945,36 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
}
}
/* finish initializing other chipset specific controls
*/
if (chip->version != 0x1868) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker,
chip));
if (err < 0)
return err;
}
if (chip->version == 0x1869) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_es18xx_opt_1869[idx],
chip));
if (err < 0)
return err;
}
} else if (chip->version == 0x1878) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878,
chip));
if (err < 0)
return err;
} else if (chip->version == 0x1879) {
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_es18xx_opt_1879[idx],
chip));
if (err < 0)
return err;
}
}
return 0;
}
@ -1927,6 +2083,7 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
err = pnp_activate_dev(acard->devc);
if (err < 0) {
snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
kfree(cfg);
return -EAGAIN;
}
snd_printdd("pnp: port=0x%lx\n", pnp_port_start(acard->devc, 0));
@ -2225,9 +2382,9 @@ static int __init alsa_card_es18xx_init(void)
if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
return err;
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
for (i = 0; i < SNDRV_CARDS; i++) {
struct platform_device *device;
if (is_isapnp_selected(i))
if (! enable[i] || is_isapnp_selected(i))
continue;
device = platform_device_register_simple(ES18XX_DRIVER,
i, NULL, 0);

View File

@ -149,10 +149,10 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
int snd_gf1_dma_init(struct snd_gus_card * gus)
{
down(&gus->dma_mutex);
mutex_lock(&gus->dma_mutex);
gus->gf1.dma_shared++;
if (gus->gf1.dma_shared > 1) {
up(&gus->dma_mutex);
mutex_unlock(&gus->dma_mutex);
return 0;
}
gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt;
@ -160,7 +160,7 @@ int snd_gf1_dma_init(struct snd_gus_card * gus)
gus->gf1.dma_data_pcm_last =
gus->gf1.dma_data_synth =
gus->gf1.dma_data_synth_last = NULL;
up(&gus->dma_mutex);
mutex_unlock(&gus->dma_mutex);
return 0;
}
@ -168,7 +168,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
{
struct snd_gf1_dma_block *block;
down(&gus->dma_mutex);
mutex_lock(&gus->dma_mutex);
gus->gf1.dma_shared--;
if (!gus->gf1.dma_shared) {
snd_dma_disable(gus->gf1.dma1);
@ -185,7 +185,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
gus->gf1.dma_data_pcm_last =
gus->gf1.dma_data_synth_last = NULL;
}
up(&gus->dma_mutex);
mutex_unlock(&gus->dma_mutex);
return 0;
}

View File

@ -225,7 +225,7 @@ int snd_gus_create(struct snd_card *card,
spin_lock_init(&gus->dma_lock);
spin_lock_init(&gus->pcm_volume_level_lock);
spin_lock_init(&gus->uart_cmd_lock);
init_MUTEX(&gus->dma_mutex);
mutex_init(&gus->dma_mutex);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
snd_gus_free(gus);
return err;

View File

@ -34,9 +34,9 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
{
if (!xup) {
down(&alloc->memory_mutex);
mutex_lock(&alloc->memory_mutex);
} else {
up(&alloc->memory_mutex);
mutex_unlock(&alloc->memory_mutex);
}
}
@ -59,7 +59,7 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
alloc->first = nblock;
else
nblock->prev->next = nblock;
up(&alloc->memory_mutex);
mutex_unlock(&alloc->memory_mutex);
return NULL;
}
pblock = pblock->next;
@ -80,7 +80,7 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo
{
if (block->share) { /* ok.. shared block */
block->share--;
up(&alloc->memory_mutex);
mutex_unlock(&alloc->memory_mutex);
return 0;
}
if (alloc->first == block) {
@ -244,7 +244,7 @@ int snd_gf1_mem_init(struct snd_gus_card * gus)
#endif
alloc = &gus->gf1.mem_alloc;
init_MUTEX(&alloc->memory_mutex);
mutex_init(&alloc->memory_mutex);
alloc->first = alloc->last = NULL;
if (!gus->gf1.memory)
return 0;
@ -299,7 +299,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
gus = entry->private_data;
alloc = &gus->gf1.mem_alloc;
down(&alloc->memory_mutex);
mutex_lock(&alloc->memory_mutex);
snd_iprintf(buffer, "8-bit banks : \n ");
for (i = 0; i < 4; i++)
snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : "");
@ -343,7 +343,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
}
snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n",
total, used, total - used);
up(&alloc->memory_mutex);
mutex_unlock(&alloc->memory_mutex);
#if 0
ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n",
ultra_memory_free_size(card, &card->gf1.mem_alloc),

Some files were not shown because too many files have changed in this diff Show More