Răsfoiți Sursa

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
  ...
Linus Torvalds 19 ani în urmă
părinte
comite
1c2e02750b
100 a modificat fișierele cu 1489 adăugiri și 1546 ștergeri
  1. 68 3
      Documentation/sound/alsa/ALSA-Configuration.txt
  2. 333 0
      Documentation/sound/alsa/Audiophile-Usb.txt
  3. 3 3
      Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
  4. 2 2
      arch/arm/mach-pxa/mainstone.c
  5. 29 25
      drivers/media/video/cx88/cx88-alsa.c
  6. 36 29
      drivers/media/video/saa7134/saa7134-alsa.c
  7. 1 1
      drivers/media/video/saa7134/saa7134.h
  8. 2 2
      include/asm-arm/arch-pxa/audio.h
  9. 1 0
      include/linux/dma-mapping.h
  10. 10 5
      include/sound/ac97_codec.h
  11. 1 1
      include/sound/ad1848.h
  12. 1 1
      include/sound/ak4531_codec.h
  13. 4 4
      include/sound/core.h
  14. 2 2
      include/sound/cs4231.h
  15. 1 1
      include/sound/cs46xx.h
  16. 2 2
      include/sound/emu10k1.h
  17. 1 1
      include/sound/emux_synth.h
  18. 3 3
      include/sound/gus.h
  19. 1 1
      include/sound/hwdep.h
  20. 5 5
      include/sound/i2c.h
  21. 1 1
      include/sound/info.h
  22. 1 1
      include/sound/mixer_oss.h
  23. 2 1
      include/sound/opl3.h
  24. 1 1
      include/sound/pcm.h
  25. 3 1
      include/sound/pcm_oss.h
  26. 2 2
      include/sound/rawmidi.h
  27. 1 1
      include/sound/sb16_csp.h
  28. 1 1
      include/sound/seq_instr.h
  29. 1 1
      include/sound/soundfont.h
  30. 3 1
      include/sound/util_mem.h
  31. 2 2
      include/sound/version.h
  32. 1 1
      include/sound/vx_core.h
  33. 6 4
      include/sound/ymfpci.h
  34. 5 5
      sound/arm/aaci.c
  35. 1 1
      sound/arm/aaci.h
  36. 6 6
      sound/arm/pxa2xx-ac97.c
  37. 18 0
      sound/core/Kconfig
  38. 29 10
      sound/core/control.c
  39. 25 8
      sound/core/control_compat.c
  40. 22 21
      sound/core/hwdep.c
  41. 14 13
      sound/core/info.c
  42. 7 6
      sound/core/info_oss.c
  43. 43 1
      sound/core/init.c
  44. 14 42
      sound/core/memalloc.c
  45. 5 0
      sound/core/oss/copy.c
  46. 5 0
      sound/core/oss/io.c
  47. 6 1
      sound/core/oss/linear.c
  48. 7 7
      sound/core/oss/mixer_oss.c
  49. 24 0
      sound/core/oss/mulaw.c
  50. 33 17
      sound/core/oss/pcm_oss.c
  51. 49 223
      sound/core/oss/pcm_plugin.c
  52. 6 22
      sound/core/oss/pcm_plugin.h
  53. 0 166
      sound/core/oss/plugin_ops.h
  54. 25 60
      sound/core/oss/rate.c
  55. 40 449
      sound/core/oss/route.c
  56. 24 21
      sound/core/pcm.c
  57. 14 14
      sound/core/pcm_native.c
  58. 29 28
      sound/core/rawmidi.c
  59. 14 13
      sound/core/seq/oss/seq_oss.c
  60. 21 22
      sound/core/seq/seq_clientmgr.c
  61. 1 1
      sound/core/seq/seq_clientmgr.h
  62. 27 26
      sound/core/seq/seq_device.c
  63. 3 3
      sound/core/seq/seq_instr.c
  64. 10 10
      sound/core/seq/seq_midi.c
  65. 6 6
      sound/core/seq/seq_ports.c
  66. 3 3
      sound/core/seq/seq_queue.c
  67. 1 1
      sound/core/seq/seq_queue.h
  68. 2 2
      sound/core/seq/seq_virmidi.c
  69. 14 13
      sound/core/sound.c
  70. 13 12
      sound/core/sound_oss.c
  71. 39 38
      sound/core/timer.c
  72. 3 1
      sound/drivers/dummy.c
  73. 3 1
      sound/drivers/mpu401/mpu401.c
  74. 1 1
      sound/drivers/opl3/opl3_lib.c
  75. 7 5
      sound/drivers/opl3/opl3_oss.c
  76. 14 8
      sound/drivers/opl3/opl3_seq.c
  77. 5 5
      sound/drivers/opl3/opl3_synth.c
  78. 1 1
      sound/drivers/opl4/opl4_lib.c
  79. 1 1
      sound/drivers/opl4/opl4_local.h
  80. 5 5
      sound/drivers/opl4/opl4_proc.c
  81. 6 6
      sound/drivers/opl4/opl4_seq.c
  82. 4 1
      sound/drivers/serial-u16550.c
  83. 3 1
      sound/drivers/virmidi.c
  84. 1 1
      sound/drivers/vx/vx_core.c
  85. 36 36
      sound/drivers/vx/vx_mixer.c
  86. 8 5
      sound/drivers/vx/vx_pcm.c
  87. 5 2
      sound/i2c/cs8427.c
  88. 1 1
      sound/i2c/i2c.c
  89. 9 6
      sound/isa/ad1816a/ad1816a_lib.c
  90. 3 1
      sound/isa/ad1848/ad1848.c
  91. 8 10
      sound/isa/ad1848/ad1848_lib.c
  92. 3 1
      sound/isa/cs423x/cs4231.c
  93. 15 15
      sound/isa/cs423x/cs4231_lib.c
  94. 2 2
      sound/isa/cs423x/cs4236.c
  95. 3 3
      sound/isa/cs423x/cs4236_lib.c
  96. 3 1
      sound/isa/es1688/es1688.c
  97. 190 33
      sound/isa/es18xx.c
  98. 5 5
      sound/isa/gus/gus_dma.c
  99. 1 1
      sound/isa/gus/gus_main.c
  100. 7 7
      sound/isa/gus/gus_mem.c

+ 68 - 3
Documentation/sound/alsa/ALSA-Configuration.txt

@@ -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.
 

+ 333 - 0
Documentation/sound/alsa/Audiophile-Usb.txt

@@ -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
+

+ 3 - 3
Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl

@@ -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

+ 2 - 2
arch/arm/mach-pxa/mainstone.c

@@ -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;

+ 29 - 25
drivers/media/video/cx88/cx88-alsa.c

@@ -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 @@ _error:
 /*
  * 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;
 

+ 36 - 29
drivers/media/video/saa7134/saa7134-alsa.c

@@ -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 @@ out:
  *
  */
 
-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;
 

+ 1 - 1
drivers/media/video/saa7134/saa7134.h

@@ -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 */

+ 2 - 2
include/asm-arm/arch-pxa/audio.h

@@ -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;

+ 1 - 0
include/linux/dma-mapping.h

@@ -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>
 

+ 10 - 5
include/sound/ac97_codec.h

@@ -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 {

+ 1 - 1
include/sound/ad1848.h

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

+ 1 - 1
include/sound/ak4531_codec.h

@@ -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,

+ 4 - 4
include/sound/core.h

@@ -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)

+ 2 - 2
include/sound/cs4231.h

@@ -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);

+ 1 - 1
include/sound/cs46xx.h

@@ -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;
 

+ 2 - 2
include/sound/emu10k1.h

@@ -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];

+ 1 - 1
include/sound/emux_synth.h

@@ -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];

+ 3 - 3
include/sound/gus.h

@@ -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 */

+ 1 - 1
include/sound/hwdep.h

@@ -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;

+ 5 - 5
include/sound/i2c.h

@@ -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);

+ 1 - 1
include/sound/info.h

@@ -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)

+ 1 - 1
include/sound/mixer_oss.h

@@ -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;
 	/* --- */

+ 2 - 1
include/sound/opl3.h

@@ -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 */

+ 1 - 1
include/sound/pcm.h

@@ -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);

+ 3 - 1
include/sound/pcm_oss.h

@@ -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;
 };
 

+ 2 - 2
include/sound/rawmidi.h

@@ -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;

+ 1 - 1
include/sound/sb16_csp.h

@@ -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);

+ 1 - 1
include/sound/seq_instr.h

@@ -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;
 };
 

+ 1 - 1
include/sound/soundfont.h

@@ -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;
 };

+ 3 - 1
include/sound/util_mem.h

@@ -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 */
 };
 
 /*

+ 2 - 2
include/sound/version.h

@@ -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)"

+ 1 - 1
include/sound/vx_core.h

@@ -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 */
 };

+ 6 - 4
include/sound/ymfpci.h

@@ -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 */

+ 5 - 5
sound/arm/aaci.c

@@ -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;

+ 1 - 1
sound/arm/aaci.h

@@ -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;

+ 6 - 6
sound/arm/pxa2xx-ac97.c

@@ -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)

+ 18 - 0
sound/core/Kconfig

@@ -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

+ 29 - 10
sound/core/control.c

@@ -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;

+ 25 - 8
sound/core/control_compat.c

@@ -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)
-		goto error;
-	if ((err = snd_ctl_elem_write(file->card, file, data)) < 0)
+	if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 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;

+ 22 - 21
sound/core/hwdep.c

@@ -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;

+ 14 - 13
sound/core/info.c

@@ -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;
 }

+ 7 - 6
sound/core/info_oss.c

@@ -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;

+ 43 - 1
sound/core/init.c

@@ -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;

+ 14 - 42
sound/core/memalloc.c

@@ -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;
 }
 

+ 5 - 0
sound/core/oss/copy.c

@@ -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

+ 5 - 0
sound/core/oss/io.c

@@ -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

+ 6 - 1
sound/core/oss/linear.c

@@ -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

+ 7 - 7
sound/core/oss/mixer_oss.c

@@ -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,

+ 24 - 0
sound/core/oss/mulaw.c

@@ -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

+ 33 - 17
sound/core/oss/pcm_oss.c

@@ -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);
 	}
 }
 

+ 49 - 223
sound/core/oss/pcm_plugin.c

@@ -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

+ 6 - 22
sound/core/oss/pcm_plugin.h

@@ -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)

+ 0 - 166
sound/core/oss/plugin_ops.h

@@ -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

+ 25 - 60
sound/core/oss/rate.c

@@ -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

+ 40 - 449
sound/core/oss/route.c

@@ -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)
-{
-	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)
+static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
+		       snd_pcm_uframes_t frames, int format)
 {
-#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);
+	format = plugin->dst_format.format;
+	dvp = dst_channels;
+	if (nsrcs <= 1) {
+		/* expand to all channels */
+		for (dst = 0; dst < ndsts; ++dst) {
+			copy_area(src_channels, dvp, frames, format);
+			dvp++;
 		}
+		return frames;
 	}
-#endif
 
-	ttp = data->ttable;
-	dvp = dst_channels;
-	for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
-		ttp->func(plugin, src_channels, dvp, ttp, frames);
+	for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {
+		copy_area(src_channels, dvp, frames, format);
 		dvp++;
-		ttp++;
+		src_channels++;
 	}
+	if (dst < ndsts)
+		zero_areas(dvp, ndsts - dst, frames, format);
 	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;
-	}
-#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_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

+ 24 - 21
sound/core/pcm.c

@@ -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

+ 14 - 14
sound/core/pcm_native.c

@@ -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);
 }

+ 29 - 28
sound/core/rawmidi.c

@@ -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);

+ 14 - 13
sound/core/seq/oss/seq_oss.c

@@ -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);
 }
 
 

+ 21 - 22
sound/core/seq/seq_clientmgr.c

@@ -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;
 }

+ 1 - 1
sound/core/seq/seq_clientmgr.h

@@ -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 */

+ 27 - 26
sound/core/seq/seq_device.c

@@ -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);
 }
 
 

+ 3 - 3
sound/core/seq/seq_instr.c

@@ -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;
 }

+ 10 - 10
sound/core/seq/seq_midi.c

@@ -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;
 }
 

+ 6 - 6
sound/core/seq/seq_ports.c

@@ -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;
 }
 

+ 3 - 3
sound/core/seq/seq_queue.c

@@ -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;
 }

+ 1 - 1
sound/core/seq/seq_queue.h

@@ -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;
 };

+ 2 - 2
sound/core/seq/seq_virmidi.c

@@ -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;
 				}

+ 14 - 13
sound/core/sound.c

@@ -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)

+ 13 - 12
sound/core/sound_oss.c

@@ -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);
 }
 
 

+ 39 - 38
sound/core/timer.c

@@ -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:

+ 3 - 1
sound/drivers/dummy.c

@@ -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)) {

+ 3 - 1
sound/drivers/mpu401/mpu401.c

@@ -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;

+ 1 - 1
sound/drivers/opl3/opl3_lib.c

@@ -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);

+ 7 - 5
sound/drivers/opl3/opl3_oss.c

@@ -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 */

+ 14 - 8
sound/drivers/opl3/opl3_seq.c

@@ -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();

+ 5 - 5
sound/drivers/opl3/opl3_synth.c

@@ -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;
 }

+ 1 - 1
sound/drivers/opl4/opl4_lib.c

@@ -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) {

+ 1 - 1
sound/drivers/opl4/opl4_local.h

@@ -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;

+ 5 - 5
sound/drivers/opl4/opl4_proc.c

@@ -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;
 }
 

+ 6 - 6
sound/drivers/opl4/opl4_seq.c

@@ -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);

+ 4 - 1
sound/drivers/serial-u16550.c

@@ -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)) {

+ 3 - 1
sound/drivers/virmidi.c

@@ -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)) {

+ 1 - 1
sound/drivers/vx/vx_core.c

@@ -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;

+ 36 - 36
sound/drivers/vx/vx_mixer.c

@@ -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;
 }
 

+ 8 - 5
sound/drivers/vx/vx_pcm.c

@@ -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);
+	if (!chip->playback_pipes)
+		return -ENOMEM;
 	chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
-	if (! chip->playback_pipes || ! chip->capture_pipes)
+	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);

+ 5 - 2
sound/i2c/cs8427.c

@@ -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);

+ 1 - 1
sound/i2c/i2c.c

@@ -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;

+ 9 - 6
sound/isa/ad1816a/ad1816a_lib.c

@@ -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,

+ 3 - 1
sound/isa/ad1848/ad1848.c

@@ -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)) {

+ 8 - 10
sound/isa/ad1848/ad1848_lib.c

@@ -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;
 }
 

+ 3 - 1
sound/isa/cs423x/cs4231.c

@@ -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)) {

+ 15 - 15
sound/isa/cs423x/cs4231_lib.c

@@ -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);

+ 2 - 2
sound/isa/cs423x/cs4236.c

@@ -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);

+ 3 - 3
sound/isa/cs423x/cs4236_lib.c

@@ -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",

+ 3 - 1
sound/isa/es1688/es1688.c

@@ -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)) {

+ 190 - 33
sound/isa/es18xx.c

@@ -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);

+ 5 - 5
sound/isa/gus/gus_dma.c

@@ -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;
 }
 

+ 1 - 1
sound/isa/gus/gus_main.c

@@ -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;

+ 7 - 7
sound/isa/gus/gus_mem.c

@@ -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),

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff